For Developers‎ > ‎Design Documents‎ > ‎

UI Localization (aka Translations)

If you find an error in an existing translation, please file a bug using the translation template.  CC "".  Thank you!
You can also help provide translations for the chromium-browser package on Ubuntu.

How to add a string

  1. Add the string to the grd file (generated_resources.grd, webkit_strings.grd, chromium_strings.grd or google_chrome_strings.grd).  See below in the "Overview of files" section for guidance on which file to add the string to.
  2. **Very important info on writing good message descriptions - see section below.
  3. Surround the string with an appropriate <if> clause to ensure that it's only included it on platforms where it's actually used (e.g. Mac and Linux). Strings used on all platforms can omit the <if> clause.
  4. The next time you build the solution, this will automatically add the en-US string to en-US.dll.
  5. In your code, include ui/base/l10n/l10n_util.h and grit/generated_resources.h.
  6. To get the string, use l10n_util::GetStringUTF16.  Alternately, you can use l10n_util::GetStringFUTF16 which will replace placeholders $1 through $4 with the extra arguments of GetStringFUTF16.  Note that we generally prefer to use UTF-16 encoded strings for user-visible text.
The base messages (en-US) will be translated to supported locales by an internal Google Localization process, and translations will appear in the associated .xtb files after ~a couple of weeks.

How to add an Android/Java string

  1. Add the string to the grd file in the Java folder (e.g. content/public/android/java/strings/android_content_strings.grd).  Strings should be named in all caps with the prefix IDS_.  For example: IDS_MY_STRING.
  2. **Very important info on writing good message descriptions - see section below.
  3. At build time, an Android-style strings.xml file will be generated in the out directory.
  4. You can reference these strings in Java code using the standard R.string.my_string syntax, or in Android layouts using @string/my_string.  Note: the name is lowercase and the IDS_ prefix is stripped.
The base messages (en-US) will be translated to supported locales by an internal Google Localization process, and translations will appear in the associated .xtb files after ~a couple of weeks.

How to add a new grd(p) file

  • This should be rare. We want to be very careful about expanding the number of grd(p) files in our source tree.
  • New grdp files need to be referenced from a parent grd file.
  • New grd files need to be added to /src/tools/gritsettings/resource_ids, IF the resources will be referenced from C++ code (won't compile without - this doesn't impact translation process).
  • New grd files need to have a rule added to /src/chrome/chrome_resources.gyp, IF the resources will be referenced from C++ code (won't compile without - this doesn't impact translation process).
    • During 'gclient sync' these grit rules are run, and your grd's '.h' file will be generated.  This file should be included by any .cc file that references your strings.
  • New grd files need to be added to /src/tools/gritsettings/translation_expectations.pyl (or <message>s won't be translated).
  • If your new grd(p) will result in new XTB files after translation, you must commit placeholder .xtb files, or Chrome won't compile. The placeholders need to have a basic xml structure.
    •  Here's a handy way to create the xtbs: 
> for lang in fr de en-GB etc; do echo '<?xml version="1.0" ?><!DOCTYPE translationbundle><translationbundle lang="'$lang'"></translationbundle>' > foo_strings_$lang.xtb; done

  • If your new grd will NOT be translated (set in translation_expectations.pyl and no XTB placeholder files required above), there is very minimal XML content required in your grd.  I wanted to document an example here:
<?xml version="1.0" encoding="utf-8"?>
This file contains all "about" strings.  It is set to NOT be translated, in translation_expectations.pyl.  en-US only.
<grit base_dir="." latest_public_release="0" current_release="1"
      source_lang_id="en" enc_check="möl">
    <output filename="grit/about_strings.h" type="rc_header">
      <emit emit_type='prepend'></emit>
  <release seq="1" allow_pseudo="false">
    <messages fallback_to_english="true">
        Debug everything.

Workflow for how strings get translated for Google Chrome

  1. Strings get added to a grd(p) file in en-US.
  2. [BlackCloudOfMagic] Translators are provided with the new strings
  3. <internal link> Further internal detail about this semi-automated process here.  </internal link>
  4. [BlackCloudOfMagic] Translations are created and dumped to xtb files
  5. Changes to xtb files are checked into the Chromium source tree


    Strings are included on all platforms by default and will needlessly increase the download size if not used.  It's important to judiciously surround strings with an appropriate <if> clauses  to ensure that they are only included on the platforms where they're actually used.

Writing good message descriptions

The message description added to the grd(p) file with your string is currently the only context our translators receive when translating UI strings.  We would all like to do our best to ensure that the user experience with Chromium is as natural as possible, no matter the language.  So let's try to give the translators as much clear context as possible.  The following includes what information is needed in a good description, placeholder information, max chars limit, as well as some examples of what these should look like.

IE: (The translator would only see what is in bold)

<message name="IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED" desc="In Title Case: Title of the bubble after bookmarking a page.">
    Bookmark Added!

(NOTE: Translators also see "meaning" if added to a message, but we only want to use this in special cases where there are duplicate identical source messages - but they have different contexts/restrictions, so we want them translated separately.)

Why do we need message descriptions?

The problem
: Currently, the translators often have no context when they translate -- they see each string in isolation and in random order, so they don't even know which feature it could be associated with, where it might appear on a page, or what action it triggers. Without context, they can't know how to translate appropriately.

The solution
: Message descriptions can help provide context and other essential information, which in turn increases the speed, accuracy, and quality of translations, and, ultimately, improves user satisfaction.

What information should I provide in the message description?

  • Where is the text located? (e.g., button, title, link, pull-down menu)
  • What triggers the message and/or what is the result? What page or text comes before and after?
  • What do the placeholders stand for? Will this message replace a placeholder in another message? Do they need to be arranged in a certain way?
  • Is this a verb or a noun? If an adjective, what does it refer to?
  • Who is the message intended for?
  • Are there any specific character limits that must not be exceeded? (e.g., for mobile products where UI space is restricted)
How should line breaks be dealt with? Are there character limitations per line? Keep in mind that the translators will not know the product as well as you do, and they work on multiple products and projects. Also, they're not engineers. So make sure that the description will be understandable by a more general audience and doesn't contain too much technical detail. Imagine giving this description out of context to a person not on your project, say your Aunt. Would they still understand it?

What does this look like in practice?

Source Message: "US city or zip"
Original Description: The message is shown in gray in the empty search box for a movie showtimes location. The content of the message should be localized by country to mean city or postal code (or simply city). Its purpose is to tell the user what kind of input will produce results.
Comment: This is very informative description, that clearly explains the context and also gives specific instructions on how the message should be adapted for another (non-US) locale.

Source Message: "Apply"
Original Description: Button label for the apply button.
Comment: Provides the context, but the translator will also need to know what is going to be applied.
Better Description: Button label; clicking the button will apply the selected label names to the message thread.

Source Message: "read Gmail attachment previews"
Original Description: Displayed in the Settings panel which lists the various permissions that this app requires. Must start with a lowercase.
Comment: Providing the translators with instructions is good, but they also need to know the reason. Why does this need to be lowercase? Different languages have different conventions around capitalization, so we need to know the reason behind the instruction. Also, what is the context? Will any text come before or after?
Better Description: Displayed in the Settings panel which lists the various permissions that this app requires. Should start with a lowercase because it will be listed with other permissions, all separated by a comma.

Source Message: "Zoom"
Original Description: The "Zoom" menu command. It brings up help on how to zoom. Try to limit menu commands to 10 characters.
Comment: Very nice description in Mobile Maps. Tells us what it does, what it triggers and what the character limit should be to keep consistency across similar messages.

Source Message: "We could not send your message. A space alien ate it. Please try again in a few minutes."
Comment: Should we translate the "space alien" part, or should it be changed to an appropriate equivalent for that locale? Should it be funny? By default, the translators will probably translate the message literally, so if they should get creative, the message description should let them know that.
Better Description: An error message. This reason given is meant to be funny, so please use an appropriate silly reason for the error, and not necessarily a direct translation.

Subpages (1): Mac Notes