Skip to content

feat: i18n (English / 简体中文 / 繁體中文) with in-app language switcher#28

Merged
rrbe merged 2 commits into
mainfrom
feat/i18n
Jun 3, 2026
Merged

feat: i18n (English / 简体中文 / 繁體中文) with in-app language switcher#28
rrbe merged 2 commits into
mainfrom
feat/i18n

Conversation

@rrbe
Copy link
Copy Markdown
Owner

@rrbe rrbe commented Jun 3, 2026

What

Adds full internationalization across all three UI layers, plus an in-extension language switcher in the settings page. Languages: English, Simplified Chinese (zh_CN), Traditional Chinese (zh_TW).

  • Manifestname / description / toolbar tooltip via __MSG_*__ + default_locale: en.
  • Settings page — every label, hint, feature name/description, search UI, and dynamic token/save messages.
  • Content scripts — Releases tab, approve dialog, commit tag tooltips, branch-name copy, review-status badges/popover, pin/unpin, watch/fork/star popups, diff-stats, collapse/expand buttons.

Why a custom resolver instead of chrome.i18n

chrome.i18n.getMessage is locked to the browser UI locale and can't be overridden at runtime. To support a manual picker, t() resolves against bundled catalogs + a preference stored in chrome.storage.local:

  • Picker options: Follow browser / English / 简体中文 / 繁體中文.
  • Follow browser maps the UI locale to a catalog: zh-TW/HK/MO or Hantzh_TW; other zh*zh_CN; else en — satisfies the TODO "默认语言根据系统语言".
  • Choice persists in chrome.storage.local; settings page re-localizes in place; content scripts pick it up on the next navigation.
  • Traditional Chinese uses Taiwan vocabulary (設定 / 檔案 / 儲存庫 / 核准 / 權杖 …), not naive character conversion.

Notes

  • Catalogs live in src/_locales so esbuild bundles them and tsc accepts them (resolveJsonModule); build.mjs copies them to dist/_locales for the manifest's __MSG__ resolution.
  • The chrome://extensions name/description still follow the browser locale (manifest __MSG__ is resolved by Chrome, not overridable in-app).

Verification

  • pnpm typecheck clean
  • pnpm test — 188/188 (added src/lib/i18n.test.ts: en/zh_CN/zh_TW switching, placeholder substitution, DOM localization)
  • pnpm build — bundles all catalogs; dist/_locales/{en,zh_CN,zh_TW} present
  • 98 message keys × 3 locales, full parity, zero missing/unused

🤖 Generated with Claude Code

rrbe and others added 2 commits June 3, 2026 15:20
Internationalize all three UI layers — manifest (name/description), the
settings page, and content-script injected UI (buttons, popovers, tooltips) —
with English and Simplified Chinese catalogs under _locales.

Because chrome.i18n is locked to the browser UI locale, t() resolves against
bundled catalogs and a stored preference instead, enabling an in-extension
language picker (Follow browser / English / 简体中文) in the settings page.
The choice persists in chrome.storage.local; content scripts pick it up on the
next navigation. "Follow browser" maps the UI locale to a catalog (zh* → zh_CN,
else en), satisfying the "default by system language" TODO.

- src/lib/i18n.ts: bundled catalogs, t()/localizePage()/initLocale()/setLocale()
- src/_locales/{en,zh_CN}/messages.json: 98 keys, full parity
- build.mjs copies src/_locales → dist/_locales for manifest __MSG__ resolution
- tsconfig: resolveJsonModule for the bundled JSON imports
- src/lib/i18n.test.ts: covers locale switching, placeholder substitution, DOM localization

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a third catalog with Taiwan vocabulary (設定/檔案/儲存庫/核准/權杖…), a
"繁體中文" entry in the language picker, and Traditional-vs-Simplified
auto-detection (zh-TW/HK/MO or Hant → zh_TW, other zh → zh_CN).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rrbe rrbe changed the title feat: i18n (English + 简体中文) with in-app language switcher feat: i18n (English / 简体中文 / 繁體中文) with in-app language switcher Jun 3, 2026
@rrbe rrbe merged commit 618d7b0 into main Jun 3, 2026
1 check passed
@rrbe rrbe deleted the feat/i18n branch June 3, 2026 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant