Chrome Extension Localization: The Complete i18n Guide (2026)
Why Localize Your Chrome Extension?
The Chrome Web Store serves users in 200+ countries. Extensions available in multiple languages see dramatically higher install rates — Chrome automatically shows your extension in the user’s preferred language when translations exist.
Localization (i18n) isn’t just translation. It includes adapting date formats, number formats, text direction, and cultural conventions. Chrome provides a built-in i18n system through messages.json files that makes this straightforward.
Setting Up the File Structure
Each supported locale needs its own messages.json file under the _locales directory:
my-extension/
├── _locales/
│ ├── en/
│ │ └── messages.json
│ ├── es/
│ │ └── messages.json
│ ├── fr/
│ │ └── messages.json
│ ├── ja/
│ │ └── messages.json
│ └── ar/
│ └── messages.json
├── manifest.json
└── popup.htmlSet the default locale in your manifest:
{
"manifest_version": 3,
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
"default_locale": "en"
}Message File Format
Each messages.json follows a structured format:
{
"extensionName": {
"message": "Tab Manager Pro",
"description": "The display name of the extension"
},
"extensionDescription": {
"message": "Organize, search, and manage your browser tabs efficiently",
"description": "Brief description shown in the Chrome Web Store"
},
"greeting": {
"message": "Welcome, $USER$!",
"description": "Greeting shown when the popup opens",
"placeholders": {
"user": {
"content": "$1",
"example": "John"
}
}
},
"tabCount": {
"message": "You have $COUNT$ open tabs",
"description": "Shows the number of open tabs",
"placeholders": {
"count": {
"content": "$1",
"example": "42"
}
}
}
}Field Reference
| Field | Required | Purpose |
|---|---|---|
message | Yes | The translated string |
description | No | Context for translators |
placeholders | No | Named variable substitutions |
placeholders.content | Yes (if placeholder used) | The replacement value or $1, $2 reference |
placeholders.example | No | Example value for translators |
Using Messages in Your Extension
In JavaScript
// Simple message
const name = chrome.i18n.getMessage('extensionName');
// With substitutions
const greeting = chrome.i18n.getMessage('greeting', ['John']);
const tabInfo = chrome.i18n.getMessage('tabCount', ['42']);In HTML (via CSS)
<p class="greeting" data-i18n="greeting"></p>// Auto-translate all elements with data-i18n attribute
document.querySelectorAll('[data-i18n]').forEach((el) => {
const key = el.getAttribute('data-i18n');
el.textContent = chrome.i18n.getMessage(key);
});In manifest.json
Use the __MSG_messageName__ pattern:
{
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
"action": {
"default_title": "__MSG_browserAction__"
}
}In CSS
body {
direction: __MSG_@@bidi_dir__;
font-family: __MSG_@@font_family__;
}Predefined Messages
Chrome provides several built-in messages you can use without defining them:
| Message | Example Value | Purpose |
|---|---|---|
@@extension_id | abcdefghij... | Extension’s unique ID |
@@ui_locale | en_US | Current UI locale |
@@bidi_dir | ltr or rtl | Text direction |
@@bidi_reversed_dir | rtl or ltr | Opposite direction |
@@bidi_start_edge | left or right | Starting edge |
@@bidi_end_edge | right or left | Ending edge |
@@font_family | 'Segoe UI', ... | Recommended font |
Advanced Placeholder Patterns
Multiple Placeholders
{
"downloadProgress": {
"message": "Downloading $FILENAME$ ($CURRENT$ of $TOTAL$)",
"placeholders": {
"filename": { "content": "$1", "example": "report.pdf" },
"current": { "content": "$2", "example": "3" },
"total": { "content": "$3", "example": "10" }
}
}
}Static Content Placeholders
For non-translatable content like brand names or HTML:
{
"welcomeMessage": {
"message": "Welcome to $APP_NAME$",
"placeholders": {
"app_name": {
"content": "ExtensionBooster",
"example": "ExtensionBooster"
}
}
}
}Escaping Dollar Signs
Use $$ for literal dollar signs:
{
"priceDisplay": {
"message": "Price: $$$AMOUNT$",
"placeholders": {
"amount": { "content": "$1", "example": "9.99" }
}
}
}Result: Price: $9.99
RTL (Right-to-Left) Support
For Arabic, Hebrew, and other RTL languages:
body {
direction: __MSG_@@bidi_dir__;
}
.sidebar {
float: __MSG_@@bidi_start_edge__;
}
.content {
margin-__MSG_@@bidi_start_edge__: 250px;
}// Detect RTL in JavaScript
const isRtl = chrome.i18n.getMessage('@@bidi_dir') === 'rtl';
if (isRtl) {
document.documentElement.setAttribute('dir', 'rtl');
}Localization Best Practices
- Write descriptions for every message — Translators need context to produce accurate translations.
- Use named placeholders —
$USER_NAME$is clearer than$1for translators. - Avoid concatenating translated strings — Word order varies across languages. Use placeholders instead.
- Test with long strings — German text averages 30% longer than English. Ensure your UI accommodates expansion.
- Include
examplein placeholders — Shows translators what the final output looks like. - Don’t hardcode strings — Extract every user-facing string, including error messages and tooltips.
Supported Locales
Chrome supports 50+ locales. The most impactful ones to translate first:
| Locale | Language | % Chrome Users |
|---|---|---|
en | English | ~25% |
zh_CN | Chinese (Simplified) | ~15% |
es | Spanish | ~8% |
pt_BR | Portuguese (Brazil) | ~5% |
ja | Japanese | ~4% |
de | German | ~4% |
fr | French | ~3% |
ko | Korean | ~3% |
What’s Next
Localization multiplies your extension’s reach with relatively low effort. Start with your top 5 languages, use descriptive placeholders, and test with RTL layouts.
Want to see how your localized extension performs across different markets? ExtensionBooster provides analytics and market insights to help you grow globally.
Share this article
Build better extensions with free tools
Icon generator, MV3 converter, review exporter, and more — no signup needed.
Related Articles
I Built the Same Chrome Extension With 5 Different Frameworks. Here's What Actually Happened.
WXT vs Plasmo vs CRXJS vs Extension.js vs Bedframe. Real benchmarks, honest opinions, and the framework with 12K stars that's quietly dying.
5 Best Email Marketing Services to Grow Your Chrome Extension (2026)
Compare the top email marketing platforms for SaaS and Chrome extension developers. MailerLite, Mailchimp, Brevo, ActiveCampaign, and Drip reviewed.
15 Best Practices to Build a Browser Extension That Users Love (2026 Guide)
Master browser extension development in 2026. Manifest V3, security, performance, and UX best practices to build extensions users love.