You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: add-a-new-language.md
+51-93Lines changed: 51 additions & 93 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,103 +2,78 @@
2
2
3
3
This guide is divided into two main parts:
4
4
5
-
1.**[Adding a New Language](#adding-a-new-language)**: Instructions for introducing a new locale across the backend and frontend.
5
+
1.**[Adding a New Language](#adding-a-new-language)**: Instructions for introducing a new locale using the automated Google Sheets workflow.
6
6
2.**[Switching or Using Supported Languages](#switching-or-using-supported-languages)** : Guidance for configuring or switching between languages that are already supported.
7
7
8
8
## Adding a New Language
9
9
10
-
This section shows how to introduce a new locale end-to-end across the backend and the frontend. It includes what files to add, the expected templates, which configs to update, and how to verify everything.
10
+
Compass uses an automated translation workflow based on Google Sheets. This allows non-technical users to add translations from a familiar spreadsheet, while developers simply run an import script to automatically apply them to the codebase.
11
11
12
-
Locale identifiers follow [IETF BCP 47](https://www.ietf.org/rfc/bcp/bcp47.txt) (e.g., `en-GB`, `es-AR`). Keep language in lowercase and region in uppercase. Keep codes consistent across config and folders.
12
+
Locale identifiers must follow [IETF BCP 47](https://www.ietf.org/rfc/bcp/bcp47.txt) (e.g., `en-GB`, `es-AR`, `fr-FR`). Keep language codes in lowercase and region codes in uppercase.
13
13
14
-
Notes
14
+
### 1. For Translators (Non-Technical)
15
15
16
-
* Use BCP‑47 language tags (e.g., `en-GB`, `en-US`, `es-ES`, `es-AR`). Keep codes consistent across config and folders.
17
-
* Backend uses locale directories under `backend/app/i18n/locales/<locale>/` with domain JSON files (e.g., `messages.json`).
18
-
* Frontend-new uses `frontend-new/src/i18n/locales/<locale>/translation.json` and maps them in [`frontend-new/src/i18n/i18n.ts`](frontend-new/src/i18n/i18n.ts).
19
-
* Supported languages are enabled via environment variables on both backend and frontend.
16
+
1.**Open the Compass Translation Sheet:** Access the shared Google Sheet provided by the development team.
17
+
2.**Add a New Language Column:** Find the first empty column header after the existing language codes. Type the BCP-47 language code for your new language (e.g., `fr-FR` for French) and press Enter.
18
+
> **Note:** Do NOT modify the `Platform` or `Key` columns, as these are strict technical identifiers required for the application to function and **must only be edited by developers or other authorised maintainers**.
19
+
3.**Fill in the Translations:** Scroll through the rows. Use the English (`en-GB` or `en-US`) columns as a reference. Type your translated text into your new column. If you leave a cell blank, the application will automatically fall back to English for that specific text.
20
+
4.**Notify the Team:** Once translations are complete, notify the development team to run the import script.
20
21
21
-
### Prerequisites
22
+
### 2. For Developers (Technical)
22
23
23
-
* Decide the language code(s) you want to support (e.g., `es-AR`).
24
-
* Pick a reference language to copy from (English is recommended):
Once translations or new keys have been added to the Google Sheet, follow these steps to pull them into the codebase.
27
25
28
-
### 1. Backend
29
-
30
-
The backend uses `LocaleProvider` to determine the current locale. The default locale in `BACKEND_LANGUAGE_CONFIG` configuration is used as the default.
31
-
32
-
#### 1.1 Create Locale directory and messages file
33
-
34
-
* Create a folder for your new locale under `backend/app/i18n/locales/<locale>/` and add a `messages.json` file with the same keys as English.
35
-
* Translate backend-facing strings in `backend/app/i18n/locales/<locale>/messages.json`. Use [`en-US/messages.json`](backend/app/i18n/locales/en-US/messages.json) as the reference.
36
-
* Key consistency is enforced by [`backend/app/i18n/test_i18n.py`](backend/app/i18n/test_i18n.py).
backend/app/i18n/locales/es-AR/messages.json # new
42
-
```
43
-
For the message structure and keys, please refer to the reference file: [`backend/app/i18n/locales/en-US/messages.json`](backend/app/i18n/locales/en-US/messages.json).
26
+
> **Supported platforms**
27
+
>
28
+
> Currently, only three platforms are powered by this workflow:
29
+
> -**Frontend** (React app)
30
+
> -**Backend** (Python services)
31
+
> -**Feedback** (survey/questions content)
32
+
>
33
+
> Only rows/keys that belong to one of these platforms will be generated. If a *new* platform is ever introduced, the import script must be extended to support it before any keys for that platform will have an effect.
44
34
45
-
#### 1.2 Update Supported Constants and Environment Variables
35
+
#### 2.1 Run the Import Script
46
36
47
-
- Add the locale to [`backend/app/i18n/types.py`](backend/app/i18n/types.py) (`Locale` enum and `SUPPORTED_LOCALES`).
48
-
- Update [`backend/app/i18n/constants.py`](backend/app/i18n/constants.py) only if the default fallback changes.
49
-
- Enable the new locale in your backend environment via `BACKEND_LANGUAGE_CONFIG`.
50
-
51
-
#### 1.3 Verify Backend Key Consistency
52
-
53
-
`I18nManager` can verify that all locales contain the same keys per domain; [`backend/app/i18n/test_i18n.py`](backend/app/i18n/test_i18n.py) enforces key parity.
54
-
55
-
Optional commands
37
+
Navigate to the `backend` directory and run the automated import script:
56
38
57
39
```bash
58
40
cd backend
59
-
poetry run python scripts/verify_i18n_keys.py --verify
60
-
```
61
-
62
-
### 2. Frontend
63
-
64
-
The frontend uses `i18next` with resources defined in locale files and mapped in [`frontend-new/src/i18n/i18n.ts`](frontend-new/src/i18n/i18n.ts).
65
-
66
-
#### 2.1 Create the locale folder and translation file
67
-
68
-
Create a folder for your new locale under `frontend-new/src/locales/<locale>/` and copy the reference `translation.json` from English (`en-GB`). Translate values, keeping all keys identical.
69
-
70
-
Example
41
+
poetry run python scripts/import_translations_from_sheets.py
frontend-new/src/i18n/locales/es-AR/translation.json # new
74
-
```
75
-
76
-
For the translation structure and keys, please refer to the reference file: [`frontend-new/src/i18n/locales/en-GB/translation.json`](frontend-new/src/i18n/locales/en-GB/translation.json).
77
-
78
-
***Add other locale files:**
79
-
- Add `frontend-new/src/feedback/overallFeedback/feedbackForm/questions-<locale>.json` mirroring the existing files, e.g., [`questions-en-GB.json`](frontend-new/src/feedback/overallFeedback/feedbackForm/questions-en-GB.json).
80
-
- Add `frontend-new/public/data/config/fields-<locale>.yaml`; keep the same structure/keys as [`fields-en-GB.yaml`](frontend-new/public/data/config/fields-en-GB.yaml).
81
43
82
-
#### 2.2 Register Locale Resources
44
+
**What this script does:**
45
+
* Connects to the Google Sheet and downloads the translation matrices.
46
+
* Generates or updates the corresponding JSON files in `frontend-new/src/i18n/locales/`, `backend/app/i18n/locales/`, and `frontend-new/src/feedback/overallFeedback/feedbackForm/`.
47
+
* Ensures that **new translation keys** defined in the sheet are created for the supported platforms, and keeps existing keys in sync.
48
+
***Auto-registers the new locale:** It automatically patches the codebase to recognize the new language by modifying:
49
+
*`config/default.json` (Adds locale to `supportedLocales` and injects English fallbacks into `sensitiveData`)
50
+
*`backend/app/i18n/types.py` (Locale enum and `SUPPORTED_LOCALES`)
*`frontend-new/src/i18n/i18n.ts` (Import statements and internal resource mapping)
83
53
84
-
* Update [`frontend-new/src/i18n/constants.ts`](frontend-new/src/i18n/constants.ts) (add to `Locale`, `LocalesLabels`, `SupportedLocales`, and adjust `FALL_BACK_LOCALE` only if the fallback changes).
85
-
* Import and register the translation and feedback JSON files in [`frontend-new/src/i18n/i18n.ts`](frontend-new/src/i18n/i18n.ts).
54
+
> **When to re-run the script**
55
+
>
56
+
> Any time the shared translation sheet is updated (new language, updated strings, or new keys), a developer must:
> 2. Commit the regenerated locale files and configuration changes.
59
+
> 3. Deploy the updated services so the changes are visible in all environments.
86
60
87
-
#### 2.3 Environment Config
61
+
#### 2.2 Manual Steps Required
88
62
89
-
Enable the new locale via environment variables:
90
-
*`FRONTEND_SUPPORTED_LOCALES`: a JSON array of enabled locale codes (see [`parseEnvSupportedLocales.ts`](frontend-new/src/i18n/languageContextMenu/parseEnvSupportedLocales.ts) for validation rules).
91
-
*`FRONTEND_DEFAULT_LOCALE`: default language if user preference not set.
63
+
While the script handles JSON translations and locale registration, one manual step remains:
92
64
93
-
Environment variables are Base64-encoded and read from [`frontend-new/public/data/env.example.js`](frontend-new/public/data/env.example.js).
65
+
1.**Embeddings:** Generate taxonomy embeddings for the new language using the appropriate model ID (see [Generate Embeddings](./deployment-procedure.md#step-43-generate-embeddings)).
94
66
95
-
#### 2.4 Verify Frontend Key Consistency
67
+
#### 2.3 Verify Key Consistency
96
68
97
-
There is an automated test that ensures all locales share the same keys as English (`en-GB`): [`frontend-new/src/i18n/locales/locales.test.ts`](frontend-new/src/i18n/locales/locales.test.ts).
98
-
99
-
Optional commands
69
+
You can optionally run the automated tests to ensure exact key consistency across platforms:
100
70
101
71
```bash
72
+
# Backend verification
73
+
cd backend
74
+
poetry run python scripts/verify_i18n_keys.py --verify
75
+
76
+
# Frontend verification
102
77
cd frontend-new
103
78
yarn test -- src/i18n/locales/locales.test.ts
104
79
```
@@ -107,30 +82,13 @@ yarn test -- src/i18n/locales/locales.test.ts
107
82
108
83
Supported languages are enabled via environment variables on both backend and frontend.
109
84
110
-
***Add environment variables for the frontend** ([see deployment procedure](./deployment-procedure.md) and [upload to secret manager](./deployment-procedure.md):
85
+
***Add environment variables for the frontend** ([see deployment procedure](./deployment-procedure.md) and [upload to secret manager](./deployment-procedure.md)):
111
86
-`FRONTEND_SUPPORTED_LOCALES`: JSON string array of supported locales, e.g., `["en-GB","es-ES"]`.
***Add environment variables for the backend** ([see deployment procedure](./deployment-procedure.md) and [upload to secret manager](./deployment-procedure.md)):
*[ ] Create `backend/app/i18n/locales/<locale>/messages.json` with the same keys as English
121
-
*[ ] Add language configurations to `BACKEND_LANGUAGE_CONFIG`
122
-
*[ ] Add the locale to `backend/app/i18n/types.py` (`Locale` enum and `SUPPORTED_LOCALES`)
123
-
*[ ] Generate embeddings for the new language using the new taxonomy model ID \([Generate Embeddings](./deployment-procedure.md#step-43-generate-embeddings)\)
124
-
*[ ] (Optional) Run backend i18n verify script
125
-
126
-
***Frontend-new**
127
-
*[ ] Create `frontend-new/src/i18n/locales/<locale>/translation.json` with the same keys as English (`en-GB`)
128
-
*[ ] Import and register resources in `frontend-new/src/i18n/i18n.ts`
*[ ] Update `env` config: `FRONTEND_SUPPORTED_LOCALES` and `FRONTEND_DEFAULT_LOCALE`
133
-
*[ ] (Optional) Run the locales consistency test
134
92
135
93
## Switching or Using Supported Languages
136
94
@@ -144,12 +102,12 @@ This section explains how to enable or switch between languages that are already
144
102
### 1. Backend
145
103
146
104
***Language Config:**`BACKEND_LANGUAGE_CONFIG` determines the default backend language and other configurations.
147
-
***Supported languages:** Listed in the `SUPPORTED_LOCALES`enum in [`backend/app/i18n/types.py`](backend/app/i18n/types.py).
105
+
***Supported languages:** Listed in the `SUPPORTED_LOCALES`list in [`backend/app/i18n/types.py`](backend/app/i18n/types.py).
148
106
149
107
### 2. Frontend
150
108
151
109
***Registered languages:** Defined in [`frontend-new/src/i18n/i18n.ts`](frontend-new/src/i18n/i18n.ts) (translation resources) and [`frontend-new/src/i18n/constants.ts`](frontend-new/src/i18n/constants.ts) (`Locale`, `LocalesLabels`, `SupportedLocales`).
152
-
***Default language:**`FRONTEND_DEFAULT_LOCALE` in `public/data/env.js` sets the default UI language.
110
+
***Default language:**`FRONTEND_DEFAULT_LOCALE` in `public/data/env.js` sets the default UI language if no user preference is set.
153
111
***Switching languages at runtime:** Users can select a language from the UI menu. Only locales listed in `FRONTEND_SUPPORTED_LOCALES` are available. To change the default language in the frontend, update `FRONTEND_DEFAULT_LOCALE` in the environment configuration.
154
112
155
-
> **Note:** Backend and frontend are not automatically synchronized. To ensure a consistent language across the application, configure both layers to support and use the same language.
113
+
> **Note:** Backend and frontend active languages are not automatically synchronized. To ensure a completely consistent language across the application, configure both layers to support and default to the same language.
0 commit comments