Translation keys and the t filter
You can access translated content in your internationalized Shopify theme by using translation keys and the t
(translation) filter in your template files.
This tutorial shows how to use translation keys and the t
filter to access the locale file for the active language and return the corresponding string of translated text in the locale file.
Retrieve a translated string
The translation filter retrieves the translated content from the locale file for the active language.
When a translation key is passed in a template file:
The
t
filter uses that key to access the locale file for the active language.The corresponding string of translated text in the locale file is returned.
Translation key
The following example shows how to output a string from a locale file to a Liquid template, section, or snippet file. In this case, the translation key is being used to output "Your email" within the comments section on a store's blog.
The translation key must be wrapped in single quotes:
Input
<span>{{ 'blog.comment.email' | t }}</span>
Locale files
Let's assume your theme is offered in English, French, and Spanish. The following examples show how to include a corresponding translation key for 'blog.comment.email'
in each of the applicable locale files:
locales/en.default.json
Input (English)
{
"blog": {
"comment": {
"email": "Your email"
}
}
}
locales/fr.json
Input (French)
{
"blog": {
"comment": {
"email": "Votre adresse courriel"
}
}
}
locales/es-ES.json
Input (Spanish)
{
"blog": {
"comment": {
"email": "Su correo electrónico"
}
}
}
HTML
The following examples show the returned HTML for the three locale files:
Output (English)
<span>Your email</span>
Output (French)
<span>Votre adresse courriel</span>
Output (Spanish)
<span>Su correo electrónico</span>
Interpolate arguments
Any arguments passed to the t
filter can be interpolated, for example:
theme.liquid
{% if customer %}
<h1>{{ 'layout.header.hello_user' | t: name: customer.first_name }}</h1>
{% endif %}
locales/en.json
{
"layout": {
"header": {
"hello_user": "Hello {{ name }}!"
}
}
}
Returned code
<h1>Hello Jane!</h1>
Pass multiple arguments
You can pass multiple arguments to a t
filter by separating them with commas:
theme.liquid
{{ 'layout.comment.metadata' | t: author: comment.author, email: comment.email }}
locales/en.json
{
"layout": {
"comment": {
"metadata": "Posted by {{ author }} — {{ email }}"
}
}
}
Returned code
Posted by Wilson Abercrombie — wilson.abercrombie@dayrep.com
Escape translated content
Translated content is escaped by default. Any HTML character is converted into its entity equivalent.
For example:
theme.liquid
{% capture link %}
<a href="https://support.mystore.com">{{ 'layout.header.support_link' | t }}</a>
{% endcapture %}
<h1>{{ 'layout.header.welcome' | t: link: link }}</h1>
locales/en.default.json
{
"layout": {
"header": {
"support_link": "support",
"welcome": "Welcome to my store. Please contact {{ link }} should you
need any assistance."
}
}
}
Returned code
<h1>Welcome to my store. Please contact <a href="https://support.mystore.com">support</a> should you need any assistance.</h1>
Include HTML in translation keys
To include HTML code in translation keys, append _html
to the end of the key, for example:
theme.liquid
{% capture link %}
<a href="https://support.mystore.com">{{ 'layout.header.support_link' | t }}</a>
{% endcapture %}
<h1>{{ 'layout.header.welcome_html' | t: link: link }}</h1>
locales/en.default.json
{
"layout": {
"header": {
"support_link": "support",
"welcome_html": "Welcome to my store. Please contact {{ link }} should
you need any assistance."
}
}
}
HTML characters returned unchanged
<h1>Welcome to my store. Please contact <a href="https://support.mystore.com">support</a> should you need any assistance.</h1>
When a translation is to be used in JavaScript, whether as part of a script tag in a template file or a .js.liquid
asset file, it should always use the _html
suffix.
Shopify escapes all translations except those that use _html
. For example, as a result of not using _html
, single quotes and double quotes in a translation will end up being rendered as '
and "
when added with $.val()
or alert
. Shopify will escape the quotes once, and then JavaScript will escape the resulting ampersands. You'll avoid the double escaping if you use _html
.
addToCartButton.val({{ 'products.product.add_to_cart_html' | t | json }});
Pluralize translation keys
Passing count
to the t
filter allows for locale-aware pluralization.
For example, English has the two pluralization forms:
one
: aka. "singular". ex. "I have 1 car"other
: aka. "plural". ex. "I have 4 cars"
Other languages have more or fewer pluralization forms, and have different rules for when to use each form.
Supported pluralization keys are defined by the Unicode Consortium's CLDR and are:
few
many
one
other
two
zero
.
For example:
theme.liquid
{% if customer %}
<h1>{{ 'customer.orders.order_count' | t: count: customer.orders_count }}</h1>
{% endif %}
locales/en.default.json
{
"customer": {
"orders": {
"order_count": {
"one": "You've made {{ count }} order with us",
"other": "You've made {{ count }} orders with us"
}
}
}
}
Returned code
// count = 1
<h1>You've made 1 order with us</h1>
// count = 12
<h1>You've made 12 orders with us</h1>
For more information about pluralization rules in different languages, take a look at the Unicode Language Plural Rules tables.
Include template elements in values
Values can contain HTML and Liquid objects (through interpolation). You should limit the presence of these elements in the translation files, to ensure a simple translation process for merchants creating an additional language.
In some cases, you might have to include template elements in the values to accommodate linguistic and grammatical differences. For example:
English
Posted by {{author}} on {{ date }}
French
Publié le {{ date }} par {{ author }}