Skip to content

Adding a new language

brows3r ships with English, Português (BR), Español, Français, Deutsch and 中文 (简体). Adding a new locale is a three-step pull request.

1. Copy the canonical locale file

The canonical bundle is src/i18n/locales/en.json. Copy it to src/i18n/locales/<code>.json where <code> follows the BCP-47 convention (e.g. it, ja, pt-PT). Translate every value — keys are the contract and must not change.

bash
cp src/i18n/locales/en.json src/i18n/locales/it.json
$EDITOR src/i18n/locales/it.json

If a key cannot be cleanly translated, leave the English value and add a TODO: comment in your PR description. Reviewers can pull native speakers in for those keys without blocking the rest.

2. Register the bundle

Edit src/i18n/index.ts:

ts
import it from "./locales/it.json";

// ...inside SUPPORTED_LANGUAGES
{ code: "it", label: "Italiano" },

// ...inside i18n.init resources
it: { translation: it },

The SUPPORTED_LANGUAGES array drives the language selector in Settings → General. The label is shown verbatim, so use the language's native name (Italiano, not Italian).

3. Verify and ship

bash
pnpm tsc --noEmit
pnpm vitest run
pnpm tauri dev

Open Settings → General, switch the dropdown to your new language, walk through the right-click menu, the keychain prompt, and the settings panel. Anything still in English is a missing translation — fix it in your locale file and commit.

Style notes

  • Keep keys human-readable and dotted (menu.file.download).
  • Don't translate technical terms (S3, bucket, URL, presigned) unless the local convention is overwhelming — in doubt, leave them in English.
  • Use the language's native punctuation (e.g. French uses « » for quotes, Spanish opens questions with ¿).
  • Use the locale's typographic ellipsis (), not three dots (...).

Tests and the locale fallback

Tests run with the detector's localStorage source set to en because the jsdom environment has no real navigator.language. If you add a component test that asserts on translated copy, prefer asserting on the key via a test-id rather than the rendered string — that way the test passes in every locale.

Released under the MIT License.