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
@@ -3,16 +3,116 @@ title: Contributing to Internationalization
3
3
sidebar_label: Contributing
4
4
---
5
5
6
-
This section introduces some concepts for contributing translations and is
7
-
especially important when submitting a new language.
6
+
Welcome! This guide will help you contribute translations to Headlamp.
8
7
9
-
**Important:** If you add a new language, keep in mind that while all
8
+
## Quick Start
9
+
10
+
### Where to Edit Translations
11
+
12
+
**⚠️ IMPORTANT:** All translations should be edited in:
13
+
```
14
+
frontend/src/i18n/locales/
15
+
```
16
+
17
+
This is the **single source of truth** for all translations. Do not edit translation files in other locations (like `plugins/headlamp-plugin/src/i18n/locales/`) as they are auto-generated during the build process.
18
+
19
+
### Translation File Structure
20
+
21
+
Each language has its own directory with three JSON files:
22
+
23
+
```
24
+
locales/
25
+
├── en/ # English (reference language)
26
+
│ ├── translation.json # Main translations
27
+
│ ├── glossary.json # Kubernetes technical terms
28
+
│ └── app.json # Desktop app specific strings
29
+
├── de/ # German
30
+
│ ├── translation.json
31
+
│ ├── glossary.json
32
+
│ └── app.json
33
+
├── fr/ # French
34
+
...
35
+
```
36
+
37
+
**Important:** When adding a new language, keep in mind that while all
10
38
the specific Kubernetes components' names are translatable, not all of them
11
39
will have a corresponding name in your language. Please refer to the
12
40
[Kubernetes localized docs](https://kubernetes.io/docs/home/) in your
13
41
language (if they exist) to understand which components should
14
42
be translated and which should be left in their original form.
15
43
44
+
## Helper Commands
45
+
46
+
We provide several commands to make translation easier:
47
+
48
+
### Check Translation Status
49
+
50
+
See which languages need translation work:
51
+
52
+
```bash
53
+
npm run i18n:status
54
+
```
55
+
56
+
This shows a colorful table with:
57
+
- Translation completion percentage for each language
58
+
- Number of translated vs. missing strings
59
+
- Visual progress bars
60
+
61
+
### List Translation Files
62
+
63
+
See all translation files with their completion status:
64
+
65
+
```bash
66
+
# List all languages
67
+
npm run i18n:list
68
+
69
+
# List specific language (note the -- before language code)
70
+
npm run i18n:list -- de
71
+
```
72
+
73
+
This shows:
74
+
- All translation files for each language
75
+
- Completion percentage for each file
76
+
- Missing files (if any)
77
+
- File paths
78
+
79
+
### Extract Empty Translations
80
+
81
+
Extract untranslated strings to a separate file for easier translation:
82
+
83
+
```bash
84
+
npm run i18n:extract -- frontend/src/i18n/locales/de/translation.json
85
+
```
86
+
87
+
This creates a file (e.g., `translation_empty.json`) containing only the empty translations. You can:
88
+
1. Translate the strings in this smaller file
89
+
2. Use the copy command (below) to merge them back
90
+
91
+
Optional: Specify output filename:
92
+
```bash
93
+
npm run i18n:extract -- frontend/src/i18n/locales/de/translation.json my_translations.json
94
+
```
95
+
96
+
### Copy Translations Between Files
97
+
98
+
Copy translations from one file to another:
99
+
100
+
```bash
101
+
# Basic usage - only copy missing translations
102
+
npm run i18n:copy -- source.json dest.json
103
+
104
+
# Force overwrite all translations (including non-empty ones)
105
+
npm run i18n:copy -- source.json dest.json --force
106
+
107
+
# Copy all keys from source, even if they don't exist in destination
108
+
npm run i18n:copy -- source.json dest.json --all
109
+
```
110
+
111
+
This is useful for:
112
+
- Merging completed translations back from an extracted file
113
+
- Copying translations between language files
114
+
- Updating translations selectively
115
+
16
116
## Namespaces
17
117
18
118
We have only two main [i18next namespaces](https://www.i18next.com/principles/namespaces):
@@ -86,39 +186,72 @@ Here's an example of using date formatting:
86
186
});
87
187
```
88
188
89
-
## Adding a new language
189
+
## Translation Workflow
190
+
191
+
### For Updating Existing Languages
90
192
91
-
Create a folder using the locale code in:
92
-
`frontend/src/i18n/locales/`
193
+
1.**Check translation status:**
194
+
```bash
195
+
npm run i18n:status
196
+
```
93
197
94
-
Then run `npm run i18n`. This command parses the translatable strings in
95
-
the project and creates the corresponding catalog files.
198
+
2.**Open the JSON files directly** in `frontend/src/i18n/locales/<lang>/`
199
+
-`translation.json` - UI strings
200
+
-`glossary.json` - Kubernetes technical terms
201
+
-`app.json` - App-specific strings
202
+
203
+
3.**Find empty strings** (these need translation):
204
+
```json
205
+
{
206
+
"Some key": "", ← Needs translation
207
+
"Another key": "Translated text"← Already done
208
+
}
209
+
```
210
+
211
+
4.**Add translations** for empty strings:
212
+
```json
213
+
{
214
+
"Some key": "Your translation here",
215
+
"Another key": "Translated text"
216
+
}
217
+
```
218
+
219
+
5.**Verify your work:**
220
+
```bash
221
+
npm run i18n:status
222
+
```
223
+
224
+
6.**Submit a pull request** with your changes
225
+
226
+
### For Adding a New Language
227
+
228
+
1.**Create the language directory:**
229
+
```bash
230
+
mkdir frontend/src/i18n/locales/<lang-code>
231
+
```
232
+
233
+
Language codes should follow the [ISO 639-1 standard](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).
234
+
235
+
2.**Generate translation files:**
236
+
```bash
237
+
# From the project root
238
+
npm run i18n
239
+
```
240
+
241
+
This will create empty translation files for your new language.
242
+
243
+
3.**Follow the update workflow above** to translate the strings
96
244
97
245
Integrated components may need to be adjusted (MaterialUI/Monaco etc).
98
246
99
-
## Translating missing strings
100
-
101
-
Technical development happens more frequently than translations. Thus, chances
102
-
are that developers introduce new strings that need to be translated and will
103
-
be stored as empty strings (defaulting to English) in the translation files.
104
-
105
-
In order to more easily spot and translate the missing strings, we have two CLI
106
-
tools:
107
-
108
-
-_extract-empty-translations.js_: This script (in ./frontend/src/i18n/tools/)
109
-
will extract the strings without a corresponding translation from the translation
110
-
files, and copy them into a new file.
111
-
E.g. `$ node copy-empty-translations.js ../locales/de/translation.json` will
112
-
by default create a `../locales/de/translation_empty.json`. This file can be
113
-
used to translate the strings in a more isolated way.
114
-
-_copy-translations.js_: This script (in ./frontend/src/i18n/tools/)
115
-
by default copies any existing translations from one source translation file to
116
-
a target one, if the same key is not translated in the destination file.
117
-
E.g. `$ node copy-translations.js ../locales/de/translation_no_longer_empty.json ../locales/de/translation.json` will
118
-
copy any new translations from the file given as the first argument to the one
119
-
given as the second argument, if the same key is not translated in the second.
120
-
There are some options to this script, which can be seen by running it with the
121
-
`--help` flag.
247
+
## Deprecated Tools
248
+
249
+
**⚠️ DEPRECATED:** The old CLI tools in `frontend/src/i18n/tools/` are deprecated and should no longer be used:
250
+
251
+
-`extract-empty-translations.js` → Use `npm run i18n:extract` instead
252
+
-`copy-translations.js` → Use `npm run i18n:copy` instead
253
+
254
+
The new i18n tool (see Helper Commands above) provides the same functionality with better error handling and a more consistent interface.
Copy file name to clipboardExpand all lines: frontend/src/i18n/README.md
+27-1Lines changed: 27 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,4 +2,30 @@
2
2
3
3
We try and keep all the i18n related things in here.
4
4
5
-
See the [i18n docs](../../docs/development/i18n.md) for full details.
5
+
## For Translators
6
+
7
+
See the [i18n contributing guide](../../../docs/development/i18n/contributing.md) for a complete guide on how to contribute translations.
8
+
9
+
### Quick Commands
10
+
11
+
```bash
12
+
npm run i18n:status # Show translation status for all languages
13
+
npm run i18n:list # List all translation files with completion status
14
+
npm run i18n:list -- de # List translation files for German with completion status
15
+
```
16
+
17
+
**Note:** These commands are run from the project root directory.
18
+
19
+
## Translation File Location
20
+
21
+
**⚠️ IMPORTANT:** All translations should be edited in:
22
+
23
+
```
24
+
frontend/src/i18n/locales/
25
+
```
26
+
27
+
This is the **single source of truth** for all Headlamp translations. Do not edit translation files in other locations (like `plugins/headlamp-plugin/src/i18n/locales/`) as they are auto-generated.
28
+
29
+
## For Developers
30
+
31
+
See the [i18n docs](../../docs/development/i18n.md) for full technical details.
Copy file name to clipboardExpand all lines: frontend/src/i18n/locales/en/app.json
+17-17Lines changed: 17 additions & 17 deletions
Original file line number
Diff line number
Diff line change
@@ -1,11 +1,11 @@
1
1
{
2
-
"Failed to fetch plugin info": "",
3
-
"An error occurred while fetching plugin info from {{ URL }}.": "",
4
-
"Yes": "",
5
-
"No": "",
6
-
"Plugin Installation": "",
7
-
"Do you want to install the plugin \"{{ pluginName }}\"?": "",
8
-
"You are about to install a plugin from: {{ url }}\nDo you want to proceed?": "",
2
+
"Failed to fetch plugin info": "Failed to fetch plugin info",
3
+
"An error occurred while fetching plugin info from {{ URL }}.": "An error occurred while fetching plugin info from {{ URL }}.",
4
+
"Yes": "Yes",
5
+
"No": "No",
6
+
"Plugin Installation": "Plugin Installation",
7
+
"Do you want to install the plugin \"{{ pluginName }}\"?": "Do you want to install the plugin \"{{ pluginName }}\"?",
8
+
"You are about to install a plugin from: {{ url }}\nDo you want to proceed?": "You are about to install a plugin from: {{ url }}\nDo you want to proceed?",
9
9
"About": "About",
10
10
"Quit": "Quit",
11
11
"Select All": "Select All",
@@ -30,11 +30,11 @@
30
30
"Zoom In": "Zoom In",
31
31
"Zoom Out": "Zoom Out",
32
32
"Toggle Fullscreen": "Toggle Fullscreen",
33
-
"Navigate": "",
33
+
"Navigate": "Navigate",
34
34
"Reload": "Reload",
35
-
"Go to Home": "",
36
-
"Go Back": "",
37
-
"Go Forward": "",
35
+
"Go to Home": "Go to Home",
36
+
"Go Back": "Go Back",
37
+
"Go Forward": "Go Forward",
38
38
"Window": "Window",
39
39
"Minimize": "Minimize",
40
40
"Bring All to Front": "Bring All to Front",
@@ -46,12 +46,12 @@
46
46
"Continue": "Continue",
47
47
"Failed to quit the other running process": "Failed to quit the other running process",
48
48
"Could not quit the other running process, PIDs: {{ process_list }}. Please stop that process and relaunch the app.": "Could not quit the other running process, PIDs: {{ process_list }}. Please stop that process and relaunch the app.",
49
-
"No available ports": "",
50
-
"Could not find an available port. There are processes running on ports {{startPort}}-{{endPort}}. Terminate these processes and retry?": "",
51
-
"Terminate and Retry": "",
52
-
"Failed to start": "",
53
-
"Could not start the server even after terminating existing processes.": "",
54
-
"Could not find an available port in the range {{startPort}}-{{endPort}}. Please free up a port and try again.": "",
49
+
"No available ports": "No available ports",
50
+
"Could not find an available port. There are processes running on ports {{startPort}}-{{endPort}}. Terminate these processes and retry?": "Could not find an available port. There are processes running on ports {{startPort}}-{{endPort}}. Terminate these processes and retry?",
51
+
"Terminate and Retry": "Terminate and Retry",
52
+
"Failed to start": "Failed to start",
53
+
"Could not start the server even after terminating existing processes.": "Could not start the server even after terminating existing processes.",
54
+
"Could not find an available port in the range {{startPort}}-{{endPort}}. Please free up a port and try again.": "Could not find an available port in the range {{startPort}}-{{endPort}}. Please free up a port and try again.",
55
55
"Invalid URL": "Invalid URL",
56
56
"Application opened with an invalid URL: {{ url }}": "Application opened with an invalid URL: {{ url }}"
0 commit comments