request
The request object is the buyer-safe, Shopify-compatible view of the current
storefront request. It describes the public host, origin, locale, path, page
type, and theme-preview modes without exposing the underlying server request.
Availability and context
request is available in every storefront Liquid render, including theme
editor and visual-preview renders. request.locale is a shop_locale object,
not a plain locale string. Normal requests retain their pathname even when the
route resolves to a 404. The themed fallback 404 currently normalizes its empty
path to /; request.path is nil only when a render explicitly supplies a
nil path.
Examples
Build a canonical absolute URL
request.path contains only the localized pathname; it never includes query
parameters.
{% if request.origin != blank and request.path != blank %} <link rel="canonical" href="{{ request.origin }}{{ request.path }}">{% endif %}Example output:
<link rel="canonical" href="https://shop.example.com/products/sandalwood-candle">Render locale-aware navigation
<html lang="{{ request.locale.iso_code }}"> <a href="{{ request.locale.root_url }}"> {{ request.locale.endonym_name | escape }} </a></html>Example output on the French storefront:
<html lang="fr"> <a href="/fr">français</a></html>Use localized resource URLs and request.locale.root_url; do not construct
locale prefixes by splitting request.path.
Avoid analytics side effects in editor previews
Buyer functionality should remain testable in previews, but analytics and third-party scripts should not create production visits or interfere with the editor frame.
{% unless request.design_mode or request.visual_preview_mode %} <script src="{{ 'analytics.js' | asset_url }}" defer></script>{% endunless %}Example output in a normal storefront request:
<script src="https://cdn.example.com/assets/analytics.js" defer></script>In design mode or visual preview mode, the example intentionally emits no
script. Do not disable product forms, cart actions, account links, or checkout
just because design_mode is true.
Branch on the routed page type
{% case request.page_type %} {% when 'product' %} <span class="visually-hidden">Product page</span> {% when 'collection' %} <span class="visually-hidden">Collection page</span> {% when 'customers/account' %} <span class="visually-hidden">Customer account</span> {% when '404' %} <span class="visually-hidden">Page not found</span>{% endcase %}Common Sellerlane values are index, product, collection, page, blog,
article, search, policy, cart, customers/account,
customers/login, customers/register, customers/addresses,
customers/rewards, customers/activate_account,
customers/reset_password, customers/order, list-collections, password,
and 404. Custom storefront routes can provide additional values, so include a
fallback when exhaustive routing matters.
Security boundary
Only the properties in the table below are public. Unknown property access
returns nil. In particular, request does not expose:
- headers, cookies, IP or geolocation headers;
- raw query parameters or the server request body;
- CSRF tokens, login/session tokens, or editor origins; or
- internal middleware, tenant, tracing, or server state.
For the deliberately narrow public query values q, type, and sort_by, use
sellerlane.query_state. Use each filter value’s url_to_add and
url_to_remove for facet state; pagination state is not exposed through
query_state. For POSTs, use {% form %}; it injects the CSRF field without
making the token readable through Liquid.
Properties
| Property | Description |
|---|---|
request.design_mode | true for the current draft-theme editor render. |
request.host | Host being served. |
request.locale | Active locale. |
request.origin | Accepted storefront scheme and host, or an empty string on a narrow/error render that has no public origin. |
request.page_type | Runtime page type such as product, collection, customers/account, customers/login, or customers/order. |
request.path | Current storefront path. Guard both origin and path before constructing an absolute URL because narrow/error surfaces can supply empty or fallback values. |
request.visual_preview_mode | Currently equivalent to design_mode: true for the same draft-theme editor render. |
Property list is generated from the storefront engine (RequestDrop), so it always matches what your theme can use. Use {{ request | json }} only as a curated debug snapshot; it can omit lazy or otherwise public properties.
Sellerlane differences from Shopify
- Sellerlane account page types use
customers/*values such ascustomers/account,customers/login, andcustomers/order. request.localeis the active published Sellerlane shop locale, includingiso_code, names, primary status, androot_url.visual_preview_modeis a separate public property, but the current renderer sets it to the same value asdesign_mode: both are true for verified draft theme renders and false otherwise.- Sellerlane intentionally provides no generic
request.paramsor raw query object.sellerlane.query_stateexposes onlyq,type, andsort_by; it does not expose facet filters or pagination state.