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 the admin fixes in about a minute. Everything below is about telling those two apart quickly.
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:
| Part | What it points at |
|---|---|
en | The locale being rendered. The file is locales/en.default.json for the default language, or locales/en.json for a non default one. |
cart | The top level group inside that JSON file. |
general | A nested group inside cart. |
title | The 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:
| File | Holds | Where 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:
| Question | Cause A: key missing everywhere | Cause 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 an empty field or the English text showing through. |
| 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. |
Type the wording into the admin and save. |
| Time it takes | Five minutes, and you need to be comfortable editing JSON. | One minute, no code. |
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 fix it in the Shopify admin (cause B)?
Shopify's own steps, which have not changed in a while:
- From your Shopify admin, go to Online Store.
- Click the menu beside the theme that you want to edit.
- Select Edit default theme content from the dropdown menu.
- Click the tab or category that includes the text you want to change, or use the Filter items search bar to locate the phrase.
- Edit the text.
- Click Save.
Two things to know. 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. And the categories are per language, so if the problem only appears on your French storefront, switch the editor to French before you start typing or you will overwrite the English.
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. A flat entry named
"gift_cards.issued.title"at the top level of the file does not resolve. Shopify walks the structure, it does not match the literal string. - 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
tfilter 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 placeholder renders empty rather than erroring.
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 it say "[object Object]" instead of "Translation missing"?
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. Some renderers then serialize that object and you get the literal characters [object Object] printed in your header where the word "Cart" belongs.
We hit this exactly once, on 4 May 2026, in a generated header. 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, because it is the one variant of this bug that the word "translation" will never help you search for. 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.
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:
| Rule | Severity | What it finds |
|---|---|---|
TranslationKeyExists | Error | References to translations that don't exist |
ValidSchemaTranslations | Error | Translation keys in schema tags with no matching entry in the default schema locale file |
MatchingTranslations | Warning | Missing or additional translations in locale files |
ValidHTMLTranslation | Warning | Invalid HTML inside translations |
The two error level rules are the ones that matter. 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.
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
- Read the key. The text after the colon is the address the theme looked up.
- Search for its last segment in Edit default theme content.
- A row exists means a language gap. Type the wording in and save.
- No row exists means the key was never defined. Add it to
locales/en.default.json, nested to match the dots. - If it prints
[object Object]instead, your key stops one level short of the text. Add the final segment. - The
defaultfilter will not rescue it. The missing message is a non empty string. - Run
shopify theme checkbefore uploading.TranslationKeyExistsis an error level rule and catches this in seconds.
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?
From your Shopify admin go to Online Store, 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 language 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. Note also that the edit 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 theme show [object Object] instead of a word?
Because the key you asked for exists but points at a group of entries rather than at a piece of text. If the cart group contains title, empty and item_count, then asking for 'cart' resolves to the whole group and gets serialized to the literal characters [object Object]. The fix is to use the full dotted path down to the text, so 'cart.title' rather than 'cart'. We saw this exactly once, in a generated header on 4 May 2026. It is the one variant of this bug that searching for the word translation will never help you find.
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 a warning 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. 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 freeNo 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.