Internationalization fundamentals for multi-language Shopify themes
Shopify themes use JSON files in the locales/ directory:
locales/
├── en.default.json # English (default language)
├── en.default.schema.json # English schema translations
├── fr.json # French translations
├── fr.schema.json # French schema translations
├── de.json # German translations
└── de.schema.json # German schema translations
Used for theme content displayed to customers:
{
"general": {
"search": "Search",
"cart": "Cart",
"menu": "Menu",
"close": "Close",
"loading": "Loading...",
"continue_shopping": "Continue Shopping"
},
"product": {
"add_to_cart": "Add to Cart",
"sold_out": "Sold Out",
"unavailable": "Unavailable",
"price": "Price",
"vendor": "Vendor"
},
"cart": {
"title": "Your Cart",
"empty": "Your cart is empty",
"subtotal": "Subtotal",
"checkout": "Checkout"
}
}
Used for Theme Editor labels:
{
"sections": {
"featured_products": {
"name": "Featured Products",
"settings": {
"heading": {
"label": "Heading",
"info": "Section heading text"
},
"collection": {
"label": "Collection"
}
}
}
}
}
{{ 'general.search' | t }}
{{ 'product.add_to_cart' | t }}
{{ 'cart.title' | t }}
{%- # In locale file -%}
{
"cart": {
"item_count": "{{ count }} items"
}
}
{%- # In Liquid -%}
{{ 'cart.item_count' | t: count: cart.item_count }}
{%- # In locale file -%}
{
"general": {
"continue_html": "Continue <span>shopping</span>"
}
}
{%- # In Liquid -%}
{{ 'general.continue_html' | t }}
{% schema %}
{
"name": "t:sections.featured_products.name",
"settings": [
{
"type": "text",
"id": "heading",
"label": "t:sections.featured_products.settings.heading.label"
}
]
}
{% endschema %}
{
"general": {
"search": "Search",
"cart": "Cart",
"menu": "Menu",
"close": "Close",
"loading": "Loading...",
"buttons": {
"learn_more": "Learn More",
"shop_now": "Shop Now",
"view_all": "View All"
},
"forms": {
"submit": "Submit",
"email": "Email",
"name": "Name",
"message": "Message"
}
}
}
{
"product": {
"add_to_cart": "Add to Cart",
"sold_out": "Sold Out",
"unavailable": "Unavailable",
"in_stock": "In Stock",
"out_of_stock": "Out of Stock",
"price": {
"from": "From {{ price }}",
"regular_price": "Regular price",
"sale_price": "Sale price"
}
}
}
{
"cart": {
"title": "Cart",
"empty": "Your cart is empty",
"item_count": "{{ count }} items",
"subtotal": "Subtotal",
"shipping": "Shipping",
"total": "Total",
"checkout": "Checkout",
"remove": "Remove"
}
}
{
"forms": {
"contact": {
"name": "Name",
"email": "Email",
"message": "Message",
"send": "Send Message",
"success": "Thank you for your message!",
"error": "Please correct the errors below"
}
},
"errors": {
"general": "An error occurred",
"required_field": "This field is required",
"invalid_email": "Please enter a valid email"
}
}
locales/fr.json (French content):
{
"general": {
"search": "Rechercher",
"cart": "Panier",
"menu": "Menu",
"close": "Fermer"
},
"product": {
"add_to_cart": "Ajouter au panier",
"sold_out": "Épuisé"
},
"cart": {
"title": "Votre panier",
"empty": "Votre panier est vide",
"checkout": "Commander"
}
}
locales/fr.schema.json (French schema):
{
"sections": {
"featured_products": {
"name": "Produits vedettes",
"settings": {
"heading": {
"label": "Titre"
},
"collection": {
"label": "Collection"
}
}
}
}
}
The | t filter automatically uses the correct translation based on the store's language:
{%- # Automatically shows "Search" in English, "Rechercher" in French -%}
<button>{{ 'general.search' | t }}</button>
{%- # Good -%}
{
"product": {
"add_to_cart": "Add to Cart"
}
}
{%- # Bad -%}
{
"prod": {
"btn1": "Add to Cart"
}
}
{
"general": { ... }, # General UI
"navigation": { ... }, # Navigation items
"product": { ... }, # Product-related
"cart": { ... }, # Cart-related
"forms": { ... } # Forms
}
en.default.json:
{
"product": {
"add_to_cart": "Add to Cart"
}
}
fr.json (same structure):
{
"product": {
"add_to_cart": "Ajouter au panier"
}
}
{%- # Good -%}
{
"forms": {
"contact": {
"name": "Name",
"email": "Email"
}
}
}
{%- # Less clear -%}
{
"forms": {
"contact_name": "Name",
"contact_email": "Email"
}
}
{
"cart": {
"item_count_one": "{{ count }} item",
"item_count_other": "{{ count }} items"
}
}
{% if cart.item_count == 1 %}
{{ 'cart.item_count_one' | t: count: cart.item_count }}
{% else %}
{{ 'cart.item_count_other' | t: count: cart.item_count }}
{% endif %}
{
"_comment": "{{ price }} will be replaced with the actual price",
"product": {
"from_price": "From {{ price }}"
}
}
{%- # Bad -%}
<h2>Featured Products</h2>
{%- # Good -%}
<h2>{{ 'sections.featured_products.heading' | t }}</h2>
{
"navigation": {
"home": "Home",
"shop": "Shop",
"collections": "Collections",
"about": "About",
"contact": "Contact"
}
}
{
"accessibility": {
"skip_to_content": "Skip to content",
"close_menu": "Close menu",
"open_menu": "Open menu",
"next_slide": "Next slide",
"previous_slide": "Previous slide"
}
}
{
"date": {
"months": {
"january": "January",
"february": "February"
},
"days": {
"monday": "Monday",
"tuesday": "Tuesday"
}
}
}
locales/en.default.json:
{
"general": {
"search": "Search",
"cart": "Cart",
"menu": "Menu"
},
"product": {
"add_to_cart": "Add to Cart",
"from_price": "From {{ price }}"
},
"cart": {
"title": "Your Cart",
"empty": "Your cart is empty"
}
}
sections/featured-products.liquid:
<section>
<h2>{{ 'sections.featured_products.heading' | t }}</h2>
{%- for product in collection.products -%}
<div>
<h3>{{ product.title }}</h3>
<p>{{ 'product.from_price' | t: price: product.price | money }}</p>
<button>{{ 'product.add_to_cart' | t }}</button>
</div>
{%- endfor -%}
</section>
Use translation keys consistently to create themes that work seamlessly in multiple languages.
npx skills add sarojpunde/Shopify i18n Basics下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer