This document describes uBlock Origin's localization system, which provides translated user interface strings for 60+ languages. It covers the structure of translation files, message naming conventions, placeholder substitution mechanisms, and how localized strings are loaded and used at runtime through the browser's i18n API.
For information about the user interface components that display these localized strings, see User Interface.
The internationalization system is built on the browser-native browser.i18n API. Each supported language has a messages.json file under src/_locales/{locale}/. At runtime, src/js/i18n.js scans HTML pages for data-i18n attributes and populates them with translated strings from the active locale. If a key is missing in the active locale, the browser falls back to the default_locale (en), as declared in manifest.json.
i18n system: locale files → runtime module → DOM injection
Sources: src/_locales/en/messages.json1-10 src/_locales/de/messages.json1-10 src/_locales/es/messages.json1-10 src/about.html53-64
Each locale directory contains a single messages.json file with a flat key-value structure. Every message entry consists of a unique key and an object containing at minimum a message field and optionally a description field for translator context.
The English locale at src/_locales/en/messages.json serves as the reference implementation and canonical source for all message keys.
Messages are organized by functional area through naming conventions:
| Prefix Pattern | Purpose | Example Keys |
|---|---|---|
ext* | Extension metadata | extName, extShortDesc |
dashboard* | Dashboard UI | dashboardName, dashboardUnsavedWarning |
popup* | Popup panel | popupPowerSwitchInfo, popupBlockedRequestPrompt |
settings* | Settings page | settingsPageName, settingsAdvancedUserPrompt |
3p* | Third-party filter lists | 3pPageName, 3pAutoUpdatePrompt1 |
1p* | User custom filters | 1pPageName, 1pEnableMyFiltersLabel |
rules* | Dynamic filtering rules | rulesPageName, rulesCommit |
whitelist* | Trusted sites | whitelistPageName, whitelistApply |
picker* | Element picker | pickerCreate, pickerContextMenuEntry |
logger* | Request logger | loggerCurrentTab, loggerClearTip |
support* | Support page | supportPageName, supportS1H |
Sources:
Messages can contain placeholders that are replaced with dynamic values at runtime. uBlock Origin uses two substitution formats.
Standard browser API format using $placeholderName$ syntax:
The actual replacement uses the browser's native substitution mechanism via browser.i18n.getMessage('key', [value1, value2]).
uBlock Origin also uses a template syntax with {{variable}} placeholders:
Common placeholder variables:
| Variable | Purpose | Example Value |
|---|---|---|
{{input}} | User input value | 50 (KB size) |
{{count}} | Numeric count | 15 (blocked requests) |
{{percent}} | Percentage | 13 (percent blocked) |
{{total}} | Total count | 100 (total requests) |
{{datetime}} | Timestamp | 2023-12-01_15-30-45 |
{{ago}} | Time elapsed | 2 hours ago |
{{used}} | Used count | 1500 (active filters) |
{{type}} | Resource type | script, image |
{{url}} | URL pattern | example.com |
{{origin}} | Origin hostname | example.com |
Sources:
The browser automatically loads message catalogs based on the user's locale setting. If a message key is missing in the user's locale, the browser falls back to the default_locale specified in manifest.json (English).
HTML elements can be automatically localized using data-i18n attributes:
The extension's initialization code scans for these attributes and replaces the element's text content with the corresponding localized message.
Code can retrieve localized strings programmatically:
uBlock Origin wraps this in a utility function that may be referenced as vAPI.i18n() in various parts of the codebase.
Sources:
Messages without any dynamic content:
Sources:
Messages providing user instructions with keyboard shortcuts:
Note the use of \n\n for paragraph breaks in multi-line messages.
Sources:
Messages combining counts and percentages:
Sources:
Messages that embed input fields for user configuration:
The {{input}} placeholder is replaced by an actual HTML input element when rendered.
Sources:
Messages containing HTML-like formatting or links:
Sources:
Based on edit frequency and maintenance activity:
| Locale Code | Language | Importance Score | Message Count |
|---|---|---|---|
en | English | 105.64 | ~1900 (reference) |
sq | Albanian | 69.82 | ~1900 |
de | German | 62.51 | ~1900 |
es | Spanish | 62.06 | ~1900 |
zh_TW | Chinese (Traditional) | 60.97 | ~1900 |
pt_PT | Portuguese (Portugal) | 57.86 | ~1900 |
id | Indonesian | 57.67 | ~1900 |
pt_BR | Portuguese (Brazil) | 53.75 | ~1900 |
vi | Vietnamese | 53.03 | ~1900 |
nb | Norwegian Bokmål | 51.62 | ~1900 |
The importance score reflects how frequently the translation file is updated, which correlates with active maintenance by translators.
Sources:
The src/_locales/ directory contains 60+ locale subdirectories. The English locale (en) is the reference implementation; all other locales map the same set of message keys with translated message values. Translations are managed through Crowdin (referenced at src/about.html:27).
| Locale Directory | Language |
|---|---|
en | English (reference) |
de | German |
es | Spanish |
fr | French |
zh_CN | Chinese (Simplified) |
zh_TW | Chinese (Traditional) |
pt_PT | Portuguese (Portugal) |
pt_BR | Portuguese (Brazil) |
ru | Russian |
pl | Polish |
nl | Dutch |
fi | Finnish |
sr | Serbian |
sk | Slovak |
ca | Catalan |
Each locale file contains approximately the same number of message keys as the English reference. Missing keys in a non-English locale result in automatic fallback to English via browser.i18n.
Sources: src/_locales/en/messages.json1-10 src/about.html26-28
Required messages for browser store listings:
The extShortDesc has a strict 132-character limit for Chrome Web Store compatibility.
Sources:
Messages specifically for screen readers:
These provide alternative text for visual UI elements to ensure accessibility.
Sources:
Messages that appear in browser context menus:
These must be concise due to limited space in context menus.
Sources:
Messages providing additional context on hover:
Tooltip messages should be brief and action-oriented.
Sources:
The codebase follows consistent patterns for organizing message keys:
Message keys use prefixes to group related functionality:
componentNamePurposeDetails
Examples:
popupTipNoCosmeticFiltering1 - Popup tooltip for cosmetic filtering (enable state)popupTipNoCosmeticFiltering2 - Popup tooltip for cosmetic filtering (disable state)loggerRowFiltererBuiltinBlocked - Logger filter for blocked itemsWhen UI components are redesigned, new message keys may be added with version suffixes:
The _v2 suffix indicates the mobile-friendly redesign.
Sources:
Messages with multiple related variants use numeric suffixes:
The base key describes the general action, while 1 and 2 variants describe specific states.
Sources:
Translations are contributed via Crowdin at https://crowdin.com/project/ublock, as referenced in src/about.html. The resulting messages.json files are committed to src/_locales/{locale}/.
src/_locales/{locale_code}/ using BCP 47 format (e.g., fr, zh_CN)src/_locales/en/messages.jsonmessage field values while preserving:
{{variable}} (e.g., {{count}}, {{input}})<code>, <a>, <b>, etc.\ndata-i18n-annotated elements display correctlyWhen new keys are added to en/messages.json:
browser.i18n)Sources: src/_locales/en/messages.json1-10 src/about.html27 </old_str>
<old_str>
The About page demonstrates typical i18n integration:
Elements with data-i18n attributes are automatically populated when the page loads.
Sources:
UI components retrieve localized strings programmatically:
The browser API handles locale selection, fallback, and placeholder substitution automatically. </old_str> <new_str>
src/about.html illustrates the pattern used across all UI pages. Elements declare their message key via data-i18n, and js/i18n.js (loaded as an ES module) populates their text on page load:
All UI pages (popup, dashboard, logger, element picker) follow this same pattern.
Sources: src/about.html21-28 src/about.html59
UI components retrieve localized strings programmatically via the browser API:
The browser API handles locale selection and fallback to English automatically.
All message files use UTF-8 encoding to support international characters. Special considerations:
Languages like Arabic use RTL text direction, but this is handled at the HTML level via dir="rtl" attribute, not in the message files themselves.
English messages use plural-safe phrasing:
The lowercase "requests" works for both singular and plural contexts.
Some messages have explicit character limits noted in descriptions:
Translators must respect these limits to ensure store listing compatibility.
Sources:
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.