Skip to content

Strings and Localization

Max Karolinskiy edited this page Mar 13, 2024 · 57 revisions

Most strings are provided as resources, so that they may be translated to the many languages that Brave supports.

They can be split in to two categories: those that are provided and referenced only from Brave code, and those that are provided and referenced from within Chromium code.

Brave-only strings

All brave-only strings are referenced from one of the files listed in lib/l10nUtil.js in braveNonGeneratedPaths.

Modifications and additions should be made directly to one of the files listed there. Translated versions of modified or added strings will only happen once per release cycle.

Chromium strings

Any chromium strings we do not want to modify

No action necessary. Original and translated strings from chromium src .grd, .grdp and .xtb files are used in-place.

Any chromium strings we want to modify for brave

For each chromium release, the chromium GRD and GRDP files that we wish to make modifications to are copied to a file inside the brave-core source. Some mappings include:

Chromium path Brave path
chrome_app_chromium_strings.grd app/brave_strings.grd
chrome_app_generated_resources.grd app/generated_resources.grd
chrome_app_bookmarks_strings.grdp app/bookmarks_strings.grdp
  • If the GRD or GRDP is not yet present by Brave-Core:
    • Add a path to brave-browser/lib/l10nUtil.js
    • Add an entry to chromiumToAutoGeneratedBraveMapping map
    • Add a mapping to get_original_grd function in brave/script/lib/transifex.py
  • Add any whole-file string replacement rules to the rebaseBraveStringFilesOnChromiumL10nFiles function
    • Add any specific xml transforms to chromium-rebase-l10n.py
  • In Brave-Browser, run npm run chromium_rebase_l10n
    • This will output a new or modified .grd[p] file which should be committed.
    • _override.grd files are generated automatically (please don't make edits to them). There are a series of regex replacements done (ex: Chrome => Brave) and these _override.grd files will get overwritten each time.

The modified string will then get translated when the next release train visits the localization station!

Modifying English strings invalidates all translations

Modifying English source strings in GRD files will invalidate all translations of that string, since the translations reference the original string hash. All users will then only see the English fallback string until the next translation process is performed during a release cycle.

Language files

These are .xtb files containing xml elements of the form:

<translation id=“[number]”>[Translated Text]</translation>

The Translation ID refers to the unique fingerprint of the original string as it appears in the source GRD file. This means that multiple strings that have the exact same English value in the source GRD file will only get translated once per language per GRD file.

Transifex

Strings are matched using filename (not path). This is something we control in transifex.py. Within each file, each unique string from a GRD is translated and pulled down. It is then stored in a corresponding .xtb file with the translation ID (unique fingerprint of the original string).

GRD Tips

  • Provide a descriptive desc=“” attribute on each <message attribute informing the translator of the context for the string.
    • Mention if it should be title case or not
    • Specify which Proper Nouns should not be translated.
  • Use translateable="false" if the whole string should not be translated.
  • Use <if expr=“”> to inform the compiler which string to select. This is useful for platform variations or platform-specific strings. For example:
    • Strings that should have a different case on different systems such as title-case for macOS menus and lower-case for menus on other platforms (<if expr="use_titlecase">)
    • Strings that only appear on a single platform, such as Android (<if expr="is_android">)

Information for submitting localization orders:

  • Login to Transifex and navigate to the Brave dashboard https://www.transifex.com/brave/brave/dashboard/
  • Click Order
  • You can pick from 3 providers gengo, TextMaster, and e2f
  • We use e2f.
  • Select something like Technical and Software for the "Tone". This screen also allows you to write information to the localizer. Simply put this in that box:
Please read this!

https://github.com/brave/brave-browser/wiki/Information-for-localizers
  • Press Next and it should take a minute or two to load, I think this happens because we have a lot of strings.
  • Uncheck All, then only select these resources for translation, the rest are taken from Chromium but we just store them in Transifex:
    • android_brave_strings,
    • brave_components_resources,
    • brave_extension,
    • brave_generated_resources, and
    • all *_override files.
    • Leave the rest unchecked!
  • The officially supported (by Chromium) languages are:

af, am, ar, as, az, be, bg, bn, bs, ca, cs, cy, da, de, el, en-GB, en, es, es-419, et, eu, fa, fi, fil, fr-CA, fr, gl, gu, he, hi, hr, hu, hy, id, is, it, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt-BR, pt-PT, or, ro, ru, si, sk, sl, sq, sr-Latn, sr, sv, sw, ta, te, th, tr, uk, ur, uz, vi, zh-CN, zh-HK, zh-TW, zu
  • Here are the 49 languages we currently select to order (same as bolded items in the above list):
# e2f

Amharic       (am)
Arabic        (ar)
Bengali       (bn)
Bulgarian     (bg)
Catalan       (ca)
Chinese-CN    (zh-CN)
Chinese-TW    (zh-TW)
Croatian      (hr)
Czech         (cs)
Danish        (da)
Dutch         (nl)
English-GB    (en-GB)
Estonian      (et)
Filipino      (fil)
Finnish       (fi)
French        (fr)
French-CA     (fr-CA)
Galician      (gl)
German        (de)
Greek         (el)
Hebrew        (he)
Hindi         (hi)
Hungarian     (hu)
Indonesian    (id)
Italian       (it)
Japanese      (ja)
Kannada       (kn)
Korean        (ko)
Latvian       (lv)
Lithuanian    (lt)
Malay         (ms)
Norwegian     (no)
Persian       (fa)
Polish        (pl)
Portuguese-BR (pt-BR)
Portuguese-PT (pt-PT)
Romanian      (ro)
Russian       (ru)
Serbian       (sr)
Slovak        (sk)
Slovenian     (sl)
Spanish       (es)
Spanish-LA    (es-419)
Swahili       (sw)
Swedish       (sv)
Thai          (th)
Turkish       (tr)
Ukrainian     (uk)
Vietnamese    (vi)
  • The total cost is usually in the hundreds to thousands range, but usually below 10k. If it's above 10k then please get special approval and make sure everything is being selected correctly.

Information for localizers:

This information can now be found here

When to submit orders and what to do when they're done

For Desktop, the ideal time to submit an order would be 1 week before the release. Per the release schedule, this lines up with the migration date. We have submitted orders with 4 days left before a release, but that's very tight. The translations themselves take a while to complete.

When it's time to submit, we typically have the PR that contains the uplift of the target Chromium version into the Release branch (or, Beta branch, if the channel migration has not run yet). We submit the strings from that branch. If the uplift has already been merged into the Release (Beta - before the migrations) branch, then we submit from that branch directly, instead of the PR branch. Once the translations have been completed, we pull them into the Release branch and then look at back-porting the strings into other branches. If release channel is 1.2 and nightly is 1.4, we'd create "lowering" PRs for 1.3 and 1.4 with the string changes from 1.2.

Once translations are ordered, we should make every effort to NOT make string changes to the product. The strings in the product should be considered frozen by reviewers.

Pushing and pulling localizations

Run this to push new strings to Transifex. The script can also push up translations, if needed (see command line params). If you need access to Transifex talk to devops.

To run these command you will need Python3 (3.10.x) with the following modules:

  • lxml
  • transifex-python==2.1.0
npm run push_l10n

Run this to pull down new xtb and translation files:

npm run pull_l10n

Do a commit for all the string translation updates (message.json and/or xtb files).

Localizing extensions

Ethereum Remote Client

These steps should be done any time we have new strings and any time we rebase on top of MetaMask.

Pushing changes to Transifex:

npm run push_l10n -- --extension=ethereum-remote-client

Pulling changes from Transifex:

npm run pull_l10n -- --extension=ethereum-remote-client

A rule for developing w/ strings for this extension: Never change a MetaMask source string text, instead change the l10n ID that's being used and add the string into brave/app/_locales/en/messages.json

The official supported locales are the same as in Brave and are listed above here: https://github.com/brave/brave-browser/wiki/Strings-and-Localization#information-for-submitting-localization-orders When making an order you want to select both of these projects:

  • ethereum_remote_client_extension
  • brave_ethereum_remote_client_extension

Note, they don't fully match the list from MetaMask.

MetaMask supports hn, ht, and ph that Brave does not. This is changing but it uses tml for ta as well.

Clone this wiki locally