/consent
{% form 'consent_give' %}
Records the visitor's cookie-consent choice on their visitor session. The optional categories are defined by the platform: analytics, advertising, advertising_data, personalized_advertising, personalization. Essential storage is always allowed. The server records the time and country of the choice.
Form fields
-
categoriesOptional Repeatable. Categories the visitor grants: analytics, advertising, advertising_data, personalized_advertising, personalization. Essential storage is always allowed and is never posted. Send no categories and no accept_all to record a necessary-only choice.
-
accept_allOptional Any non-empty value grants every category. Use it for the banner's Accept all button.
-
return_toOptional Path to return to; defaults to the referring page.
-
_formatOptional Set to json when submitting with fetch; omit for the normal browser redirect.
Validation
Requires a visitor session. Each category must be one of analytics, advertising, advertising_data, personalized_advertising, personalization. An unknown category refuses the whole choice with STOREFRONT_CONSENT_CATEGORY_INVALID and saves nothing. The server records the time and country of the choice; values sent by the client are ignored.
Limits
One consent choice per visitor session; a new submission replaces the previous choice.
Response
{
success,
consent,
user_errors
}
consent has the same fields as the CTX consent root: required, given, categories and available_categories. A refused choice returns HTTP 400 with success: false and user_errors. A request without a visitor session fails the CSRF check with HTTP 403 and STOREFRONT_RUNTIME_CSRF_INVALID. A form submission redirects to return_to (or the referring page) with HTTP 303 and reports a refusal through form_notice.
/consent/withdraw
{% form 'consent_withdraw' %}
Withdraws optional consent by recording an explicit no-consent choice. From the next page, analytics are counted anonymously and the advertising attribution cookie is removed.
Form fields
-
return_toOptional Path to return to; defaults to the referring page.
-
_formatOptional Set to json when submitting with fetch; omit for the normal browser redirect.
Validation
Requires a visitor session.
Limits
Repeatable: withdrawing without an earlier choice still records an explicit no-consent choice.
Response
{
success,
consent,
user_errors
}
consent has the same fields as the CTX consent root. A request without a visitor session fails the CSRF check with HTTP 403 and STOREFRONT_RUNTIME_CSRF_INVALID. A form submission redirects to return_to (or the referring page) with HTTP 303.
/localization
{% form 'localization_set' %}
Changes the visitor's country, language, or both. A form submission redirects to the same page at the address for the new choice; JSON returns the new localization and redirect_url.
Form fields
-
country_codeOptional ISO country code from localization.available_countries. Omit it to change only the language; the current country is kept.
-
localeOptional Language code from localization.available_languages. Omit it to change only the country; the language then becomes the new country's default language.
-
return_toOptional Path on this storefront to return to. Defaults to the referring page. The path is readdressed for the new country and language.
-
_formatOptional Set to json when submitting with fetch; omit for the normal browser redirect.
Validation
Send country_code, locale, or both. Values must come from localization.available_countries and localization.available_languages, and a language must be offered in the chosen country. When only locale is sent, the current country is kept: the domain's own country when the domain has one, otherwise the country in the page address (/{locale}-{country}), otherwise the country saved on the visitor session, otherwise the store's country. When only country_code is sent, the language becomes that country's default language. return_to is reduced to a path on this storefront and addressed for the new choice.
Limits
External return URLs are never used as destinations.
Response
{
success:true,
data:{market,
currency,
localization,
available_countries,
available_languages,
stamped,
redirect_url},
user_errors
}
stamped is true when the choice was saved to the visitor session. A refused choice returns HTTP 400 with success: false and user_errors: STOREFRONT_UNSUPPORTED_COUNTRY, STOREFRONT_UNSUPPORTED_LANGUAGE, or STOREFRONT_LOCALIZATION_CHOICE_REQUIRED when neither field is sent. A form submission redirects to redirect_url with HTTP 303 and reports a refusal through form_notice.
Country and language switchers#
{% form 'localization_set' %} posts to /localization. Send country_code, locale, or both: a country picker sends only country_code, and a language picker sends only locale. Take the values from localization.available_countries and localization.available_languages, described in Locale, country, and currency.
{% for country in localization.available_countries %}
{% form 'localization_set' %}
<input type="hidden" name="country_code" value="{{ country.iso_code }}">
<button type="submit"{% if country.selected %} aria-current="true"{% endif %}>{{ country.flag }} {{ country.name }} ({{ country.currency_code }})</button>
{% endform %}
{% endfor %}
{% for language in localization.available_languages %}
{% form 'localization_set' %}
<input type="hidden" name="locale" value="{{ language.iso_code }}">
<button type="submit"{% if language.selected %} aria-current="true"{% endif %}>{{ language.native_name | default: language.name }}</button>
{% endform %}
{% endfor %}
When only locale is sent, the visitor keeps their current country: the domain's own country when the domain has one, otherwise the country in the page address (/{locale}-{country}), otherwise the country saved for the visitor, otherwise the store's country. When only country_code is sent, the currency becomes that country's currency and the language becomes the country's default language. When both are sent, the language must be offered in that country.
A form submission redirects (HTTP 303) to the page the visitor came from, at its address for the new country and language. With JSON, redirect_url carries that address and the storefront bridge navigates to it.
Errors#
Refused choices return success: false with user_errors, and change nothing.
Code |
HTTP status |
When |
|---|---|---|
STOREFRONT_LOCALIZATION_CHOICE_REQUIRED |
400 |
localization_set received neither country_code nor locale. |
STOREFRONT_UNSUPPORTED_COUNTRY |
400 |
The country is not one of localization.available_countries. field is country_code. |
STOREFRONT_UNSUPPORTED_LANGUAGE |
400 |
The language is not offered in the chosen country. field is locale. |
STOREFRONT_CONSENT_CATEGORY_INVALID |
400 |
consent_give received a category outside the platform set. field is categories. |
STOREFRONT_RUNTIME_CSRF_INVALID |
403 |
The CSRF token is missing or expired, or the visitor has no session. |
STOREFRONT_RUNTIME_INTERNAL |
500 |
A temporary failure. Try again. |
{
"success": false,
"user_errors": [
{
"code": "STOREFRONT_UNSUPPORTED_COUNTRY",
"message": "The country ZZ is not available for this store.",
"locale": "en",
"params": [{ "key": "code", "value": "ZZ" }],
"field": ["country_code"]
}
]
}
After a native form submission, a refusal appears in form_notice on the next page: STOREFRONT_LOCALIZATION_UNAVAILABLE for a country or language that is not offered, STOREFRONT_LOCALIZATION_CHOICE_REQUIRED, or STOREFRONT_CONSENT_CATEGORY_INVALID.
Cookie consent#
consent_give and consent_withdraw record the visitor's choice on their visitor session. Build the banner from the CTX consent root as shown in Customers, carts, and consent, and see Consent categories for what each category covers and when visitors are asked.
Related#
Order tracking and recommendation clicks are on their own pages in this section.