Our translation keys are broken down into three sections:
namespace:filename.string
namespace
provides a convenient grouping for translations or modules. Each namespace will get its own file full of translations.filename
should match the current file name, unless it is generic and there is a real risk of overlap with another file in the same namespace.string
should convey the meaning or purpose of the individual string being translated. It should make sense to a translator who does not understand code.
We follow these conventions in order to produce a consistent and predictable translation keys that avoid conflicts.
Please read:
In our project, we are breaking our namespaces down by what are effectively modules. You can either go with an existing namespace for the module you are working in, or you can create a new name if none exists. A general rule of thumb is that the namespace works well if it contains some reference to the relative path in which it exists.
For example:
src/ui/client/components/Landing/home.tsx
Might have a namespace of:
componentsLanding
Or possibly just:
landing
Omit any portions of the path that do not seem relevant to the namespace. For example, we've already omitted src/ui/client
.
The namespace
portion of your key should ONLY be aware of the path that it is in. Generally, it should NOT reference any individual filename or string name contained within.
If a single namespace contains hundreds of translations, consider breaking it up into multiple namespaces.
A translated string in our application might look like this:
t('namespace:filename.quickBrownFox', 'Quick brown fox')
When the translation files are compiled, the following JSON structure will be created:
{
"namespace": {
"filename": {
"quickBrownFox": "Quick brown fox"
}
}
}
We have chosen to include filenames in our keys. This helps ensure uniqueness among keys, and avoid potential conflicts between files with similar (but slightly different) strings.
For example, Sort By
is in file1.tsx
, and + SORT BY
is in file2.tsx
. We don't want to accidentally merge them into the same translated string by overlapping their key as namespace:sortBy
. Instead, having namespace:file1.sortBy
and namespace:file2.sortBy
helps ensure uniqueness and avoid accidental conflicts while being easy for developers to write and maintain.
It may be tempting to truncate the filename, but please avoid doing this. For example, truncating file2Container
to just file2
.
The filename
portion of your key should ONLY be aware of the filename that it exists within. It should NOT reference its path or the string(s) included in that file.
This is the last portion of our key. It should represent the string being translated, and it should be human readable by a non-programmer. Expect translators to look to this for a reference to what the meaning of the original string was.
- A short string such as
Sort By
might get a key ofsortBy
. - A generic paragraph of text for an About Page might get a key of
descriptionParagraph
. - The second paragraph might get the key
descriptionParagraph2
. - A short sentence such as
Students will turn this in to their teachers for grading
might get the keyturnInForGrading
orstudentsTurnInForGrading
. - When two similar strings exist in the same file, such as
add more
and+ add more
, it is necessary to use unique keys, such asaddMore
andplusAddMore
.
This portion of the translation key should ONLY be aware of the individual string being translated. It should NOT reference the filename or path.