feat(i18n): localize the extension UI in 18 languages (V2-537)#8
Open
Nic-dorman wants to merge 6 commits into
Open
feat(i18n): localize the extension UI in 18 languages (V2-537)#8Nic-dorman wants to merge 6 commits into
Nic-dorman wants to merge 6 commits into
Conversation
Add multi-language support to ant-webex. The extension was previously
English-only with every string hardcoded in the popup/onboarding HTML and TS.
Approach: Hybrid — a hand-rolled runtime dictionary (no framework; the
extension stays dependency-free) for all in-UI strings, plus native
`_locales`/`__MSG__` for the one thing a runtime dictionary can't localize:
the store-listing description (Chrome Web Store / Firefox AMO). The product
name "Autonomi" stays untranslated.
- src/i18n/index.ts: t() with {name} interpolation + _one/_many plurals,
locale resolution (chrome.storage override -> navigator.language -> en),
normalizeLocale / NATIVE_LOCALE_NAMES / RTL_LOCALES ported from ant-ui.
- 18 runtime catalogs (en source of truth; 17 machine-translated baselines
flagged _translator_notes for native-speaker review). Shared UI atoms are
copied verbatim from the ant-ui desktop app so the two read identically.
- Popup + onboarding marked with data-i18n*; dynamic strings routed through
t()/tc(). Per-OS terminal copy moved from constants.ts into the catalog.
- Language picker in popup Settings (System default + all 18 in native script).
- Content script: bundled string subset (follows browser UI language),
regenerated from the locale files on every build.
- RTL: <html dir="rtl"> for ar/he + logical CSS properties.
- build.mjs copies both string stores into dist/ and dist-firefox/.
- CONTRIBUTING-i18n.md for translators.
Verified: typecheck clean; build:all (Chrome + Firefox) green; structural
validation 18/18 (key parity, placeholders, atoms); web-ext lint on the
Firefox dist has 0 errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
readdirSync order is unspecified and differs across filesystems (macOS vs Linux/CI), which could make the generated content-locales.json vary between machines and trip the reproducible-build check. Sort for a stable key order. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nic-dorman
added a commit
that referenced
this pull request
Jul 21, 2026
…source (V2-688) (#10) On a `v*` tag push (or manual workflow_dispatch), build from a clean checkout and produce the distributable artifacts, then attach them to the GitHub Release: - ant-webex-chrome-vX.Y.Z.zip — CWS upload package (manifest at zip root). - ant-webex-firefox-vX.Y.Z.xpi — signed, unlisted via `web-ext sign` when the AMO API secrets (WEB_EXT_API_KEY/SECRET) are set; installable by testers. Falls back to an unsigned .zip (with a warning) when creds are absent, so the rest of the release still succeeds. - ant-webex-source-vX.Y.Z.zip — `git archive` source tree for AMO's source-code submission requirement. Guards: version must agree across tag / manifest.json / package.json; web-ext lint runs before signing so a broken build doesn't burn an AMO version number. Runs in a `release` GitHub Environment so signing can be gated behind a required reviewer and secrets aren't exposed to fork-PR runs. RELEASING.md documents the tag flow + one-time AMO credential setup. Branched off main; independent of the i18n (#8) and CI-hardening (#9) PRs. Co-authored-by: Nic <nic@nics-mbp.home> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The onboarding page's <title> stayed hardcoded "Welcome to Autonomi" in every locale — the in-body heading was localized (onboarding.welcome_title) but the browser tab title was not. Mark it data-i18n so applyStaticTranslations() fills it from the active catalog. Reuses the existing key: no new strings, key parity preserved across all 18 locales. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…English normalizeLocale mapped any tag we don't ship verbatim to English. For the two languages we ship only regionally — Chinese (zh-CN/zh-TW) and Portuguese (pt-BR) — that silently dropped common real-world tags to English: pt-PT, zh-HK, and the script subtags zh-Hant/zh-Hans (which some systems send). Add a regional fallback: pt* → pt-BR; zh* → zh-TW when the tag carries a Traditional script (Hant) or region (TW/HK/MO), else zh-CN. Exact matches and base-language folding (fr-CA → fr) are unchanged. Adds index.test.ts covering the resolution table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Settings language <select> added for i18n had no style rule, so it rendered as a white native control against the dark popup. Theme it like the text inputs (dark fill, slate border), strip the native appearance, and add an inline-SVG caret plus dark <option> colours. (On macOS the opened menu is drawn natively and ignores option colours — platform limitation.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The downloads list filtered by `byExtensionId === chrome.runtime.id`, which is unreliable: it's undefined on Firefox, and if chrome.runtime.id ever reads falsy the `=== id` test inverts and lets every unowned browser download through — so the box showed the user's entire download history. Filter instead to the download ids the background already records for autonomi:// content (STORAGE_KEYS.DOWNLOADS, address → id) — authoritative and browser-agnostic. Side-effect: the antd installer download no longer shows in the box (it has its own progress panel during setup); the box is now purely autonomi:// content. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds multi-language support to
ant-webex. Previously the extension was English-only, with every user-facing string hardcoded in the popup/onboarding HTML and TS. Now the UI localizes into 18 languages, with a user-selectable language picker and RTL support.Closes V2-537.
Approach — Hybrid (runtime dictionary + native
_locales)The extension is dependency-free, so this is a ~130-line hand-rolled runtime, not a framework:
src/i18n/index.ts+src/i18n/locales/<lang>.json) powers all in-UI strings —t()with{name}interpolation,_one/_manyplurals, and fallback (active locale → English → key)._locales/__MSG__localizes the one thing a runtime dictionary can't: the store-listing description (Chrome Web Store / Firefox AMO), read from the manifest before any JS runs. The product name "Autonomi" stays untranslated.chrome.storage.local— independent of the browser UI language.Languages
en(source) +ja ko nl fr bg es ar he ru uk zh-CN zh-TW pt-BR tr vi id de.The 17 non-English locales ship as machine-translated baselines, each flagged with
_translator_notesfor native-speaker polish (seeCONTRIBUTING-i18n.md). Shared UI atoms (Download, Save, Settings, Connected, Downloads, …) are copied verbatim from the siblingant-uidesktop app so the two products read identically.RTL
Arabic + Hebrew ship with
<html dir="rtl">wiring and the popup's physicalmargin-left/rightconverted to logical properties. (One decorative progress-shimmer keyframe is a noted minor follow-up.)Notable
constants.tsinto the catalog (it's user-facing prose).web_accessible_resources. Content-script labels follow the browser UI language.CONTRIBUTING-i18n.md.Verification
npm run typecheck— cleannpm run build:all— Chrome + Firefox dists builden.json, all{placeholder}tokens preserved, shared atoms verbatim, native descriptions presentweb-ext linton the Firefox dist: 0 errors (confirms__MSG__/_localesresolve). The 2 Chrome-dist lint errors are pre-existing (verified identical on basev0.1.2; web-ext is a Firefox tool flagging the intentionalservice_worker) and unrelated to this change.For reviewers / testers
dist/(Chrome) ordist-firefox/(Firefox) as an unpacked extension._translator_notesare open for polish — seeCONTRIBUTING-i18n.md.🤖 Generated with Claude Code