Consent page

The consent page lets customers view and manage all consent categories you've configured in your project, including legitimate interests. Customers can unsubscribe from any category they choose. Embed it on your website to give customers control over their preferences—this is essential for maintaining valid consent and keeping your email deliverability rating high.

How it works

The consent page is an editor you embed on your website. Each customer gets a unique link to manage their preferences.

  1. Under Settings, select Project settings.
  2. Under Campaigns, go to Privacy management > Consents.

Generate consent page links

You can generate the unique customer link in 2 ways:

  1. Use Jinja: {{ consent.page }}.
  2. In campaigns, click the personalization button to insert: <a href="{{ consent.page }}">Click here ...</a>

Where to find consent page links

The consent page link is available in the personalization tabs of:

  • Add event (scenario node)
  • Email
  • Experiments
  • Facebook message
  • Push notifications
  • Set property (scenario node)
  • SMS
  • Tag manager
  • Weblayers

If you use the consent page outside your own domain, no page_visit or session_start events are generated.

❗️

Warning

The consent link only works in live campaigns. It won't work in test emails.

Customize consent page

You can edit the consent page using HTML, CSS, JavaScript, and Jinja—for example, to display a specific customer's name.

Consent page customization using HTML, CSS, JavaScript, and Jinja

Consent page customization using HTML, CSS, JavaScript, and Jinja

What appears on consent page

All categories you create in Project settings > Privacy management > Consents appear on the consent page.

All consent categories configured in project settings appear on the consent page

All consent categories configured in project settings appear on the consent page.

Multi-language support

You can create different language versions of the consent page. Language groups appear once you define your languages in project settings.

Multi-language support options on the consent page

Multi-language support options on the consent page

Cache behavior and data freshness

Caching stores data temporarily so pages load faster, but can sometimes display outdated information.

How consent pages handle caching

Consent pages use strict cache controls to ensure customers always see the latest consent data, using these HTTP headers:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

These headers tell browsers and content delivery networks to fetch the latest version from the server on every reload. When you update consents, those changes appear immediately when customers refresh the page.

When customers might see outdated data

If customers keep the consent page open for an extended period without reloading, they may submit outdated information. This is a limitation of any web page held open without refreshing.

Advanced customization

Hide specific categories

You can hide categories from the consent page using Jinja. This example hides category_to_hide_1 and category_to_hide_2.

Add this code to your HTML:

{% for category in categories %}
    {% if category.name not in ["category_to_hide_1", "category_to_hide_2"] %}
        <hr>
        <label>
            <input type="checkbox" value="grant" {% if category.valid %}checked{% endif %}
                    id="category_{{ category.id | escape }}"
                    name="category {{ category.id | escape }}">
            <span class="checkbox-title">{{ category.name | escape }}</span>
            {% if category.description %}
                <span class="checkbox-subtitle">{{ category.description | escape }}</span>
            {% endif %}
        </label>
    {% else %}
        <input type="checkbox" value="grant" {% if category.valid %}checked{% endif %}
            id="category_{{ category.id | escape }}"
            name="category {{ category.id | escape }}" hidden>
    {% endif %}
{% endfor %}

Hidden categories aren't visible to customers, but if a customer clicks Unsubscribe from all, they'll also unsubscribe from hidden categories.

To prevent Unsubscribe from all from affecting hidden categories, add this JavaScript:

{%- for category in categories -%}
    {% if category.name not in ["category_to_hide_1", "category_to_hide_2"] %}
        check = document.getElementById({{ ('category_' ~ category.id) | json }});
        if (!check.disabled) {
            check.checked = false;
        }
    {% endif %}
{% endfor %}
Consent page with Unsubscribe from all button excluding hidden categories

Consent page with Unsubscribe from all button, excluding hidden categories

Create custom sub-categories

You can create custom sub-categories for each category using customer attributes—either boolean (checkbox) or text input.

This example displays "Sales" as a sub-category. The matching customer attribute in Bloomreach is newsletter_sales:

       <label>
	    <input type="hidden" name="property newsletter_sales">
	    <input type="checkbox" {% if customer.newsletter_sales %} checked="true" {% endif %} 
 id="newsletter_sales" name="property newsletter_sales">
	    <span class="checkbox-label">Sales</span>
	</label>

Boolean attribute rules

  • Names must start with property followed by the attribute name: name="property property_name".
  • Every checkbox input needs a hidden input with the same name and no value attribute. Hidden inputs detect unchecked checkboxes.
  • Don't compare values to true—use {% if customer.newsletter_sales %}, not {% if customer.newsletter_sales == true %}.
  • Checkboxes can't have empty value attributes. Don't use value="".

Text attributes

Text inputs don't need duplicated hidden inputs. Their names must start with property_text:

<label>
	<input type="text" name="property_text property_name" value="{{ customer.property_name }}">
	<span class="title">Property Name</span>
</label>

Changes appear on the consent page immediately after saving. They may take a few minutes to appear in the application.

📘

Note

Both techniques (boolean and text) only work if the <label> tag is inside the
<form method="POST" action="" id="form"> tag.

How different updates appear

Consent updates

When consents change—either in your system or when customers update their preferences directly—those changes appear immediately on page reload. Strict cache controls ensure customers always see their current consent status.

Customer attribute updates

Updates to customer attributes—such as names, email addresses, or custom properties—don't appear immediately on the consent page. The system caches customer attributes for 30 minutes to improve performance.

For example, if you update a customer's email address at 2:00 PM, the change won't appear on their consent page until after 2:30 PM, even after a reload.

🚧

Important

The 30-minute cache applies only to customer attributes displayed on the consent page, not to consent data itself. Consent changes always appear immediately on reload.

Translate category names

You can create multiple language versions of the consent page. To translate category names, use Jinja. This example translates "Newsletter" and "Personalization" into German.

Add this at the very beginning of your HTML to set up translations::

{% set translations = [{
	'Newsletter': { 
		'name': 'Newsletter_in_German',
		'description':'German description text for the category'
	},
	'Personalisation': {
		'name': 'Personalisierung',
		'description': 'German descriprion text for the category'
	}
}]%}

Find the line {% for category in categories %} and add this code below it to apply the translations:

{{translations[0][(category.name |escape)]['name'] }}
	{% if category.description %}
		{{ translations[0][(category.name |escape)]['description']  }}
	{% endif %}

Pass custom values to consent pages

Add a mode query parameter to a consent page link to change page behavior based on the value. For example, to show or hide parts of the consent page for a specific campaign, append mode to the URL:

{{consent.page ~ "?mode=Special_campaign"}}

Use {{mode}} in Jinja to access the value and show or hide categories with an if condition. If no mode parameter is present, {{mode}} returns "default".

Multi-language considerations

When using multiple language versions, the ?lang parameter is always added first. Using ?mode=Special_campaign creates an invalid query string (?lang?mode=Special_campaign). Use &mode=Special_campaign instead.

For customers with and without a language property, use an if-else statement:

{%-if customer.language is defined -%}{{- consent.page ~ "&mode=survey" -}}{%-else -%}{{- consent.page ~ "?mode=survey" -}}{%- endif -%}

Track consent events

Consent events tracked from consent pages can trigger scenarios.


© Bloomreach, Inc. All rights reserved.