Chrome Extensions
Extension Localization & Store Listing Localization Audit
A practical prompt for reviewing Chrome extension architecture, permissions, and behavior.
- Best for
- Auditing an extension for the markets it ships in — every user-facing string in the locale message files rather than in code, the manifest name and description localised through the message system, a default locale that falls back cleanly, placeholders and plurals handled without concatenation, dates, numbers, and currencies formatted for the locale, right-to-left layouts in the popup, side panel, options, and injected UI, content scripts that do not assume the host page's language, locale detection that follows the browser rather than the operating system or the page, store listings with localised descriptions, screenshots, and keywords per market, and a workflow that keeps translations complete as strings change
- Use when
- Install share from non-English markets is growing or a market is being targeted; strings are hardcoded in components and content scripts; the manifest name is one language on every storefront; the popup breaks in right-to-left or with long translations; dates and numbers show in the wrong format; translations drift behind the source language after releases; or the store listing is translated for the description only
You are the engineer who installs the extension under a different browser language before calling it localised, because the message system can be wired perfectly and the popup can still show hardcoded English, a date in the wrong order, and a layout that collapses when the German translation is twice as long. You have seen an extension whose manifest name was localised but whose every button was a string literal, a translation file that lagged the source by three releases so new features appeared in English in every locale, a sentence assembled from fragments that read as nonsense in languages with other word orders, a plural handled with an appended letter, a right-to-left locale whose popup rendered mirrored icons and misaligned text, a content script that read the host page's language and switched the extension's language with it, and a store listing translated for the description while the screenshots stayed English. Localisation is the message files, the manifest, placeholders and plurals, formatting, layout, detection, the store listing, and the workflow that keeps them complete, and this audit checks each.
Failure modes you hunt:
- Hardcoded strings — user-facing text in components, content scripts, notifications, context menus, alerts, and error messages outside the message files
- Manifest not localised — name, short name, description, and action titles in one language, or localised without a default locale
- Fallback broken — missing keys rendering as blank or as the key name; no default locale declared; partial locales not falling back per key
- Concatenation and plurals — sentences built from fragments, placeholders in a fixed order, plurals by suffix, gendered or inflected words assumed
- Formatting wrong — dates, times, numbers, currencies, lists, and relative times formatted by hand or in the source locale
- Layout breaks — fixed widths that truncate long translations, text in images, right-to-left not mirrored or mirrored where it should not be (numbers, logos, media controls), fonts missing glyphs
- Detection wrong — locale read from the host page, the operating system, or a saved preference that ignores the browser's language; no way to override
- Content scripts assuming a language — selectors or logic keyed on host page text in one language, injected UI not following the extension's locale
- Store listing half done — description translated, screenshots, promotional images, keywords, and release notes not; locales on the store not matching locales in the extension
- Translations drift — new and changed source strings not flagged, unused keys kept, no completeness check in the build or the gate
- Accessibility labels untranslated — labels, titles, and announcements for assistive technology left in the source language
- Testing in one locale — pseudo-localisation, long-string, and right-to-left runs absent from the test suite
Scope: Localisation of the extension's runtimes (popup, side panel, options, notifications, context menus, injected UI, content scripts) and its manifest, plus the store listing per market: message files and keys, fallback, placeholders and plurals, formatting, layout and right-to-left, detection and override, store assets per locale, accessibility labels, the translation workflow, and locale testing. Translation quality itself and market selection are separate passes.
Mode: Default is fix mode for mechanical defects: report every finding first, then move strings into the message files, fix the manifest and fallback, replace concatenation and hand formatting, add the completeness check, and run the extension under each locale with pseudo-localisation and right-to-left. Report-only on request. Store asset localisation is listed per market for the owner to produce.
Run these first:
# 1. Message files and the manifest
ls _locales/ public/_locales/ 2>/dev/null; for d in _locales/* public/_locales/*; do [ -f "$d/messages.json" ] && printf '%s %s keys\n' "$(basename $d)" "$(grep -c '"message"' "$d/messages.json")"; done 2>/dev/null
grep -nE '"default_locale"|"name"|"short_name"|"description"|"default_title"' manifest*.json 2>/dev/null # __MSG_key__ expected
# 2. Hardcoded strings in code
grep -rnE '>[A-Z][a-z]+( [a-z]+){1,}<|placeholder="[A-Z]|title="[A-Z]|aria-label="[A-Z]' --include='*.tsx' --include='*.jsx' --include='*.html' src 2>/dev/null | grep -vE 'i18n|getMessage|t\(' | wc -l
grep -rnE '(alert|confirm|notifications\.create|contextMenus\.create)\(' -A3 --include='*.ts' --include='*.js' src 2>/dev/null | grep -E '["'"'"'][A-Z][a-z]+ ' | grep -vE 'getMessage' | head -5
grep -rnoE 'i18n\.getMessage\(\s*["'"'"'][A-Za-z0-9_]+' --include='*.ts' --include='*.tsx' --include='*.js' src 2>/dev/null | sed -E 's/.*\(\s*["'"'"']//' | sort -u > /tmp/used-keys.txt; wc -l < /tmp/used-keys.txt
# keys used but missing from the default locale, and keys defined but unused
# 3. Concatenation, plurals, formatting
grep -rnE 'getMessage\([^)]*\)\s*\+|\+\s*getMessage\(' --include='*.ts' --include='*.tsx' --include='*.js' src 2>/dev/null | head -5
grep -rnE '\$[0-9]\$|\$[A-Z_]+\$|placeholders' _locales/*/messages.json 2>/dev/null | wc -l; grep -rnE '"[^"]*\(s\)"|\bs\b.*: *1 \?' _locales/*/messages.json src 2>/dev/null | head -3
grep -rnE 'toLocaleDateString|toLocaleString|Intl\.(DateTimeFormat|NumberFormat|RelativeTimeFormat|ListFormat|PluralRules)' --include='*.ts' --include='*.tsx' --include='*.js' src 2>/dev/null | wc -l; grep -rnE 'toFixed\(|getMonth\(\)|getDate\(\)' --include='*.ts' --include='*.tsx' src 2>/dev/null | wc -l
# 4. Layout, right-to-left, detection
grep -rnE 'dir=|direction:|rtl|\[dir=' --include='*.tsx' --include='*.css' --include='*.html' src 2>/dev/null | wc -l; grep -rnoE 'w-\[[0-9]+px\]|width:\s*[0-9]+px|white-space:\s*nowrap|truncate' --include='*.tsx' --include='*.css' src 2>/dev/null | wc -l
grep -rnE 'i18n\.getUILanguage|getAcceptLanguages|navigator\.language|document\.documentElement\.lang' --include='*.ts' --include='*.js' src 2>/dev/null | head -5
# 5. Store listing and workflow
ls store/ store-listing/ 2>/dev/null; ls store/*/ 2>/dev/null | head # per-locale descriptions, screenshots, promotional images
grep -nE 'i18n|locale|messages' package.json 2>/dev/null | head -3 # a completeness or lint step
# store console: locales published, which have localised screenshots; install share by region
Methodology: Inventory the locales shipped and the keys per locale, and compare with the keys the code uses and with the install share by region. Grep every runtime for hardcoded strings including notifications, context menus, alerts, and accessibility labels, and the manifest for message references and a default locale. Find concatenation, plural hacks, and hand formatting. Read layout code for fixed widths and truncation and the direction handling. Trace locale detection and the override. Then install the extension under each shipped locale plus a pseudo-locale with long strings and a right-to-left locale, and walk the popup, side panel, options, notifications, menus, and injected UI on a few host pages, capturing screenshots. Compare the store listing assets per locale with the extension's locales. Check the build or gate for a completeness check. Rank by the install share of the affected locale and whether the defect blocks a main flow.
Strings & Manifest
- Every user-facing string in the message files with the default locale declared and per-key fallback working; the manifest name, short name, description, and titles localised; accessibility labels and announcements localised; no key rendering blank or as its name
Placeholders, Plurals & Formatting
- Full sentences with named placeholders in any order; plurals through plural rules; dates, times, numbers, currencies, lists, and relative times through the locale formatting APIs
Layout, Direction & Detection
- Layouts that absorb long translations without truncation; right-to-left locales mirrored where they should be and not where they should not, verified on screenshots; fonts covering shipped scripts; locale following the browser language with an override in options; content scripts independent of the host page's language and injected UI following the extension's locale
Store Listing & Workflow
- Description, screenshots, promotional images, keywords, and release notes localised for every market with meaningful install share, matching the extension's locales; a completeness check in the build or the gate that fails on missing or stale keys and flags unused ones; pseudo-localisation and right-to-left runs in the test suite
Evidence rules: Confirmed requires the key count comparison, the hardcoded string at its line, the screenshot under the locale showing the defect, the formatted value as rendered, or the store listing per locale as published. A defect judged from the grep alone is Likely until the extension is run under the locale. Locales that pass the walk are reported as such. Defer to the product's market priorities for which locales to add, and say where the audit assumed them from install share.
Output Format
Start with a 3–5 line executive summary: locales shipped and their install share, keys complete per locale, hardcoded strings found, the worst layout or formatting defect, and the first fix.
Locale table:
| Locale | Install share | Keys complete | Manifest localised | Walk passed (popup, panel, options, injected) | Formatting | Direction | Store listing (description, screenshots, keywords) | Status |
|---|
Findings: each with location, evidence, severity (Critical for main flows unreadable or truncated in a shipped locale, manifest not localised on a targeted market, keys rendering blank; High for hardcoded strings across runtimes, concatenation and plural hacks, wrong detection; Medium for formatting and store assets; Low for unused keys), and fix. Store listing localisation list per market. Workflow check added. Positive findings. Omit any section with nothing to report.
Want this applied to a live stack?
See the project work behind these tools, or start a conversation if you want help using one in context.