Localization and Internationalization (i18n) System in Markdown Here
Markdown Here leverages the native Chrome Extension i18n API, storing locale-specific strings in JSON bundles under src/_locales/ and retrieving them at runtime via a thin wrapper around chrome.i18n.getMessage() located in src/common/utils.js.
The open-source Markdown Here extension renders Markdown in any web text field, and its localization and internationalization (i18n) system relies entirely on the WebExtension platform's built-in capabilities rather than third-party libraries. According to the source code in adam-p/markdown-here, the implementation uses standard Chrome extension patterns including manifest declarations, __MSG_ placeholders, and locale-specific message bundles to support multiple languages including Traditional Chinese, Korean, and Japanese.
Manifest Configuration and Default Locale
In src/manifest.json, the extension declares "default_locale": "en" to establish English as the fallback language when a user's browser preference isn't available. This manifest also leverages the __MSG_<id>__ placeholder syntax for user-visible metadata such as the extension name and description, which Chrome automatically substitutes with strings from the appropriate locale bundle.
The manifest registration follows this pattern:
{
"name": "__MSG_extension_name__",
"description": "__MSG_extension_description__",
"default_locale": "en"
}
Locale Bundle Structure and Storage
Each supported language resides in its own directory under src/_locales/<locale>/ with a single messages.json file containing the translated strings. This structure follows the standard Chrome extension i18n schema.
For example, Traditional Chinese translations live in src/_locales/zh_TW/messages.json, while Korean and Japanese translations are stored in src/_locales/ko/messages.json and src/_locales/ja/messages.json respectively. Each entry follows this structure:
{
"toggle_button_tooltip": {
"message": "點擊來切換Markdown算繪模式",
"description": "Tooltip for the toolbar button"
}
}
Runtime Message Retrieval and Error Handling
The codebase accesses localized strings through a centralized utility function rather than calling the Chrome API directly. In src/common/utils.js, the getMessage(messageID) function wraps chrome.i18n.getMessage() to provide consistent error handling.
// src/common/utils.js
function getMessage(messageID) {
const message = chrome.i18n.getMessage(messageID);
if (!message) {
throw new Error('Could not find message ID: ' + messageID);
}
return message;
}
This design ensures that missing translation keys trigger explicit runtime errors rather than silent failures, making development and debugging more straightforward. When retrieving the toggle button tooltip, the code calls:
const tooltip = getMessage('toggle_button_tooltip');
// Returns: "點擊來切換Markdown算繪模式" when UI language is Traditional Chinese
Adding New Translations to the Codebase
To add support for new UI text within the Markdown Here localization and internationalization (i18n) system, developers must follow three steps:
- Add the translation entry to every language's
messages.jsonfile undersrc/_locales/<locale>/ - If the string appears in the manifest, use the
__MSG_<id>__placeholder syntax insrc/manifest.json - Retrieve the string in JavaScript using
getMessage('<id>')
For UI elements that appear in HTML files like src/common/options.html, use the __MSG_<id>__ syntax directly in the markup, and Chrome will automatically substitute the appropriate localized string when the page loads.
Summary
- Markdown Here uses the native Chrome Extension i18n API exclusively, requiring no external dependencies like i18next or react-intl.
- Translations are stored in
src/_locales/<locale>/messages.jsonwith adefault_localeof"en"declared insrc/manifest.json. - Runtime access occurs through
getMessage()insrc/common/utils.js, which wrapschrome.i18n.getMessage()and throws errors for missing keys to prevent silent failures. - UI strings in the manifest and HTML use
__MSG_placeholders, allowing Chrome to substitute localized content automatically before the extension loads.
Frequently Asked Questions
Does Markdown Here use external i18n libraries like i18next?
No, the project relies purely on the Chrome Extension i18n API built into the WebExtension platform. According to the source code analysis, there are no third-party internationalization libraries in the dependency tree; all localization logic is handled through native chrome.i18n methods and JSON locale bundles in the src/_locales/ directory.
How does Markdown Here handle missing translations?
The getMessage() wrapper in src/common/utils.js implements strict error handling by throwing a runtime error when chrome.i18n.getMessage() returns an empty or undefined value. This behavior ensures developers immediately notice missing translation keys during development rather than allowing silent failures to reach production.
Where are the translation files located in the repository?
Translation files are located in the src/_locales/ directory, with each locale having its own subdirectory (such as zh_TW/, ko/, or ja/) containing a messages.json file. The manifest file at src/manifest.json references these through the default_locale field and __MSG_ placeholders for extension metadata.
What happens if a user's browser language isn't supported?
Chrome automatically falls back to the default_locale specified in the manifest, which is set to "en" (English) in src/manifest.json. If a specific message key exists in the default locale but not in the user's preferred language, Chrome displays the English version; if the key is missing entirely from all locale files, the getMessage() wrapper throws an error to alert developers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →