Description
Use the chrome.i18n
infrastructure to implement internationalization across your whole app or extension.
Manifest
If an extension has a /_locales
directory, the manifest must define "default_locale"
.
Concepts and usage
You need to put all of its user-visible strings into a file named messages.json
. Each time
you add a new locale, you add a messages file under a directory named /_locales/_localeCode_
, where
localeCode is a code such as en
for English.
Here's the file hierarchy for an internationalized extension that supports English (en
), Spanish
(es
), and Korean (ko
):
Support multiple languages
Say you have an extension with the files shown in the following figure:
To internationalize this extension, you name each user-visible string and put it into a messages file. The extension's manifest, CSS files, and JavaScript code use each string's name to get its localized version.
Here's what the extension looks like when it's internationalized (note that it still has only English strings):
Some notes about internationalizing:
- You can use any of the supported locales. If you use an unsupported locale, Google Chrome ignores it.
In
manifest.json
and CSS files, refer to a string named messagename like this:__MSG_messagename__
In your extension or app's JavaScript code, refer to a string named messagename like this:
chrome.i18n.getMessage("messagename")
In each call to
getMessage()
, you can supply up to 9 strings to be included in the message. See Examples: getMessage for details.Some messages, such as
@@bidi_dir
and@@ui_locale
, are provided by the internationalization system. See the Predefined messages section for a full list of predefined message names.In
messages.json
, each user-visible string has a name, a "message" item, and an optional "description" item. The name is a key such as "extName" or "search_string" that identifies the string. The "message" specifies the value of the string in this locale. The optional "description" provides help to translators, who might not be able to see how the string is used in your extension. For example:{ "search_string": { "message": "hello%20world", "description": "The string we search for. Put %20 between words that go together." }, ... }
For more information, see Formats: Locale-Specific Messages.
Once an extension is internationalized, translating it is straightforward. You copy messages.json
,
translate it, and put the copy into a new directory under /_locales
. For example, to support
Spanish, just put a translated copy of messages.json
under /_locales/es
. The following figure
shows the previous extension with a new Spanish translation.
Predefined messages
The internationalization system provides a few predefined messages to help you localize. These
include @@ui_locale
, so you can detect the current UI locale, and a few @@bidi_...
messages that
let you detect the text direction. The latter messages have similar names to constants in the
gadgets BIDI (bi-directional) API.
The special message @@extension_id
can be used in the CSS and JavaScript files, whether or not the
extension or app is localized. This message doesn't work in manifest files.
The following table describes each predefined message.
Message name | Description |
---|---|
@@extension_id | The extension or app ID; you might use this string to construct URLs for resources inside the extension. Even unlocalized extensions can use this message. Note: You can't use this message in a manifest file. |
@@ui_locale | The current locale; you might use this string to construct locale-specific URLs. |
@@bidi_dir | The text direction for the current locale, either "ltr" for left-to-right languages such as English or "rtl" for right-to-left languages such as Arabic. |
@@bidi_reversed_dir | If the @@bidi_dir is "ltr", then this is "rtl"; otherwise, it's "ltr". |
@@bidi_start_edge | If the @@bidi_dir is "ltr", then this is "left"; otherwise, it's "right". |
@@bidi_end_edge | If the @@bidi_dir is "ltr", then this is "right"; otherwise, it's "left". |
Here's an example of using @@extension_id
in a CSS file to construct a URL:
body {
background-image:url('chrome-extension://__MSG_@@extension_id__/background.png');
}
If the extension ID is abcdefghijklmnopqrstuvwxyzabcdef, then the bold line in the previous code snippet becomes:
background-image:url('chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef/background.png');
Here's an example of using @@bidi_*
messages in a CSS file:
body {
direction: __MSG_@@bidi_dir__;
}
div#header {
margin-bottom: 1.05em;
overflow: hidden;
padding-bottom: 1.5em;
padding-__MSG_@@bidi_start_edge__: 0;
padding-__MSG_@@bidi_end_edge__: 1.5em;
position: relative;
}
For left-to-right languages such as English, the bold lines become:
dir: ltr;
padding-left: 0;
padding-right: 1.5em;
Locales
You can choose from many locales, including some (such as en
) that let a single translation support multiple variations of a language (such as en_GB
and en_US
).
You can localize your extension to any locale that is supported by the Chrome Web Store. If your locale is not listed here, choose the closest alternative. For example, if the default locale of your extension is "de_CH"
, choose "de"
in the Chrome Web Store.
Locale code | Language (region) |
---|---|
ar | Arabic |
am | Amharic |
bg | Bulgarian |
bn | Bengali |
ca | Catalan |
cs | Czech |
da | Danish |
de | German |
el | Greek |
en | English |
en_AU | English (Australia) |
en_GB | English (Great Britain) |
en_US | English (USA) |
es | Spanish |
es_419 | Spanish (Latin America and Caribbean) |
et | Estonian |
fa | Persian |
fi | Finnish |
fil | Filipino |
fr | French |
gu | Gujarati |
he | Hebrew |
hi | Hindi |
hr | Croatian |
hu | Hungarian |
id | Indonesian |
it | Italian |
ja | Japanese |
kn | Kannada |
ko | Korean |
lt | Lithuanian |
lv | Latvian |
ml | Malayalam |
mr | Marathi |
ms | Malay |
nl | Dutch |
no | Norwegian |
pl | Polish |
pt_BR | Portuguese (Brazil) |
pt_PT | Portuguese (Portugal) |
ro | Romanian |
ru | Russian |
sk | Slovak |
sl | Slovenian |
sr | Serbian |
sv | Swedish |
sw | Swahili |
ta | Tamil |
te | Telugu |
th | Thai |
tr | Turkish |
uk | Ukrainian |
vi | Vietnamese |
zh_CN | Chinese (China) |
zh_TW | Chinese (Taiwan) |
Search for messages
You don't have to define every string for every supported locale. As long as the default locale's
messages.json
file has a value for every string, your extension or app will run no matter how
sparse a translation is. Here's how the extension system searches for a message:
- Search the messages file (if any) for the user's preferred locale. For example, when Google
Chrome's locale is set to British English (
en_GB
), the system first looks for the message in/_locales/en_GB/messages.json
. If that file exists and the message is there, the system looks no further. - If the user's preferred locale has a region (that is, the locale has an underscore: _), search
the locale without that region. For example, if the
en_GB
messages file doesn't exist or doesn't contain the message, the system looks in theen
messages file. If that file exists and the message is there, the system looks no further. - Search the messages file for the default locale. For example, if the extension's
"default_locale" is set to "es", and neither
/_locales/en_GB/messages.json
nor/_locales/en/messages.json
contains the message, the extension uses the message from/_locales/es/messages.json
.
In the following figure, the message named "colores" is in all three locales that the extension supports, but "extName" is in only two of the locales. Wherever a user running Google Chrome in US English sees the label "Colors", a user of British English sees "Colours". Both US English and British English users see the extension name "Hello World". Because the default language is Spanish, users running Google Chrome in any non-English language see the label "Colores" and the extension name "Hola mundo".
Set your browser's locale
To test translations, you might want to set your browser's locale. This section tells you how to set the locale in Windows, Mac OS, Linux, and ChromeOS.
Windows
You can change the locale using either a locale-specific shortcut or the Google Chrome UI. The shortcut approach is quicker, once you've set it up, and it lets you use several languages at once.
Use a locale-specific shortcut
To create and use a shortcut that launches Google Chrome with a particular locale:
- Make a copy of the Google Chrome shortcut that's already on your desktop.
- Rename the new shortcut to match the new locale.
Change the shortcut's properties so that the Target field specifies the
--lang
and--user-data-dir
flags. The target should look something like this:path_to_chrome.exe --lang=locale --user-data-dir=c:\locale_profile_dir
Launch Google Chrome by double-clicking the shortcut.
For example, to create a shortcut that launches Google Chrome in Spanish (es
), you might create a
shortcut named chrome-es
that has the following target:
path_to_chrome.exe --lang=es --user-data-dir=c:\chrome-profile-es
You can create as many shortcuts as you like, making it straightforward to test in multiple languages. For example:
path_to_chrome.exe --lang=en --user-data-dir=c:\chrome-profile-en
path_to_chrome.exe --lang=en_GB --user-data-dir=c:\chrome-profile-en_GB
path_to_chrome.exe --lang=ko --user-data-dir=c:\chrome-profile-ko
Use the UI
Here's how to change the locale using the UI on Google Chrome for Windows:
- App icon > Options
- Choose the Under the Hood tab
- Scroll to Web Content
- Click Change font and language settings
- Choose the Languages tab
- Use the drop down to set the Google Chrome language
- Restart Chrome
Mac OS
To change the locale on Mac, you use the system preferences.
- From the Apple menu, choose System Preferences
- Under the Personal section, choose International
- Choose your language and location
- Restart Chrome
Linux
To change the locale on Linux, first quit Google Chrome. Then, all in one line, set the LANGUAGE environment variable and launch Google Chrome. For example:
LANGUAGE=es ./chrome
ChromeOS
To change the locale on ChromeOS:
- From the system tray, choose Settings.
- Under the Languages and input section, choose the Language drop-down.
- If your language is not listed, click Add languages and add it.
- Once added, click the 3-dot More actions menu item next to your language and choose Display ChromeOS in this language.
- Click the Restart button that appears next to the set language to restart ChromeOS.
Examples
You can find examples of internationalization in the examples/api/i18n directory. For a complete example, see examples/extensions/news. For other examples and for help in viewing the source code, see Samples.
getMessage()
The following code gets a localized message from the browser and displays it as a string. It replaces two placeholders within the message with the strings "string1" and "string2".
function getMessage() {
var message = chrome.i18n.getMessage("click_here", ["string1", "string2"]);
document.getElementById("languageSpan").innerHTML = message;
}
Here's how you'd supply and use a single string:
// In JavaScript code
status.innerText = chrome.i18n.getMessage("error", errorDetails);
"error": {
"message": "Error: $details$",
"description": "Generic error template. Expects error parameter to be passed in.",
"placeholders": {
"details": {
"content": "$1",
"example": "Failed to fetch RSS feed."
}
}
}
For more information about placeholders, see the Locale-Specific Messages page. For details on
calling getMessage()
, see the API reference.
getAcceptLanguages()
The following code gets accept-languages from the browser and displays them as a string by separating each accept-language with ','.
function getAcceptLanguages() {
chrome.i18n.getAcceptLanguages(function(languageList) {
var languages = languageList.join(",");
document.getElementById("languageSpan").innerHTML = languages;
})
}
For details on calling getAcceptLanguages()
, see the API reference.
detectLanguage()
The following code detects up to 3 languages from the given string and displays the result as strings separated by new lines.
function detectLanguage(inputText) {
chrome.i18n.detectLanguage(inputText, function(result) {
var outputLang = "Detected Language: ";
var outputPercent = "Language Percentage: ";
for(i = 0; i < result.languages.length; i++) {
outputLang += result.languages[i].language + " ";
outputPercent +=result.languages[i].percentage + " ";
}
document.getElementById("languageSpan").innerHTML = outputLang + "\n" + outputPercent + "\nReliable: " + result.isReliable;
});
}
For more details on calling detectLanguage(inputText)
, see the API reference.
Types
LanguageCode
An ISO language code such as en
or fr
. For a complete list of languages supported by this method, see kLanguageInfoTable. For an unknown language, und
will be returned, which means that [percentage] of the text is unknown to CLD
Type
string
Methods
detectLanguage()
chrome.i18n.detectLanguage(
text: string,
callback?: function,
)
Detects the language of the provided text using CLD.
Parameters
-
text
string
User input string to be translated.
-
callback
function optional
The
callback
parameter looks like:(result: object) => void
-
result
object
LanguageDetectionResult object that holds detected langugae reliability and array of DetectedLanguage
-
isReliable
boolean
CLD detected language reliability
-
languages
object[]
array of detectedLanguage
-
language
string
-
percentage
number
The percentage of the detected language
-
-
-
Returns
-
Promise<object>
Chrome 99+Promises are supported in Manifest V3 and later, but callbacks are provided for backward compatibility. You cannot use both on the same function call. The promise resolves with the same type that is passed to the callback.
getAcceptLanguages()
chrome.i18n.getAcceptLanguages(
callback?: function,
)
Gets the accept-languages of the browser. This is different from the locale used by the browser; to get the locale, use i18n.getUILanguage
.
Parameters
-
callback
function optional
The
callback
parameter looks like:(languages: string[]) => void
-
languages
string[]
Array of LanguageCode
-
Returns
-
Promise<LanguageCode[]>
Chrome 99+Promises are supported in Manifest V3 and later, but callbacks are provided for backward compatibility. You cannot use both on the same function call. The promise resolves with the same type that is passed to the callback.
getMessage()
chrome.i18n.getMessage(
messageName: string,
substitutions?: any,
options?: object,
)
Gets the localized string for the specified message. If the message is missing, this method returns an empty string (''). If the format of the getMessage()
call is wrong — for example, messageName is not a string or the substitutions array has more than 9 elements — this method returns undefined
.
Parameters
-
messageName
string
The name of the message, as specified in the
messages.json
file. -
substitutions
any optional
Up to 9 substitution strings, if the message requires any.
-
options
object optional
Chrome 79+-
escapeLt
boolean optional
Escape
<
in translation to<
. This applies only to the message itself, not to the placeholders. Developers might want to use this if the translation is used in an HTML context. Closure Templates used with Closure Compiler generate this automatically.
-
Returns
-
string
Message localized for current locale.
getUILanguage()
chrome.i18n.getUILanguage()
Gets the browser UI language of the browser. This is different from i18n.getAcceptLanguages
which returns the preferred user languages.
Returns
-
string
The browser UI language code such as en-US or fr-FR.