LocalePack
ChromeFirefoxEdgeOperaSafariCWS Listing
Vue.jsReact
Next.jsi18nextReact Native
Guides
Home/Guides/Store listing vs in-extension i18n
February 21, 2026

Store listing localization vs in-extension i18n (Chrome + AMO pitfalls)

Every browser extension has two public-facing layers of text: the store listing (what users see before they install) and the in-extension strings (what users see after they install). These are localised through completely different systems. Confusing the two is one of the most common extension i18n mistakes — and it leads to partial translations, broken store pages, and missed international users.

The two layers, explained

Here is the split in plain terms:

In-extension strings
Source: _locales/*/messages.json
Examples: Popup text, toolbar badge label, options page strings, content script UI, notification bodies
API: chrome.i18n.getMessage() / browser.i18n.getMessage()
Store listing
Source: Chrome Developer Dashboard / AMO developer hub / App Store Connect
Examples: Extension name on store page, store description, screenshots, promotional text, category tags
API: Manual entry in each platform's developer console
Translating messages.json does not translate your store listing. Translating your store listing does not translate what users see inside the extension. They are completely independent.

The __MSG_ bridge in Chrome

There is one exception to the separation: Chrome allows __MSG_key__ tokens in manifest.json fields. When Chrome reads your manifest, it substitutes these tokens with the matching key from the active locale’s messages.json:

// manifest.json
{
  "manifest_version": 3,
  "name": "__MSG_appName__",
  "description": "__MSG_appDescription__",
  "default_locale": "en",
  "version": "1.0.0"
}

// _locales/en/messages.json
{
  "appName": {
    "message": "Tab Manager Pro",
    "description": "Extension name displayed in Chrome toolbar and Web Store."
  },
  "appDescription": {
    "message": "Manage, search, and organize your browser tabs effortlessly.",
    "description": "Short description shown on the Chrome Web Store listing."
  }
}

// _locales/de/messages.json
{
  "appName": {
    "message": "Tab Manager Pro",
    "description": "Extension name displayed in Chrome toolbar and Web Store."
  },
  "appDescription": {
    "message": "Verwalten, suchen und organisieren Sie Ihre Browser-Tabs mühelos.",
    "description": "Short description shown on the Chrome Web Store listing."
  }
}

With this setup, Chrome pulls the extension name and description from messages.json and displays the correct locale in both:

  • The Chrome toolbar (extension name, tooltip)
  • The Chrome Web Store listing page (if no separate listing localisation is uploaded)
Chrome Web Store shows __MSG_appDescription__ as the listing description only if you have not entered a separate description in the Chrome Developer Dashboard for that locale. If you upload a per-locale listing in the dashboard, that dashboard text takes priority over the manifest substitution.

Chrome Web Store listing localisation

The Chrome Developer Dashboard has a dedicated “Store Listing” tab where you can enter per-locale marketing text that is independent of your extension code:

What's controlled by the dashboard

  • Detailed description — the long store page description (up to 16,000 characters)
  • Screenshots — per-locale screenshots with localised UI
  • Promotional tiles — small, large, and marquee promotional images
  • Category & tags — store categorisation

What's controlled by __MSG_ (or entered directly)

  • Extension name — from __MSG_appName__ in manifest, or a fixed string
  • Short description — from __MSG_appDescription__ in manifest, or a fixed string (max 132 characters)

The recommended approach: use __MSG_appName__ and __MSG_appDescription__ in your manifest so that the name and short description are automatically localised from messages.json. Then enter the detailed description in each locale separately in the dashboard. This minimises duplication while ensuring both layers are localised.

AMO (Firefox) listing localisation

AMO (addons.mozilla.org) works differently from Chrome in a few important ways:

AMO displays __MSG_ substitutions automatically

Like Chrome, Firefox resolves __MSG_appName__ and __MSG_appDescription__ from your messages.json files. AMO shows the resolved name and description for the visitor’s locale on the add-on listing page.

AMO has a separate 'Describe' section

In the AMO developer hub, under “Manage Listing,” there is a per-locale “Describe” section where you can enter a longer summary, release notes, and other marketing copy. This text appears on the public listing and is not read from messages.json.

AMO does NOT sync listing text from _locales

A common misconception: developers assume that translating messages.json will automatically update their AMO listing description. It does not. The add-on name and short description use __MSG_ substitution, but the detailed listing text must be entered separately in the AMO developer hub for each locale you want to support.
AMO reviewers see your extension in their own locale setting. If your messages.json translations are incomplete or placeholder-mangled, the reviewer sees broken text. This can lead to review delays or rejection comments. Complete, accurate translations improve your chances of a smooth AMO review.

Side-by-side: Chrome vs AMO vs Safari

AspectChromeFirefox (AMO)Safari
Name / short desc source__MSG_ from messages.json__MSG_ from messages.json__MSG_ (in-extension only)
Detailed description sourceDeveloper DashboardAMO developer hubApp Store Connect
Screenshots sourceDeveloper DashboardAMO developer hubApp Store Connect
Store desc auto-syncs from _locales?No (name/desc only via __MSG_)No (name/desc only via __MSG_)No
Locale code format (store)en, de, ja, zh_CNen-US, de, ja, zh-CNen-US, de-DE, ja, zh-Hans
Listing preview before publishYes (Developer Dashboard)Yes (AMO dev hub)Yes (App Store Connect)

Why both layers matter for international reach

Store listing localisation and in-extension localisation serve different stages of the user journey:

1

Discovery (store listing)

A developer or user searching the Chrome Web Store or AMO in German sees your extension name, description, and screenshots. If these are in English only, the listing ranks lower in local search results and the user is less likely to click.

2

Decision (store listing)

The user reads the detailed description and reviews screenshots. Localised marketing copy and screenshots showing a native-language UI dramatically increase install rates in non-English markets.

3

Usage (in-extension strings)

After install, the user interacts with the extension popup, options page, and content script UI. messages.json translations determine this experience. If the listing was localised but the extension itself is English-only, users feel misled.

4

Retention (both)

An extension with consistent localisation — store listing and in-extension UI both in the user's language — builds trust and reduces uninstalls. The user never encounters a jarring language switch.

The __MSG_ pattern: what it covers and what it doesn’t

Here is the exact scope of __MSG_key__ substitution in manifest fields:

Manifest field__MSG_ substitution?Notes
name✓ YesExtension name in toolbar and store listing
short_name✓ YesShorter name for space-constrained UI
description✓ YesShort store description (max 132 chars on Chrome)
action.default_title✓ YesToolbar button tooltip text
version✗ NoMust be a literal version string
permissions✗ NoArray of permission strings, not localisable
content_scripts✗ NoMatch patterns and script paths are not localisable
background.service_worker✗ NoScript path, not localisable

In practice, most developers use __MSG_ for just two fields: name and description. These are the only two manifest fields that appear in the store listing.

Common pitfalls

Translating messages.json and assuming the store listing is done

The most common mistake. messages.json translations only affect what getMessage() returns at runtime, plus the name / description fields in manifest.json (via __MSG_). The detailed store description, screenshots, and promotional text must be entered separately in each store’s developer console.

Hardcoding name/description in manifest.json instead of using __MSG_

If your manifest has "name": "Tab Manager Pro" (a literal string), Chrome and Firefox will always show that English string regardless of locale — even though you have a perfectly good translation in _locales/de/messages.json. Use "name": "__MSG_appName__" to enable automatic locale switching.

Only localising the store listing, not in-extension strings

Some developers translate their Chrome Web Store description into multiple languages but leave the extension UI in English only. The user installs based on a localised listing, then opens the popup to find English-only text. This mismatch damages trust and increases uninstall rates.

Forgetting AMO listing text is separate from _locales

On AMO, the add-on name and short description come from __MSG_ substitution automatically. But the detailed “About this add-on” text is entered in the AMO developer hub’s “Describe” section. Many developers localise messages.json and expect AMO to pull the full description from it — it does not.

Using __MSG_ in fields where it's not supported

__MSG_ substitution only works in name, description, and short_name in the manifest. Placing it in action.default_title is also supported, but fields like permissions, content_scripts, or version do not support substitution.

Safari: App Store Connect is entirely separate

Safari Web Extensions ship via the App Store. __MSG_ substitution still works inside Safari for the toolbar and extension UI, but the App Store listing (app name, subtitle, description, keywords, screenshots) is managed entirely in App Store Connect. See the Safari localization article for details.

Recommended workflow

To localise both layers efficiently:

1

Set up __MSG_ in manifest.json

Use __MSG_appName__ and __MSG_appDescription__. This lets both the in-extension UI and the basic store listing draw from the same localised source.

2

Translate messages.json into your target locales

Upload your source messages.json to LocalePack, choose your target languages, and download the _locales ZIP. This handles all in-extension strings including appName and appDescription.

3

Enter detailed store listing copy per locale

In the Chrome Developer Dashboard, AMO developer hub, or App Store Connect, enter the longer marketing description for each locale you want to support. This text is independent of messages.json.

4

Upload localised screenshots

Take screenshots of your extension UI in each locale (the in-extension strings are already localised from step 2). Upload these per-locale screenshots in each store's developer console.

Quick reference: which text comes from where?

Text the user seesSource
Extension name in browser toolbar__MSG_appName__ → messages.json "appName"
Extension name on store page__MSG_appName__ (or dashboard override)
Short description on store page__MSG_appDescription__ (or dashboard override)
Detailed store page descriptionEntered manually in store's developer console
Store screenshotsUploaded per-locale in store's developer console
Popup text / options page labelschrome.i18n.getMessage() → messages.json
Content script UI stringschrome.i18n.getMessage() → messages.json
Toolbar button tooltip__MSG_ or action.default_title → messages.json

Localise your in-extension strings in minutes

LocalePack handles the messages.json side — including appName, appDescription, and all your in-extension strings with placeholder-safe translations. Upload, choose your target languages, pay once, and download a ready _locales ZIP. Then enter your store listing copy in each platform’s developer console to complete both layers.

Translate extension strings →Translate store listing →
← Back to Guides
LocalePack
GuidesPrivacyTermsSupport

© 2025 LocalePack. All rights reserved.

This project was translated with LocalePack logoLocalePack