.translations.json Reference
.translations.json lives at the root of any repo that uses your-last-translation-tool. It declares one or more translation projects in the repo, each with its own locales directory and source language.
Minimal example
Section titled “Minimal example”Copy this into your repo root to get started:
{ "projects": [ { "name": "web", "localesDir": "apps/web/locales", "sourceLanguage": "en" } ]}Top-level fields
Section titled “Top-level fields”| Field | Required | Type | Description |
|---|---|---|---|
$schema | no | string | Optional advisory schema URL. Validation is by Zod, not the JSON Schema. |
projects | yes | Project[] (≥ 1) | Every translation project the repo ships. |
Unknown top-level fields are ignored (forward compatibility).
Project fields
Section titled “Project fields”| Field | Required | Default | Notes |
|---|---|---|---|
name | yes | — | Human label, unique within the file. Shown in the UI. |
localesDir | yes | — | Path relative to the repo root (e.g. apps/web/locales). |
sourceLanguage | yes | — | The language used by developers in code (e.g. en). |
fileStructure | no | {lang}/{namespace}.json | MVP supports only this value. |
format.type | no | json | Serialization format. Only json is supported in MVP. |
format.nested | no | false | If true, keys nest into objects. If false, flat with keySeparator. |
format.keySeparator | no | . | Separator for flat keys (matches i18next default). |
plurals.enabled | no | true | Toggle plural awareness in the editor. |
plurals.suffixes | no | i18next CLDR (see below) | The set of plural suffixes the editor recognizes. |
validation.placeholders | no | ["{{name}}", "{name}"] | Placeholder formats checked for round-trip presence. |
validation.allowHtml | no | true | If false, target translations with HTML tags are flagged. |
branchPrefix | no | translations/ | Prefix for new translation branches created by the app. |
languageNames | no | {} | Human labels per language code (e.g. "uk": "Українська"). |
Unknown per-project fields are ignored.
Language autodetection
Section titled “Language autodetection”You do not declare languages in .translations.json. The app scans <localesDir>/* and treats every subfolder matching the BCP 47 pattern as a language:
apps/web/locales/ en/ ← detected uk/ ← detected pt-BR/ ← detected _archive/ ← ignored (doesn't match pattern) README.md ← ignored (not a directory)To add a new language, create the folder. No config change needed.
Default plural suffixes
Section titled “Default plural suffixes”The defaults match i18next 23.14.0 CLDR conventions:
["_zero", "_one", "_two", "_few", "_many", "_other"]Override with plurals.suffixes if your codebase uses different conventions.
Multi-project example
Section titled “Multi-project example”{ "$schema": "https://stape.io/schemas/translations-v1.json", "projects": [ { "name": "web", "localesDir": "apps/web/locales", "sourceLanguage": "en", "branchPrefix": "translations/web/" }, { "name": "marketing-site", "localesDir": "apps/marketing/i18n", "sourceLanguage": "en", "languageNames": { "uk": "Українська", "pt-BR": "Português (Brasil)" } } ]}Validation
Section titled “Validation”The schema is enforced with Zod on app load. Field-level errors surface with JSON-pointer paths (e.g. projects[0].localesDir) so you can jump straight to the offending key. Unknown fields pass through silently.
Bootstrap wizard
Section titled “Bootstrap wizard”If you open a repo without .translations.json, the in-app wizard collects the required fields and writes the file to your working tree. It does not run git add, git commit, or git push — those happen through the PR flow.