Consent Page

The consent page allows your customers to see all the consent categories including legitimate interests you had predefined in the project settings and to unsubscribe from any of them if they choose to. The consent page should be available and embedded on your website as the option to opt-out is absolutely crucial in assessing the continued validity of customers’ consents. It also ensures that your email deliverability rating remains high as people only receive those emails which they want.

The consent page is an editor within Bloomreach Engagement that allows your customers to manage their subscription preferences. On the consent page, your customer can choose to opt-out on your website. To use the consent page editor go to Settings > Project Settings > Campaigns > Privacy > Management.

The consent page is accessible through a link generated uniquely for every customer. It is either generated through Jinja {{ }} format or when creating a campaign you can generate the link by clicking on the personalization button and get the following: <a href="{{ }}">Click here ...</a>

Consent page link can be found in the personalization tabs of these:

  • SMS
  • Email
  • Push notifications
  • Add event (Node in a scenario)
  • Set property (Node in a scenario)
  • WebLayers
  • Experiments
  • Tag manager
  • Facebook message


Issues with the tracking

If you are using our consent page outside of your own domain for subscribing/unsubscribing customers, no page_visit or session_start events will be generated.


The consent link works only in real launched campaigns and will not work in the test email.

Customization with HTML, CSS, JS, Jinja

You can edit and customize the consent page through JS, HTML, CSS, and Jinja, for example, to display the particular customer’s name.

Consent categories visible on the consent page

All categories created in the Project settings > Privacy management > Consents will be visible for the customers on the consent page.

Multi-language support

You can create various language groups for the Consent page. The language groups are visible once you defined your languages in the settings.

Additional use cases

Hiding categories

You can hide some categories from displaying on the consent page by adding Jinja into the code. This example shows how to hide 2 categories: category_to_hide_1 and category_to_hide_2.

In the HTML code, add if and else statements into the Jinja for loop:

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

This will visually hide these 2 consent categories from the consent page. However, if the user clicks on the Unsubscribe from all button, the user will also be unsubscribed from the 2 hidden categories.

Depending on your use case, you might want to prevent the Unsubscribe from all button from also unsubscribing from these hidden categories. To do that, you would need to add a similar if statement into the JS code:

{%- for category in categories -%}
    {% if not in ["category_to_hide_1", "category_to_hide_2"] %}
        check = document.getElementById({{ ('category_' ~ | json }});
        if (!check.disabled) {
            check.checked = false;
    {% endif %}
{% endfor %}

Creating custom sub-categories (advanced)

You can create custom sub-categories for each category through customer attributes. It can be either a boolean type (checkbox) or a text input.

In this example, "Sales" will be displayed as a sub-category on the consent page while the name of the matching customer attribute in Bloomreach Engagement will be "newsletter_sales":

	    <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>

For boolean attributes:

  • The name must start with the keyword property followed by the attribute name (name="property property_name").
  • Every checkbox input needs to have a hidden input element with the same name and no value attribute. Hidden inputs are used to detect which checkboxes the customer did not check yet.
  • The hidden input elements must bear the same name as the checkbox. In the example above, it is newsletter_sales.
  • Use Jinja to load already existing values. Do not compare value to true as this is not its value ({% if customer.newsletter_sales == true %}) - ensure to use the format without "== true" part as in the example above (line 3).
  • Checkboxes cannot contain empty value attributes: Do not use value="".

For other attribute types (text)

Other attributes can be specified using inputs (e.g. text type) and do not require any duplicated hidden input alongside them. Their name must start with the keyword property_text as in the example below:

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

Changes will be visible on the consent page immediately after saving but it may take a few minutes until they become visible in Bloomreach Engagement.


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


Changes in consent

If consents or sub-categories are updated manually or by tracking, these changes are not reflected immediately on the consent page when it is reloaded due to caching. Time to live (TTL) of the cache is 30 minutes.
Changes done on the consent page directly are, on the other hand, reflected immediately.

Language versions for category names (advanced)

You can have multiple language versions of the consent page as explained above. However, you need to translate the names of each category through an additional Jinja code. Let's say you have categories "Newsletter" and "Personalization" and want to translate them into German.

First, you need to set the translations. Adjust and insert this code as the very first thing in the HTML code:

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

Now you can use the translations. If you are translating all your categories, simply locate the line {% for category in categories %} and paste the following code below that line:

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

Passing a custom value to a consent page (advanced)

If you append a query parameter mode with a consent page link, you are able to access a value from this parameter and behave accordingly once a customer visits a consent page.
For example, if you have a specific marketing campaign and you want to show/hide some parts of a general consent page append a _mode _to a URL link:
{{ ~ "?mode=Special_campaign"}}.
Then use a Jinja {{mode}} in a consent page to access the value from a URL. This value can be used in an if condition to show/hide categories on a consent page.
If no mode is put into the link, the {{mode}} jinja will return "default" as a value

If you are using multiple language versions of the consent page, ?lang parameter always gets added first, so using
?mode=Special_campaign results in an invalid query string. Something like ?lang?mode=Special_campaign whereas it should be ?lang&mode=Special_campaign . Because of that, you need to use &mode=Special_campaign instead of ?mode=Special_campaign.

If you would like to use specific consent page for customers that have and customers that don't have language property, you should use if-else statement to change the ? sign to & for customers that have language property:
{%-if customer.language is defined -%}{{- ~ "&mode=survey" -}}{%-else -%}{{- ~ "?mode=survey" -}}{%- endif -%}\


Consent events tracked from consent page can serve to trigger Scenarios.