Skip to content

feat(i18n): use the OS language by default - #327

Open
hiro-nikaitou wants to merge 2 commits into
tonyantony300:mainfrom
hiro-nikaitou:fix/i18n-os-language-default
Open

hiro-nikaitou wants to merge 2 commits into
tonyantony300:mainfrom
hiro-nikaitou:fix/i18n-os-language-default

Conversation

@hiro-nikaitou

Copy link
Copy Markdown

Description

With no saved choice the UI language was hardcoded to English, so a first run on a German (or Portuguese, Japanese, …) system came up in English even though the translation ships. getStoredLanguage() now falls back to navigator.language, matched case-insensitively against the shipped locales: the full tag wins first (zh-TW stays Traditional), otherwise the two-letter language prefix is used (pt-PT → pt-BR, de-AT → de), and an unmatched language still ends on English.

A choice made in the language switcher keeps winning, and the detected language is not written to storage, so the app keeps following the system language until the user picks one explicitly.

Scope notes: only navigator.language (the top OS/browser preference, which is what WebView2 and Android WebView report from the system) is consulted — not the secondary navigator.languages list. nb/nn (Bokmål/Nynorsk) still falls back to English because only a no locale ships, and a zh-HK/zh-Hant tag resolves through zh to zh-CN. Happy to extend the mapping if you want those covered.

Verification

  • pnpm lint (biome lint: 350 files, no fixes applied + tsc --noEmit --skipLibCheck): exit 0
  • pnpm test:lib: # tests 151 / # pass 151 / # fail 0, exit 0 (same on the unpatched tree)
  • pnpm exec biome format frontend/src/i18n/setup.ts: No fixes applied, exit 0
  • Behavioural check on the real module: frontend/src/i18n/setup.ts was built through this repo's own vite.config.ts (SSR build) and imported once per case with a stubbed navigator/localStorage. After the patch 11/11 cases pass — de→de, pt-PT→pt-BR, zh-TW→zh-TW, zh→zh-CN, en-US→en, fr-FR→fr, ja→ja, JA→ja, nl-NL→en (not shipped), nb-NO→en, and a saved ja still winning over system de-DE. The identical script before the patch passes 4/11 (every case that should follow the system language resolved to en).

Not covered: I did not run the desktop/web/Android UI on a non-English system.

Checklist

  • PR title follows Conventional Commits (type(scope): description)
  • I have run pnpm lint before raising this PR
  • I have run pnpm format on the touched file (biome format, no Rust files touched)

Disclosure: this change was prepared with AI assistance.

Signed-off-by: hiro-nikaitou <vieteviete@proton.me>
@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 82c2e6c8-abc0-4d77-9fc6-dabf118bab79

📥 Commits

Reviewing files that changed from the base of the PR and between 4164ded and dcf5cfb.

📒 Files selected for processing (1)
  • frontend/src/i18n/setup.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

When no language is stored, getStoredLanguage matches the browser’s preferred language against the loaded locale keys. It falls back to English if neither the full language tag nor its two-character prefix matches. Errors during storage access or browser-language detection also result in English.

Changes

Locale Selection

Layer / File(s) Summary
Browser locale fallback
frontend/src/i18n/setup.ts
getStoredLanguage checks the browser language against loaded locale keys before falling back to English. It continues to browser-language detection if storage access fails.

Priority: ⬇️ Low

Change: Feature

Merge Risk: ⚪ Minimal · up to dcf5c

The language fallback is ready to merge after normal checks.

🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@CLAassistant

CLAassistant commented Sep 23, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 977009d1-9ca3-49ab-8dea-f5e3362e2698

📥 Commits

Reviewing files that changed from the base of the PR and between ccc1eb8 and 4164ded.

📒 Files selected for processing (1)
  • frontend/src/i18n/setup.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Comment thread frontend/src/i18n/setup.ts
Reading the saved language and reading `navigator.language` shared one
try/catch, so a storage denial returned the fallback before the browser
locale was ever consulted. Separate the two so storage only means "no
saved choice".

Signed-off-by: hiro-nikaitou <vieteviete@proton.me>
@hiro-nikaitou

Copy link
Copy Markdown
Author

Applied in dcf5cfb, following the suggestion: the storage read and the locale lookup no longer share one try/catch, so a storage denial leaves stored null and navigator.language is still consulted instead of returning 'en' early.

biome lint frontend/src/i18n/setup.ts is clean.

This branch has not been deployed

No deployments
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.

2 participants