如何自定义代码同意页面

预计阅读 9 分钟 | 更新于 2026年4月21日 9:54 AM EST

你会学到

了解如何启用和使用 Klaviyo 的托管页面功能,该功能允许您自定义代码自己的首选项页面、订阅页面和取消订阅页面。

本文适用于开发者; Klaviyo 目前不提供帮助构建自定义代码的服务,也不提供自定义代码故障排除的支持。要了解我们的内置应用程序同意页面,请访问我们的 有关同意页面入门的文章.

开始之前

在配置托管页面之前,启用此功能:

  1. 导航至 设置 > 其他.
  2. 选择 同意书页 从下拉菜单中。
  3. 在下面 自定义托管页面,将开关切换至 对托管页面使用自定义专用域.
    The Custom Hosted Pages section on the Consent Pages tab in Klaviyo showing the switch to enable hosted pages.

请注意,只有通过了付费计划的帐户 账户验证 有权访问此设置。

创建自定义同意页面

  1. 前往 设置 > 其他.
  2. 点击 托管页面. 
  3. 旁边 页数,单击 + 符号添加新页面。
  4. 命名此页面(例如,unsubscribe.tmpl);您可以将其用于任何同意页面,但如果您愿意,可以创建多个页面。 

    托管页面名称不能包含空格,否则会导致错误。避免使用空格或使用下划线来分隔标题。

  5. 设计一个包含您选择的字段和功能的 HTML 页面。可以为自定义同意页面插入的示例字段包括:
    • 电子邮件频率的选择:
      • 取消订阅的选项
      • 接收所有电子邮件的选项
      • 每日、每周、每月等时事通讯的频率选项
    • 可用于定位和细分的信息:
      • 用户是否想要销售公告的复选框
      • 用户是否想要产品公告的复选框
      • 用户是否想要博客更新的复选框
      • 用户可能想要加入的其他列表
同意页面的 HTML 代码示例

您可以在 unsubscribe.tmpl 中使用此代码来获取功能齐全的同意页面,其中包含电子邮件类型和频率首选项:

<!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 %}{% 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 %}{% endif %} />
                     Promotions & 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 %}{% elif not person.EmailInterests and not request.POST.EmailInterests %}{% 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 %}{% elif not person.EmailInterests and not request.POST.EmailInterests %}{% 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>
               © 2017 Company Name — <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'));
            });
        });
        $('input[name="$unsubscribe"]').on('change', function(){
          $('input[type=checkbox]').not(this).prop('checked', false);
        });
        $('input[type=checkbox]').not('input[name="$unsubscribe"]').on('change', function(){
          $('input[name="$unsubscribe"]').prop('checked', false);
        });
    </script>
   </body>
</html>

提交后设置托管页面的重定向(可选)

默认情况下,成功提交托管页面(例如托管首选项页面)后,用户将被重定向到以下两个位置之一:

  • 如果他们请求取消订阅,他们将被发送到您帐户的默认取消订阅确认页面。
  • If they’ve updated their profile (or done anything that’s not an unsubscribe request), the user will be sent to your account’s default preferences confirmation (success) page.

如果您使用上面的示例 HTML,这将在 <body> 中反映为:

<!-- <input type="hidden" 
name="$unsubscribed_url" value="/p/preferences_updated" /> -->
<!-- <input type="hidden"
name="$updated_profile_url" value="/p/preferences_updated" /> -->

要自定义提交托管页面后将某人重定向到的位置,请将 value=”…” 行调整为 HTML 中您的首选 URL。

将自定义资源添加到托管页面(可选)

如果您想在托管页面上使用自己的 CSS 文件、JS 文件或图像,请通过单击 + 旁边的符号 资产 并在页面的源代码中引用它们。

使用以下标签来引用您已上传到 Klaviyo 帐户的资产: {% asset_url 'style.css' %}

source code of your consent page showing uploaded custom asset tag

使用自定义同意页面

您可以将每个帐户的默认同意页面替换为自定义编码页面,以便所有电子邮件默认使用这些自定义页面。或者,您可以仅配置 1 个特定列表以使用自定义编码页面,以便只有发送到该列表的电子邮件才会使用自定义页面。 

  • 如果您为特定列表自定义了同意页面,则发送到该列表的任何电子邮件都将使用这些唯一的同意页面。
  • 您尚未为其自定义唯一同意页面的任何列表都将使用您帐户的默认同意页面。此外,任何未发送到特定列表的电子邮件,包括指标触发的流电子邮件、发送到分段的营销活动或 个人电子邮件,还将使用您的默认同意页面。

将默认同意页面更改为托管页面

如果您想将帐户的 1 个或多个默认同意页面(例如首选项页面、订阅页面或电子邮件取消订阅页面)替换为自定义编码页面,请按照以下步骤操作: 

  1. 单击 Klaviyo 左下角您的公司名称。 
  2. 选择 设置.
    Account tab in the bottom left corner with settings selected from the navigation menu
  3. 选择 其他 从顶部。
  4. 单击您计划替换的同意页面上的 3 点下拉菜单,然后选择 使用托管页面.
    The Consent Pages tab in Klaviyo showing an the additional options menu open on an example preference page.
  5. 在出现的对话框窗口中,选择您的自定义页面文件,然后单击 节省. 

如果您想对发送到分段的流电子邮件或营销活动使用自定义页面,则必须将帐户的默认同意页面切换为使用自定义页面。按照与上述相同的流程,将默认同意页面替换为自定义编码页面。 

使用自定义同意页面作为列表

您必须配置要使用自定义页面而不是默认同意页面的每个单独列表。

  1. 导航到您想要连接到自定义页面的列表。 
  2. 单击 订阅和偏好页面 选项卡可查看该列表的所有可编辑同意页面。 
  3. 在您想要替换为自定义页面的同意页面下,单击 3 点下拉菜单并选择 使用托管页面. 
    The Subscribe & preferences pages tab for an example list in Klaviyo showing the additional actions menu open on the preferences page.

    请注意,如果您愿意,您可以选择对所有同意页面使用托管页面。

  4. 在出现的对话框窗口中,选择您的自定义页面文件,然后单击 节省.

在您的电子邮件中,您仍然应该使用标准的 Klaviyo 取消订阅和管理首选项标签 (即 {% unsubscribe %} 和 {% manage_preferences %})。这些标签将作为链接填充在您的实时电子邮件中,并自动将收件人带到您的自定义页面。 

托管页面常见问题解答

我是否需要在页面中添加任何 JavaScript 才能正确提交此表单?
由于您的自定义表单将包含在托管页面内,因此您无需向 <form> 添加任何额外的 JavaScript 或操作 URL 即可使其正确提交。 只要通过 Klaviyo 发送的电子邮件访问托管页面,它就会自动绑定回正确的联系人。

该页面必须是 HTML 格式吗?
此页面必须为 HTML 格式。您可以通过链接或添加包含文件的文件夹来包含其他图像、样式表等。

Klaviyo 可以帮助我构建自定义页面吗?
Klaviyo 目前不提供帮助构建自定义代码的服务,也不提供自定义代码故障排除的支持。这 托管页面 该功能旨在为 开发人员或精通代码的营销人员.

了解有关 Klaviyo 内置同意页面的自定义功能的更多信息 同意页面入门.

其他资源