Create a Custom Unsubscribe or Manage Preferences Page

read

Overview

Klaviyo's hosted pages can be used to design a custom unsubscribe page and/or manage preferences center. With this feature, you can build more sophisticated forms to collect extensive information about your subscribers for segmenting and targeting purposes. 

Note

To build a custom unsubscribe or manage preferences page, you'll need to use our Hosted Pages feature. To request access to this feature, please email success@klaviyo.com.

Hosted pages give you a blank slate and allow you to custom code your own forms. We then make it easy to use these custom pages in Klaviyo by hosting them for you and providing ways to swap out our default pages for your customized ones.

 

Create a Custom Unsubscribe or Manage Preferences Page

To create a custom unsubscribe or manage preferences page, navigate to the Hosted Pages tab in your account. If you don't see this tab, email success@klaviyo.com to have this enabled. Once inside the Hosted Pages tab, go to Pages and click Add a New Page. Name this unsubscribe.tmpl. You will be able to use this for both your unsubscribe page and manage preferences page, but you can create more than one page if you'd like.

You can then design an HTML page that includes the fields and features of your choice. Example fields that can be inserted for a custom unsubscribe page:

Choices for email frequency:

  • An option to unsubscribe
  • An option to receive all email
  • Frequency options for daily, weekly, monthly, etc. newsletters

Information that could be used to target and segment, e.g.:

  • A checkbox for whether or not the user wants sale announcements
  • A checkbox for whether or not the user wants product announcements
  • A checkbox for whether or not the user wants blog updates
  • Other lists the user may want to join

To get started, here is a basic HTML template that includes:

  • The email frequency hidden field
  • Radio buttons with values for daily, weekly, and monthly frequencies
  • Radio button with the value of "$unsubscribe" which, when the form is submitted, will unsubscribe that user
  • Submit button to submit the form to Klaviyo

You can use this code in your unsubscribe.tmpl to get a fully functional unsubscribe or manage preferences page with email type and frequency preferences:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 
 <!-- Latest compiled and minified CSS -->
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
 
 <style type="text/css">
 /* Space out content a bit */
 body {
 padding-top: 20px;
 padding-bottom: 20px;
 }
 form {
 margin-bottom: 18px;
 }
 /* Custom page header */
 .header {
 border-bottom: 1px solid #e5e5e5;
 margin-bottom: 10px;
 }
 .header h1 {
 margin: 10px 0;
 }
 .required-fields {
 text-align: right;
 }
 .required-fields span {
 color: #a94442;
 font-weight: bold;
 }
 .list-group-item label {
 font-weight: normal;
 margin-top: 17px;
 }
 .list-group-item label input[type="checkbox"] {
 margin-right: 4px;
 }
 .form-group span.required {
 position: absolute;
 top: 0;
 right: 0;
 font-size: 20px;
 color: #a94442;
 font-weight: bold;
 user-select: none;
 }
 label.error {
 color: #a94442;
 font-weight: bold;
 margin-top: 4px;
 }
 .form-actions {
 margin: 25px 0;
 }
 .form-control + .form-control {
 margin-top: 6px;
 }
 .panel-group .panel-title .closed-icon,
 .panel-group .panel-title .open-icon {
 margin-right: 0.5em;
 top: 2px;
 }
 .panel-group .panel-title a:hover,
 .panel-group .panel-title a:active {
 text-decoration: none;
 }
 .panel-group .panel-title a:hover .text,
 .panel-group .panel-title a:active .text {
 text-decoration: underline;
 }
 .panel-group .panel-title .closed-icon { display: none; }
 .panel-group.closed .panel-title .open-icon { display: none; }
 .panel-group.closed .panel-title .closed-icon { display: inline; }
 /* Custom page footer */
 .footer {
 padding-top: 18px;
 border-top: 1px solid #e5e5e5;
 }
 /* Customize container */
 @media (min-width: 768px) {
 .container {
 max-width: 730px;
 }
 }
 </style>
 
 <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
 <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
 <!--[if lt IE 9]>
 <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
 <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
 <![endif]-->
 </head>
<body>

 <div class="container">
 <div class="header">
 <img src="http://via.placeholder.com/300x75" />
 <h1>Email Preferences</h1>
 </div>
 
 <form action="" id="preferences_form" method="POST" role="form" class="form-horizontal">
 
 {% if form.non_field_errors %}
 <div class="alert alert-danger">
 {% for error in form.non_field_errors %}
 {{ error }}{% if not forloop.last %}<br />{% endif %}
 {% endfor %}
 </div>
 {% endif %}
 
 <input type="hidden" name="$fields" value="EmailInterests,EmailFrequency" />
 <input type="hidden" name="$list_fields" value="EmailInterests" />
 <!-- <input type="hidden" name="$unsubscribed_url" value="/p/preferences_updated" /> -->
 <!-- <input type="hidden" name="$updated_profile_url" value="/p/preferences_updated" /> -->
 
 <!--<p class="required-fields">
 <span>*</span> Required Information
 </p>-->
 
 <div class="form-group{% if form.errors|lookup:'$email' %} has-error{% endif %}">
 <label for="email" class="col-sm-3 control-label">Email Address<span class="required">*</span></label>
 <div class="col-sm-9">
 <input type="email" class="form-control" id="email" name="$email" value="{% if request.POST|lookup:'$email' %}{{ request.POST|lookup:'$email' }}{% else %}{{ person.email|default:'' }}{% endif %}" />
 {% if form.errors|lookup:'$email' %}
 <p class="help-block">{% for error in form.errors|lookup:'$email' %}{{ error }}{% endfor %}</p>
 {% endif %}
 </div>
 </div>
 
 <div class="form-group">
 <label for="first_name" class="col-sm-3 control-label">First Name</label>
 <div class="col-sm-9">
 <input type="text" class="form-control" id="first_name" name="$first_name" value="{% if request.POST|lookup:'$email' %}{{ request.POST|lookup:'$first_name' }}{% else %}{{ person.first_name|default:'' }}{% endif %}" />
 </div>
 </div>
 
 <div class="form-group">
 <label for="last_name" class="col-sm-3 control-label">Last Name</label>
 <div class="col-sm-9">
 <input type="text" class="form-control" id="last_name" name="$last_name" value="{% if request.POST|lookup:'$email' %}{{ request.POST|lookup:'$last_name' }}{% else %}{{ person.last_name|default:'' }}{% endif %}" />
 </div>
 </div>
 
 <div class="form-group">
 <label for="interests" class="col-sm-3 control-label">Interests</label>
 <div class="col-sm-9">
 <div class="checkbox">
 <label>
 <input type="checkbox" name="EmailInterests" value="New Releases" {% if 'New Releases' in person.EmailInterests or 'New Releases' in request.POST.EmailInterests %}checked="checked"{% elif not person.EmailInterests and not request.POST.EmailInterests %}checked="checked"{% endif %} />
 New Product Releases
 </label>
 </div>
 <div class="checkbox">
 <label>
 <input type="checkbox" name="EmailInterests" value="Promotions" {% if 'Promotions' in person.EmailInterests or 'Promotions' in request.POST.EmailInterests %}checked="checked"{% elif not person.EmailInterests and not request.POST.EmailInterests %}checked="checked"{% endif %} />
 Promotions &amp; Sales
 </label>
 </div>
 <div class="checkbox">
 <label>
 <input type="checkbox" name="EmailInterests" value="Blog" {% if 'Blog' in person.EmailInterests or 'Blog' in request.POST.EmailInterests %}checked="checked"{% elif not person.EmailInterests and not request.POST.EmailInterests %}checked="checked"{% endif %} />
 Latest from the Blog
 </label>
 </div>
 <div class="checkbox">
 <label>
 <input type="checkbox" name="EmailInterests" value="Events" {% if 'Events' in person.EmailInterests or 'Events' in request.POST.EmailInterests %}checked="checked"{% elif not person.EmailInterests and not request.POST.EmailInterests %}checked="checked"{% endif %} />
 Events
 </label>
 </div>
 </div>
 </div>
 
 <div class="form-group">
 <label for="interests" class="col-sm-3 control-label">How often would you like to hear from us?</label>
 <div class="col-sm-9">
 <div class="radio">
 <label>
 <!-- Default value. -->
 <input type="radio" name="EmailFrequency" id="email_frequency_0" value="All" {% if person.EmailFrequency == 'All' or request.POST.EmailFrequency == 'All' %}checked="checked"{% elif not person.EmailFrequency and not request.POST.EmailFrequency %}checked="checked"{% endif %} />
 Twice per Week
 </label>
 </div>
 <div class="radio">
 <label>
 <input type="radio" name="EmailFrequency" id="email_frequency_1" value="Weekly" {% if person.EmailFrequency == 'Weekly' or request.POST.EmailFrequency == 'Weekly' %}checked="checked"{% endif %} />
 Once per Week
 </label>
 </div>
 <div class="radio">
 <label>
 <input type="radio" name="EmailFrequency" id="email_frequency_2" value="Monthly" {% if person.EmailFrequency == 'Monthly' or request.POST.EmailFrequency == 'Monthly' %}checked="checked"{% endif %} />
 Once per Month
 </label>
 </div>
 </div>
 </div>
 
 <div class="checkbox">
 <label>
 <input type="checkbox" name="$unsubscribe" value="true" />
 <span class="text">Unsubscribe me from all emails.</span>
 </label>
 </div>
 
 <div class="clearfix form-actions">
 <div class="pull-right">
 <button type="submit" class="btn btn-default btn-primary">Update Preferences</button>
 </div>
 </div>
 </form>
 
 <footer class="footer">
 <p>
 &copy; 2017 Company Name &mdash; <a href="https://www.klaviyo.com" target="_blank">Privacy Policy</a>
 </p>
 </footer>
 
 </div> <!-- /container -->
 
 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
 <!-- Latest compiled and minified JavaScript -->
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
 <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.13.1/jquery.validate.min.js"></script>
 
 <script>
 $(function () {
 $('#preferences_form').validate({
 rules: {
 $email: {
 required: true
 }
 },
 messages: {
 $email: 'Please enter your email address.',
 $first_name: 'Please enter your first name.',
 $last_name: 'Please enter your last name.'
 }
 });
 // Toggle validation based on selection.
 $('input[name="$unsubscribe"]').on('change', function () {
 $('form .form-actions button[type="submit"]').toggleClass('cancel', $(this).is(':checked'));
 });
 });
 </script>
 
 </body>
</html>

Set a Form's Redirect After Submission (Optional)

By default, after a form is submitted successfully, the user will be redirected. If they've requested to unsubscribe, the user will be sent to the global "Unsubscribe Confirmation" page in your Klaviyo account. If they've updated their profile (or done anything that's not an unsubscribe request), the user will be sent to the global "Preferences Confirmation" page.

If you want to customize where someone is redirected to, you can add a hidden input to your form with the name of the field being the redirect type, and the value of the field being the URL you want to redirect users to. The two field names are:

  • $unsubscribed_url: custom URL to redirect to after someone unsubscribes
  • $updated_profile_url: custom URL to redirect to after someone updates their profile

Using the Custom Unsubscribe Page

For each Klaviyo list that you want to use a custom unsubscribe or manage preferences page for, you'll have to configure the list to use your custom page instead of the default. Additionally, if you would like to use a custom page for flow emails or campaigns sent to a segment, you will have to switch your default email forms unsubscribe/preferences pages to use your custom pages instead of the default:

  • Any email that's sent to a specific list will use the opt-in related forms customized for that list
  • Any email that is NOT sent to a specific list -- i.e. behavior-triggered flow emails or campaigns sent to a segment -- your default email forms will be used

If you want to use a custom unsubscribe and/or preferences page for every email sent, you will want to follow these steps for every list as well as your default email forms.

  1. Navigate to a list you want to connect to your custom pages
  2. Click Subscribe Pages > View All Pages to get a list of all opt-in related pages you can modify
  3. Under the "Unsubscribe" and "Preferences" pages, you will see a Use Custom Page option

    2017-05-22_10-38-32.png
  4. When you click this, a dialog window will appear. Select your custom page file and click Save Settings.

In your emails, use should still use the standard Klaviyo unsubscribe and manage preferences tags. These tags will populate as links in your live emails, and will automatically bring recipients to your custom pages if you've configured them correctly.

Adding Custom Assets to Hosted Pages

If you want to use your own CSS file, image, or other custom assets on your hosted page, upload them into your Klaviyo account and reference them in the source code of the page.

Use the following tag to reference an asset you've uploaded to your Klaviyo account: {% asset_url 'myCustomStyles.css' %}

hosted_pages.png

FAQ about Hosted Pages

Do I need to add any JavaScript to my page for this form to submit properly?
Since your custom forms will be contained inside of a hosted page, you don't have to add any extra JavaScript or an action URL to the <form> to make it submit properly. As long as a hosted page is visited from an email sent via Klaviyo, it will automatically tie back to the correct contact.

Does this page have to be in HTML?
This page must be in HTML. You can include additional images, stylesheets, etc., either by linking to them or by adding a folder of included files. 

Can Klaviyo help me build a custom page?
Klaviyo does not currently offer services to help build out custom code, nor do we provide support for custom code troubleshooting. The Hosted Pages feature is meant to provide a blank slate for developers or code savvy marketers.

Was this article helpful?
0 out of 2 found this helpful