Age gate

Render the store's age gate as a theme section, or let the platform show a plain one.

A store can turn on an age gate in Settings > Compliance. Every storefront page then asks visitors to confirm a minimum age before they continue. It is a confirmation, not an identity check. The page content stays in the HTML, so search engines, advertising and merchant crawlers always see the store.

Read age_gate#

age_gate is available on every route. show is true when the gate applies to the visitor's country: to every visitor, or, in selected-countries mode, to visitors from those countries and to visitors whose country is unknown. It uses the same visitor country as the consent banner. Render the gate only when show is true. The platform adds its gate script only then, so a gate rendered while show is false could never be dismissed. heading, body, confirm_label and decline_label are already in the shopper's language with the minimum age filled in; body can contain line breaks. min_age, remember_days (0 means the browser session) and decline_url are informational: the platform stores the answer and handles declining.

Render the section#

Add a section named age-gate to the global_overlay surface. Give its root element data-tf-age-gate, role="dialog", aria-modal="true" and aria-labelledby pointing to its heading. Wrap the question in data-tf-age-gate-ask and mark the buttons data-tf-age-gate-confirm and data-tf-age-gate-decline. Render the gate open: do not use the hidden attribute or a closed dialog element.

vascula
{% if age_gate.show %}
  <div class="age-gate" data-tf-age-gate role="dialog" aria-modal="true" aria-labelledby="age-gate-title">
    <div class="age-gate__panel" data-tf-age-gate-ask>
      <h2 id="age-gate-title">{{ age_gate.heading }}</h2>
      <p>{{ age_gate.body }}</p>
      <button type="button" data-tf-age-gate-confirm>{{ age_gate.confirm_label }}</button>
      <button type="button" data-tf-age-gate-decline>{{ age_gate.decline_label }}</button>
    </div>
  </div>
{% endif %}

The platform script does the rest. Before first paint it hides every [data-tf-age-gate] element for a visitor who already confirmed. While the gate is open it keeps focus inside it, makes the rest of the page inert, and ignores Escape. Confirming stores the answer in a first-party cookie for remember_days days or the browser session and dispatches tf:age-gate-confirmed on document. Declining goes to decline_url when the store set one. Otherwise the question is hidden and your [data-tf-age-gate-declined] element is shown, or the platform adds its own come-back-later screen inside your gate. Raising the minimum age asks visitors again.

Without a theme section#

When the active theme renders no element with data-tf-age-gate, the platform adds a plain gate. It uses your theme's fonts and the --bg, --text, --accent and --border colour tokens. In the theme editor the gate stays hidden unless the age-gate section is selected, like the consent banner, so it never covers the sections you edit.