Localization
WXT includes a util, i18n, that provides a type-safe feature-rich alternative to browser.i18n.getMessage.
It is available automatically when you create a messages file under the locales/ directory, and add a default_locale to the manifest:
<srcDir>
└─ locales/
├─ en.json
├─ es.json5
├─ fr.yml
├─ de.yaml
└─ ...You can use JSON, JSON5, or YAML formats.
// wxt.config.ts
export default defineConfig({
manifest: {
default_locale: 'en',
},
});Message File Format
# Use plain strings
simpleMessage: Hello world!
# Nest strings in objects
popup:
overview:
title: Nested text
# Plural form support
items:
1: 1 item
n: $1 items
# Optionally include a custom string for 0
cartSize:
0: Empty
1: 1 item
n: $1 items
# Or stick with the standard web extension format (with a message, description, and placeholders)
manifestMessage:
message: $THIS$ is translated
description: This is not-translated, helps translators
placeholder:
this:
content: ThisTIP
locales/<code>.json is 100% compatible with the standard web extension localization format (_locales/<code>/messages.json). If you have existing messages files, just move them into the locales/ directory.
Usage
i18n is auto-imported, but can be manually imported from wxt/i18n.
import { i18n } from 'wxt/i18n';Basic Usage
You can access messages by their name:
helloWorld: Hello world!i18n.t('helloWorld'); // "Hello world!"Nested messages are combined into one string using an _.
popup:
overview:
title: Hello world!i18n.t('popup_overview_title'); // "Hello world!"If a message is in the standard web extension format, don't include a _message, even if it's nested.
helloWorld:
message: Hello world!
description: Some description
popup:
overview:
title:
message: Nested Titlei18n.t('helloWorld'); // "Hello world!"
i18n.t('popup_overview_title'); // "Nested Title"Substitutions
To insert a custom string into a translation, pass an array of values as the second parameter of the i18n.t function:
hello: Hello, $1, my name is $2.i18n.t('hello', ['Aaron', 'Mark']); // "Hello Aaron, my name is Mark."Plural Form
When getting the translation for text with a plural form, use the i18n.tp function.
friends:
0: I have no friends.
1: I have a friend.
n: I have many friends.i18n.tp('friends', 0); // "I have no friends."
i18n.tp('friends', 1); // "I have one friend."
i18n.tp('friends', 2); // "I have many friends."The first number is the count. It is what decides which form will be used.
Substitutions are not required. But usually, a plural form will look something like this:
items:
1: 1 item
n: $1 itemsi18n.tp('items', 0, ['0']); // "0 items"
i18n.tp('items', 1, ['1']); // "1 item"
i18n.tp('items', 2, ['2']); // "2 items"
i18n.tp('items', 3, ['3']); // "3 items"