# Internationalization

> Make a Shoplazza Theme translatable and locale-aware: use t filter translation keys, interpolate values, and adapt formatting and right-to-left layout.

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](/docs/theme/architecture/locales/overview) and output them with the [`t` filter](/docs/theme/references/liquid/filters/localization). The translation key must be prefixed with `i18n.`:

```liquid
{{ '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](/docs/theme/architecture/locales/storefront-locale-files#usage).

## Interpolate dynamic values

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

```liquid
{{ '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:

```liquid
{% 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](/docs/theme/references/liquid/objects/shop) 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):

```liquid
{% 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`:

```liquid
<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.
