All posts
11 min read

Why does my Shopify store say "Translation missing"?

Translation missing means your theme asked for a piece of text by key and no locale file in the theme holds an entry at that key, so Shopify prints the key path in place of the words. The text after the colon is the address it looked up, not an error code, and reading it tells you exactly which file to open.

There are two causes and they need different fixes, which is why the usual advice ("go and edit it in the admin") works for some people and does nothing at all for others. Either the key is missing from every locale file in the theme, which only a code edit can solve, or the key exists in the default language and is missing from a second language you added, which is a translation job rather than a code one. Everything below is about telling those two apart quickly.

What exactly does Shopify print for each locale mistake?

We tested this on a live Shopify store on 11 October 2026 rather than trusting older write ups, because two of the answers were not what this page used to say. We pushed a small unpublished theme with Shopify CLI 3.93.1, rendered each expression on the storefront, then deleted the theme. Every row below is the literal output:

What the theme doesWhat the shopper sees
Asks for a key that exists: {{ 'cart.general.title' | t }}Your cart
Asks for a key that is not in the fileTranslation missing: en.cart.general.subtitle
Asks for a key in a group the file does not have at allTranslation missing: en.gift_cards.issued.title
Asks for a group instead of a text entry: {{ 'cart' | t }}The whole group dumped as Ruby style text, for example {"general"=>{"title"=>"Your cart"}, "greet"=>...}
Adds | default: 'Fallback' after a missing keyTranslation missing: en.cart.general.subtitle (the fallback never shows)
Passes the wrong variable name: | t: nme: 'Ada' for a value of Hello {{ name }}I18n Error: Missing interpolation value "name" for "Hello {{ name }}"
Asks for a key whose value is an empty string ""Nothing at all, no message
Locale file contains a key with a dot in its name, such as "flat.key"The push fails for that file: Key 'flat.key' contains invalid characters

Three things follow from that table. The missing message always starts with the locale code and is an ordinary string (45 characters long for en.cart.general.subtitle, which is why no filter treats it as empty). A wrong variable name is louder than a missing key, not quieter. And a group reference never says "translation" at all, so searching for that word will not find it.

What does "Translation missing: en.cart.general.title" actually mean?

Read it as an address. Shopify locale files are nested JSON, and the dots are the levels of nesting. A string like en.cart.general.title breaks into four parts:

PartWhat it points at
enThe locale being rendered. The file is locales/en.default.json for the default language, or locales/en.json for a non default one.
cartThe top level group inside that JSON file.
generalA nested group inside cart.
titleThe actual entry whose value is the words a shopper reads.

The theme requested it with the t filter, which looks like {{ 'cart.general.title' | t }} in Liquid. Shopify resolves that against the locale file for the active language. If it finds nothing, it does not fail the page, throw an error, or leave a blank. It prints the key so a developer can see what broke, which is a sensible choice for a developer and a confusing one for a shopper looking at your cart.

Shopify separates these files by purpose, and the distinction matters when you go looking:

FileHoldsWhere a failure shows
locales/en.default.json Storefront text: buttons, labels, cart wording, form messages On the live storefront, as "Translation missing"
locales/fr.json, locales/de.json and so on The same storefront text for each extra language you publish Only when a shopper is viewing that language
locales/en.default.schema.json Theme editor labels: section names, setting names, help text Inside the theme editor sidebar, never on the storefront

Shopify allows exactly one default file of each type, named with the *.default.json pattern, and the rest follow standard IETF language tags where the lowercase code is the language and an optional uppercase code is the region, so en-GB.json and fr-CA.json are both valid. If your missing key only appears inside the theme editor and never on the storefront, you are looking at the schema file, not the storefront one.

Which of the two causes do I have?

Open your Shopify admin, go to Online Store, click the menu beside the theme, and select Edit default theme content. Then use the Filter items search bar and paste in the last part of the key, for example title from cart.general.title.

That single check splits the two causes, because the language editor is built from the theme's own locale files. It can only show you rows that exist:

QuestionCause A: key missing everywhereCause B: key missing in one language
What you see in Edit default theme content No row for it at all. Searching finds nothing. The row is there with your default wording. The gap is only in the other language.
Who broke it Whoever wrote the Liquid. The theme references a key that was never defined. Nobody. A language was added after the theme was written.
Which shoppers see it Everyone, in every language. Only shoppers browsing in that one language.
The fix Add the key to locales/en.default.json in the code editor. Add the wording for that language in the Translate & Adapt app, or in that language's locale file.
Time it takes Five minutes, and you need to be comfortable editing JSON. A few minutes, no code if you use the app.

One more possibility worth ruling out before you edit anything: the wording might be coming from an app rather than the theme. Apps that inject storefront text through an app embed carry their own translations, and a missing string there is fixed in the app's settings, not in your locale file. If the key path starts with a group name you do not recognise and cannot find in locales/en.default.json, check which apps render on that page first.

How do I change the wording in the Shopify admin?

Shopify's own steps for the default language:

  1. From your Shopify admin, go to Online Store.
  2. Click the menu beside the theme that you want to edit.
  3. Select Edit default theme content from the dropdown menu.
  4. Click the tab or category that includes the text you want to change, or use the Filter items search bar to locate the phrase.
  5. Edit the text.
  6. Click Save.

Two things to know. First, this edits the theme you selected, so if you fix it and then switch themes or upload a fresh copy of the same theme, the edit does not travel with you. Second, it covers your default language only: Shopify's help centre says the theme content editor changes the wording "for your default language". For a second language (cause B), Shopify points you to the Translate & Adapt app, a CSV import, or a compatible translation app instead. We could not test what a second language shows for a missing key, because our test store publishes one language, so if you see the message only in one language, start with that language's file or the app rather than the English one.

How do I fix it in the theme code (cause A)?

Go to Online Store, Themes, Edit code, and open locales/en.default.json. Then add the key path exactly as the error prints it, minus the leading locale code. For a key printed as Translation missing: en.gift_cards.issued.title you need:

{
  "gift_cards": {
    "issued": {
      "title": "Gift card",
      "subtext": "Here's your gift card!"
    }
  }
}

Three rules that catch people out here:

  • The nesting must match the dots. Do not write a flat entry named "gift_cards.issued.title" at the top level of the file. Shopify walks the structure, and in our 11 October test it refused to upload a locale file containing a dotted key at all, with the error Key 'flat.key' contains invalid characters.
  • The file must stay valid JSON. A trailing comma after the last entry in a group breaks the whole file, and the symptom is that every key in the theme starts failing at once, not just the one you edited. If the page went from one missing string to dozens after your edit, that is what happened.
  • Variables in the value use double braces. Shopify's t filter takes named parameters, so a value of "Use this code at checkout to redeem your {{ value }} gift card" pairs with a Liquid call of {{ 'gift_cards.issued.redeem' | t: value: gift_card.initial_value | money }}. Get the parameter name wrong and the whole string is replaced by an error that shoppers can read, for example I18n Error: Missing interpolation value "name" for "Hello {{ name }}". The fix is to make the name in the Liquid call match the name inside the braces exactly.

If the theme came from the Shopify Theme Store, note the edit somewhere, because a theme update replaces the file and takes your addition with it.

Why does my store show {"title"=>...} or [object Object] instead of a word?

Because the key you asked for exists, but it points at a group rather than at a piece of text. In a file where cart contains title, empty and item_count, a Liquid call of {{ 'cart' | t }} resolves to the whole group. On a real Shopify storefront, as our 11 October test showed, the group is printed as Ruby style text with => arrows, such as {"title"=>"Your cart"}, right where the word "Cart" belongs. A JavaScript preview tool rendering the same theme prints [object Object] instead, which is how we first met it, on 4 May 2026, in a generated header shown in our own preview.

The fix is always the same: use the full dotted path down to the text itself, so {{ 'cart.title' | t }} rather than {{ 'cart' | t }}. It is worth checking for deliberately, for two reasons. The word "translation" never appears, so searching for it will not help. And shopify theme check does not flag it: in our test it reported every missing key but said nothing about 'cart' or 'cart.general', because those keys do exist. Our locale base file currently has 6 top level groups and 10 group paths that hold other groups rather than text, so there are 10 keys in a theme of ours that would produce this if a section asked for them directly.

Will the default filter hide it?

No, and this is the most common wasted fix. Writing {{ 'cart.general.title' | t | default: 'Cart' }} looks like a safety net and does nothing, because default only substitutes when the value is empty, false or nil. "Translation missing: en.cart.general.title" is a perfectly good non empty string as far as Liquid is concerned, so it passes straight through the filter and onto the page. We confirmed it on a live store on 11 October 2026: the fallback text never appeared, and piping the same missing key into size returned 45, the length of the message.

If you want a label to show nothing on purpose, give the key an empty value ("") in the locale file. That renders as nothing, with no message, and keeps the key available for a translator later.

If you genuinely want a fallback rather than a fix, the honest version is to drop the filter and write the literal text, which is what we do for every section name and setting label in our own themes: 297 schema labels, all literal English, zero translation keys. That is a deliberate trade. It means those labels cannot be translated for a merchant working in another language, and in exchange the theme editor can never show a raw key where a setting name should be.

Does theme check catch this before it reaches a shopper?

Yes, and it is worth running before you upload anything, because this is one of the few Shopify faults that is completely invisible until a real page renders. Shopify's theme check ships four rules that cover locale files:

RuleSeverityWhat it finds
TranslationKeyExistsErrorReferences to translations that don't exist
ValidSchemaTranslationsErrorTranslation keys in schema tags with no matching entry in the default schema locale file
MatchingTranslationsErrorMissing or additional translations in locale files
ValidHTMLTranslationWarningInvalid HTML inside translations

Three of the four are error level in Shopify's default configuration. TranslationKeyExists is cause A caught at build time, and ValidSchemaTranslations is the theme editor equivalent. MatchingTranslations is the one that finds cause B, because it compares your language files against each other and reports the entries one of them is missing. Run it with shopify theme check from the theme folder.

Here is what it reported on our 11 October test theme, which had several deliberate mistakes in its Liquid and a French file missing five entries. The messages are worth knowing word for word, because they are what you will paste into a search bar:

MistakeRuleMessage
Key not in the default fileTranslationKeyExists'cart.general.subtitle' does not have a matching entry in 'locales/en.default.json'
Key in the default file but not in FrenchMatchingTranslationsThe translation for 'cart.greet' is missing
Key pointing at a group, such as 'cart'noneNo offense reported
Wrong variable name in a t callnoneNo offense reported

So a clean theme check run is necessary but not sufficient. The last two rows only show up when a real page renders.

What we found auditing our own themes

We build Shopify themes with AI, which means every | t call in a generated section is written by a model and every locale entry has to be generated alongside it. That is an obvious place for this bug to breed, so on 14 September 2026 we parsed it rather than assuming.

Across 33 generated themes in our build archive we scanned 1,218 Liquid files containing 1,254 calls to the t filter. Unresolvable keys: zero. Keys pointing at a group instead of a string: zero. Our hand written boilerplate on its own accounts for 51 Liquid files, 57 t calls and 25 distinct keys against a locale base of 36 entries, and all 25 resolve.

That is the current state and not the historical one. On 2 July 2026 the gift card page of every theme we shipped rendered "Translation missing" five times over, because gift_card.liquid called gift_cards.issued.title, .subtext, .redeem, .expires_on and .shop_link, and the locale base file had no gift_cards group at all. Five keys, one page, and nobody had seen it because the gift card page only renders when a gift card is actually issued. The fix was adding the five entries. The reason it does not recur is that the generation prompt now carries a rule that every {{ 'foo.bar' | t }} call must have a matching key path in the theme's locale data, with an explicit instruction to use a literal string instead when in doubt.

The broader lesson holds for hand built themes too. This bug survives every check that does not actually render the page, which is why it tends to be found by a customer rather than by you.

The short version

  1. Read the key. The text after the colon is the address the theme looked up.
  2. Search for its last segment in Edit default theme content.
  3. A row exists means a language gap. Fill it in for that language in Translate & Adapt or that language's file.
  4. No row exists means the key was never defined. Add it to locales/en.default.json, nested to match the dots, never as one dotted key.
  5. If it prints {"title"=>...} (or [object Object] in a preview tool), your key stops one level short of the text. Add the final segment.
  6. If it prints I18n Error: Missing interpolation value, the variable name in the Liquid call does not match the one in braces.
  7. The default filter will not rescue it. The missing message is a non empty string.
  8. Run shopify theme check before uploading. TranslationKeyExists is an error level rule and catches missing keys in seconds, but not group references or wrong variable names.

This sits in the same family as the other Shopify faults that produce no error message anywhere: a section that never appears in the Add section list, which is a missing presets array, and an empty Apps tab in the block picker, which is a missing @app declaration. If a locale edit stops the theme uploading altogether, the cause is usually a JSON or schema error in the ZIP rather than the translation itself. Every theme in our free theme gallery ships a complete locale file, and each one has a live preview you can open before installing anything.

Frequently asked questions

Why does my Shopify store say "Translation missing"?

Because the theme asked for a piece of text by key and no locale file in the theme has an entry at that key, so Shopify prints the key path instead of the words. The text after the colon is the address it looked up. There are two causes. Either the key is missing from every locale file, which happens when the theme's Liquid references a key that was never defined and needs a code edit, or the key exists in your default language but not in a second language you added, which you fix in the admin under Edit default theme content in about a minute.

How do I fix "Translation missing" on Shopify without editing code?

For your default language, go to Online Store in your Shopify admin, click the menu beside the theme, and select Edit default theme content. Use the Filter items search bar to find the phrase, edit the text, and click Save. This only works when a row for that key already exists, because the editor is built from the theme's own locale files. If searching finds no row at all, the key was never defined in the theme and the admin cannot fix it. Shopify says this editor changes wording for your default language only; for a second language use the Translate & Adapt app, a CSV import, or a compatible translation app. The edit also belongs to that one theme and does not travel with you if you switch themes or re-upload.

What does "Translation missing: en.cart.general.title" mean?

Read it as a path. The en is the locale being rendered, so the file is locales/en.default.json. The cart is a top level group in that JSON file, general is a group nested inside it, and title is the entry that should hold the actual words. The theme requested it with a Liquid call of 'cart.general.title' piped through the t filter. Shopify found no entry at that address, so rather than failing the page or leaving a blank it printed the address. Open locales/en.default.json in the code editor and check whether that nesting exists.

Why does my Shopify store show text like {"title"=>"Your cart"} or [object Object] instead of a word?

Because the key the theme asked for exists but points at a group of entries rather than at a piece of text. Asking for 'cart' when the cart group holds title, empty and item_count returns the whole group. On a live Shopify storefront we tested on 11 October 2026, that group is printed as Ruby style text with => arrows; a JavaScript preview tool prints [object Object] instead. The fix is to use the full dotted path down to the text, so 'cart.title' rather than 'cart'. shopify theme check does not flag this, because the key exists.

What does "I18n Error: Missing interpolation value" mean on Shopify?

A translation contains a variable in double braces, such as Hello {{ name }}, and the Liquid call that uses it passed a different variable name or none at all. In our 11 October 2026 test, calling that key with nme instead of name replaced the whole string on the storefront with I18n Error: Missing interpolation value "name" for "Hello {{ name }}". Make the parameter name in the t filter call match the name inside the braces exactly. shopify theme check did not report this mistake.

Why does Shopify say a locale key contains invalid characters?

Because a key in a locale file has a dot in its name, for example "flat.key": "Flat value". Dots are how Shopify separates nesting levels, so they are not allowed inside a single key. In our 11 October 2026 test, shopify theme push rejected en.default.json with Key 'flat.key' contains invalid characters. Rewrite it as nested groups, so a key printed as cart.general.title becomes a cart group holding a general group holding title.

Can I use the default filter to hide a Translation missing error?

No. Piping the t filter into default with a fallback label looks like a safety net and does nothing, because the default filter only substitutes when a value is empty, false or nil. The string Translation missing: en.cart.general.title is a perfectly good non empty string as far as Liquid is concerned, so it passes straight through onto the page. If you want a fallback rather than a fix, drop the t filter and write the literal text. The trade is that the text can no longer be translated for another language.

Does shopify theme check catch missing translations?

Yes. Four rules cover locale files. TranslationKeyExists is error severity and identifies references to translations that don't exist, which is the storefront case. ValidSchemaTranslations is also error severity and identifies translation keys in schema tags that don't have a matching entry in the default schema locale file, which is the theme editor case. MatchingTranslations is also error severity in Shopify's default configuration and identifies missing or additional translations in locale files, which is how you find a gap in a second language. ValidHTMLTranslation is a warning covering invalid HTML inside translations. In our 11 October 2026 test, theme check did not catch a key that points at a group or a wrong variable name, so a clean run is not proof the storefront is clean. Run shopify theme check from the theme folder before you upload.

Where are Shopify locale files and what is the difference between en.default.json and en.default.schema.json?

Both live in the locales folder of the theme, reachable through Online Store, Themes, Edit code. The storefront file en.default.json holds the text shoppers read: button labels, cart wording, form messages. The schema file en.default.schema.json holds theme editor labels: section names, setting names and help text. A failure in the first appears on your live storefront as Translation missing. A failure in the second appears only inside the theme editor sidebar and is never seen by a shopper. Shopify permits one default file of each type, and additional languages follow standard IETF tags such as fr-CA.json or de.json.

Does a missing translation break my Shopify store or hurt SEO?

It does not break anything functionally. The page renders, the cart works, and checkout is unaffected, because Shopify substitutes the key path rather than failing. The damage is trust and, where the missing string sits in a title tag or a heading, search appearance. A product or cart page whose heading reads Translation missing: en.cart.general.title is indexable with that text in place of a real heading. Treat it as urgent cosmetics rather than an outage: fix it the same day, but do not roll back a theme over it.

Generate a theme that looks like your brand

A complete Shopify 2.0 theme with conversion features built in, ready in minutes. No credit card required.

Generate my theme free

No Shopify store yet? Start one here, then bring the theme. Themr may earn a commission if you start a paid plan; it does not change what you pay.