6.9 KiB
6.9 KiB
CONTRIBUTING — i18n
Thank you for contributing to Clash Verge Rev localization! This guide reflects the current project layout and tooling so you can land translation improvements smoothly.
Quick workflow
- Focus fixes on the language folders inside
src/locales/<lang>/and usesrc/locales/en/as the baseline for key shape and intent. - Keep pull requests small and open draft PRs early if you would like feedback.
- Run
pnpm format:i18nto align JSON structure andpnpm i18n:typesto refresh generated typings before pushing. - Preview changes with
pnpm dev(desktop shell) orpnpm web:dev(web only) to verify context and layout. - Report missing context, untranslated UI strings, or script bugs via issues so we can track them.
Locale layout
Every language lives in its own directory:
src/locales/
en/
connections.json
home.json
…
shared.json
tests.json
index.ts
zh/
…
- Each JSON file maps to a namespace (
home→home.*,shared→shared.*, etc.). Keep keys scoped to their file. shared.jsonstores reusable copy (buttons, labels, validation messages). Feature-specific content remains in the relevant namespace file (profiles.json,settings.json, …).index.tsre-exports aresourcesobject that aggregates the namespace JSON. When adding files, mirror the pattern used insrc/locales/en/index.ts.- Do not edit
src-tauri/resources/locales; those files are copied fromsrc/localesduring packaging bypnpm prebuild. - Rust/Tauri uses a separate set of YAML bundles in
src-tauri/locales/for system tray text and native notifications. Update those when backend-facing strings change.
Locale maintenance script
The repository ships with scripts/cleanup-unused-i18n.mjs, a TypeScript-aware analyzer that:
- Scans
src/andsrc-tauri/fort("...")usage (including dynamic prefixes) to determine which keys are referenced. - Compares locales to the baseline (
en) to list missing or extra keys. - Optionally removes unused keys and aligns key ordering/structure.
- Emits optional JSON reports for CI or manual review.
Typical commands
# Dry-run audit (recommended before opening a PR)
pnpm node scripts/cleanup-unused-i18n.mjs
# Apply removals and align to the baseline structure (same as pnpm format:i18n)
pnpm node scripts/cleanup-unused-i18n.mjs --apply --align
# Generate a machine-readable report
pnpm node scripts/cleanup-unused-i18n.mjs --report ./i18n-report.json
Aliases and flags:
pnpm format:i18n→node scripts/cleanup-unused-i18n.mjs --align --applypnpm node scripts/cleanup-unused-i18n.mjs -- --helpshows all options (--baseline,--src,--keep-extra,--no-backup,--report,--apply,--align, …).
Before submitting translations
- Run the script in dry-run mode to inspect missing/unused keys.
- Apply alignment if you added or removed keys so diffs stay minimal.
- Review
.bakbackups (generated when--applyruns) to ensure important strings were not removed; delete the backups once confirmed. - For dynamic keys, add explicit references in code or update the script whitelist so the analyzer recognizes them.
Typings & runtime integration
pnpm i18n:typesregeneratessrc/types/generated/i18n-keys.tsandsrc/types/generated/i18n-resources.ts. Run it whenever keys change so TypeScript enforces valid usages.- Supported runtime languages are defined in
src/services/i18n.ts. Update thesupportedLanguagesarray when you add an additional locale. - The app defaults to Chinese (
zh) and lazily loads other bundles. If a bundle fails to load, it falls back tozh. - Packing (
pnpm build,pnpm prebuild) copiessrc/localesintosrc-tauri/resources/localesso keep the source tree authoritative. - Backend (Tauri) strings such as tray menu labels and native notifications use the YAML bundles under
src-tauri/locales/<lang>.ymlviarust-i18n. Keep the English file (en.yml) aligned with the Simplified Chinese semantics and mirror updates across the remaining languages (繁體zhtwtranslates the Chinese copy; other locales can temporarily duplicate English until translators step in). - When adding a new language to the backend, create a matching
<lang>.ymlinsrc-tauri/locales/, populate the keys used in the existing files, and ensuresrc/services/i18n.tsincludes the language code so the frontend can request it.
Adding a new language
- Duplicate
src/locales/en/intosrc/locales/<new-lang>/(match the folder name to the language code you intend to serve, e.g.pt-br). - Translate the JSON files while preserving the key hierarchy.
shared.jsonshould stay aligned with the baseline. - Update the new locale’s
index.tsto import every JSON namespace (use the English file as reference). - Append the language code to
supportedLanguagesinsrc/services/i18n.ts. Adjustcrowdin.ymlif the locale code needs a mapping. - Run
pnpm format:i18n,pnpm i18n:types, and optionallypnpm node scripts/cleanup-unused-i18n.mjs(dry-run) to verify structure. - Execute
pnpm devto confirm UI translations load, andpnpm prebuildif you want to double-check Tauri resource syncing.
Authoring guidelines
- Reuse shared vocabulary: before creating a new label, check
shared.json(actions,labels,statuses,placeholders,validation,window,editorModes, etc.). Only introduce feature-specific copy when it is unique to that area. - Keep keys semantic: use camelCase leaves that describe intent (
systemProxy,updateInterval,autoRefresh). Avoid positional keys likeitem1ordialogTitle2. - Organize by UI responsibility inside each namespace. Common buckets include:
page,sections,forms,fields,actions,tooltips,notifications,errors,dialogs,tables,components,statuses.
- Document dynamic placeholders: continue using the
{{placeholder}}syntax and ensure code comments/context explain required parameters. - Example structure (from
src/locales/en/home.json):
{
"page": {
"title": "Home",
"tooltips": {
"settings": "Home Settings"
}
},
"components": {
"proxyTun": {
"status": {
"systemProxyEnabled": "System Proxy Enabled"
}
}
}
}
Testing & QA
- Launch the desktop shell with
pnpm dev(orpnpm web:devfor browser-only checks) to confirm strings display correctly and spacing still works in the UI. - Run
pnpm testif you touched code that relies on translations or formatting logic. - Note uncovered scenarios or language-specific concerns (pluralization, truncated text) in your PR description.
Feedback & support
- Open an issue for tooling problems, missing context, or translation bugs so we can track them.
- For localization contributions (translations, fixes, context notes, etc.), submit a PR with screenshots when layout changes might be impacted.
- If you need a second pair of eyes, leave a comment on your PR and the team will follow up.