docs/CONTRIBUTING_i18n.md
Thanks for helping localize Clash Verge Rev. This guide reflects the current architecture, where the React frontend and the Tauri backend keep their translation bundles separate. Follow the steps below to keep both sides in sync without stepping on each other.
src/locales/<lang>/; use src/locales/en/ as the canonical reference for keys and intent.pnpm i18n:format to align structure (frontend JSON + backend YAML) and pnpm i18n:types to refresh generated typings.crates/clash-verge-i18n/locales/<lang>.yml.pnpm dev (desktop shell) or pnpm web:dev (web only).Each locale folder mirrors the namespaces under src/locales/en/:
src/locales/
en/
connections.json
home.json
shared.json
...
index.ts
zh/
...
home.json → home.*). Keep keys scoped to the file they belong to.shared.json stores reusable vocabulary (buttons, validations, etc.); feature-specific wording should live in the relevant namespace.index.ts re-exports a resources object that aggregates the namespace JSON files. When adding or removing namespaces, mirror the pattern from src/locales/en/index.ts.src/services/i18n.ts. Only languages listed in supportedLanguages are fetched at runtime, so append new codes there when you add a locale.Because backend translations now live in their own directory, you no longer need to run pnpm prebuild just to sync locales—the frontend folder is the sole source of truth for web bundles.
pnpm i18n:format → node scripts/cleanup-unused-i18n.mjs --align --apply. It aligns key ordering, removes unused entries, and keeps all locales in lock-step with English across both JSON and YAML bundles.pnpm i18n:check performs a dry-run audit of frontend and backend keys. It scans TS/TSX usage plus Rust t!(...) calls in src-tauri/ and crates/ to spot missing or extra entries.pnpm i18n:types regenerates src/types/generated/i18n-keys.ts and src/types/generated/i18n-resources.ts, ensuring TypeScript catches invalid key usage.Native UI strings (tray menu, notifications, dialogs) use rust-i18n with YAML bundles stored in crates/clash-verge-i18n/locales/<lang>.yml. These files are completely independent from the frontend JSON modules.
en.yml semantically aligned with the Simplified Chinese baseline (zh.yml). Other locales may temporarily copy English if no translation is available yet.zh), so catching gaps early avoids mixed-language output.pnpm i18n:check / pnpm i18n:format tooling now validates backend YAML keys against Rust usage, so run it after backend i18n edits.clash-verge-i18n crate (crates/clash-verge-i18n/src/lib.rs). No additional build step is required after editing YAML files; tauri dev and tauri build pick them up automatically.src/locales/en/ into src/locales/<new-lang>/ and translate the JSON files while preserving key structure.index.ts to import every namespace. Matching the English file is the easiest way to avoid missing exports.supportedLanguages in src/services/i18n.ts.crates/clash-verge-i18n/<new-lang>.yml and translate the keys used in existing YAML files.pnpm i18n:format, pnpm i18n:types, and (optionally) pnpm i18n:check in dry-run mode to confirm structure.shared.json for common actions, statuses, and labels.systemProxy, updateInterval, autoRefresh) over positional ones (item1, dialogTitle2).{{placeholder}} and ensure components supply the required values.page, sections, forms, actions, tooltips, notifications, errors, tables, statuses, etc.).pnpm dev (or pnpm web:dev) and navigate through the affected views to confirm translations load and layouts behave.pnpm test if you touched code that consumes translations or adjusts formatting logic.