Skip to main content

Internationalization

To reach a global audience, build your theme so its text, layout, and formatting adapt to each customer's language. Follow these practices to make a theme translatable and locale-aware.

Use translation keys instead of hardcoded text

Don't hardcode customer-facing strings in your templates. Store them in locale files and output them with the t filter. The translation key must be prefixed with i18n.:

{{ 'i18n.products.product.add_to_cart' | t }}

With "add_to_cart": "Add to cart" set under that key in en-US.json, this renders Add to cart; the same key in fr.json renders Ajouter au panier, so the storefront shows the right wording per locale. This lets merchants and translators localize your theme without editing templates. For the locale file format and full usage, see Storefront locale files.

Interpolate dynamic values

Pass named arguments to insert variables into a translation instead of concatenating strings:

{{ 'i18n.cart.summary.item_count' | t: count: cart.item_count }}

The locale string holds the variable in double braces, and the named argument fills it. With "item_count": "{{count}} items" in the locale file and a cart of 3, this renders 3 items. Pass multiple arguments separated by commas: | t: count: 3, name: 'Tom'.

Count-based plural forms (such as one/other value objects) aren't supported. When wording changes with a number, branch in Liquid and use a separate key for each form:

{% if cart.item_count == 1 %}
{{ 'i18n.cart.summary.item_count_one' | t }}
{% else %}
{{ 'i18n.cart.summary.item_count_other' | t: count: cart.item_count }}
{% endif %}

Detect the active language

The store's active locale is available on the shop object as shop.locale — for example, en-US or ar-SA. Use it when behavior needs to depend on the language:

For example, choose a date format that matches the language (something the t filter can't express on its own):

{% assign date_format = '%b %d, %Y' %}
{% if shop.locale == 'ja-JP' %}{% assign date_format = '%Y年%m月%d日' %}{% endif %}
{{ 'now' | date: date_format }}

Support right-to-left languages

Languages such as Arabic and Hebrew read right to left. The platform doesn't set text direction automatically — your theme must do it. Set the dir attribute on the <html> element in your layout based on shop.locale:

<html lang="{{ shop.locale }}"{% if shop.locale == 'ar-SA' %} dir="rtl"{% endif %}>

Add a check for each right-to-left locale your theme supports, and make sure your CSS handles the mirrored layout — for example, use logical properties such as margin-inline-start instead of margin-left.

Prefer native translation over client-side widgets

Translate your theme through native locale files and the t filter. This text is rendered on the server, so search engines index it and it stays consistent with the rest of the page.

Third-party translation widgets, such as a Google Translate dropdown, overlay translations in the browser after the page loads. They're quick to install but produce lower-quality, non-indexable text. Use them only as a fallback, not as your primary localization.