-
-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: New
@wxt-dev/i18n
package (#758)
- Loading branch information
Showing
30 changed files
with
2,002 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Internationalization | ||
|
||
This guide is for using the vanilla, `browser.i18n` APIs. There are two other alternatives: | ||
|
||
1. [`@wxt-dev/i18n`](/guide/i18n/installation) - a wrapper around `browser.i18n` APIs with additional features, a simplified localization file format, and editor support | ||
2. Third party packages - You can use any i18n package on NPM, most of which are more feature rich than `browser.i18n` and `@wxt-dev/i18n` | ||
|
||
:::info | ||
Currently, using the `browser.i18n` APIs are the recommended approach. WXT has some built-in support for them and they work well enough. `@wxt-dev/i18n` was recently released, and it will become the recommended approach after some of the bugs have been worked out. Head over to [it's docs](/guide/i18n/introduction.md) to learn more. | ||
::: | ||
|
||
## Setup | ||
|
||
First familiarize yourself with [Chrome's docs](https://developer.chrome.com/docs/extensions/reference/api/i18n). The only difference when using these APIs with WXT is where you put the localization files - in the [`public` directory](/guide/directory-structure/public/). | ||
|
||
``` | ||
<srcDir>/ | ||
└─ public/ | ||
└─ _locales/ | ||
├─ en/ | ||
│ └─ messages.json | ||
├─ de/ | ||
│ └─ messages.json | ||
└─ ko/ | ||
└─ messages.json | ||
``` | ||
|
||
Next, to set a `default_locale` on your manifest, add it to your `wxt.config.ts` file: | ||
|
||
```ts | ||
// wxt.config.ts | ||
export default defineConfig({ | ||
manifest: { | ||
default_locale: 'en', | ||
name: '__MSG_extName__', | ||
description: '__MSG_extDescription__', | ||
}, | ||
}); | ||
``` | ||
|
||
> You can localize the `name` and `description` of your extension from the `manifest` config as well. | ||
Finally, to get a translation, call `browser.i18n.getMessage`: | ||
|
||
```ts | ||
browser.i18n.getMessage('extName'); | ||
browser.i18n.getMessage('extDescription'); | ||
browser.i18n.getMessage(/* etc */); | ||
``` | ||
|
||
## Examples | ||
|
||
See the official localization examples for more details: | ||
|
||
- [I18n](https://github.com/wxt-dev/wxt-examples/tree/main/examples/vanilla-i18n#readme) | ||
- [Vue I18n](https://github.com/wxt-dev/wxt-examples/tree/main/examples/vue-i18n#readme) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Build Integrations | ||
|
||
To use the custom messages file format, you'll need to use `@wxt-dev/i18n/build` to transform the custom format to the one expected by browsers. | ||
|
||
Here's a list of build tools that already have an integration: | ||
|
||
[[toc]] | ||
|
||
:::info | ||
If you want to contribute, please do! In particular, an `unplugin` integration would be awesome! | ||
::: | ||
|
||
## WXT | ||
|
||
See [Installation with WXT](./installation#with-wxt). | ||
|
||
But TLDR, all you need is: | ||
|
||
```ts | ||
// wxt.config.ts | ||
export default defineConfig({ | ||
modules: ['@wxt-dev/i18n/module'], | ||
}); | ||
``` | ||
|
||
Types are generated whenever you run `wxt prepare` or another build command: | ||
|
||
```sh | ||
wxt prepare | ||
wxt | ||
wxt build | ||
wxt zip | ||
# etc | ||
``` | ||
|
||
## Custom | ||
|
||
If you're not using WXT, you'll have to pre-process the localization files yourself. Here's a basic script to generate the `_locales/.../messages.json` and `wxt-i18n-structure.d.ts` files: | ||
|
||
```ts | ||
// build-i18n.js | ||
import { | ||
parseMessagesFile, | ||
generateChromeMessagesFile, | ||
generateTypeFile, | ||
} from '@wxt-dev/i18n/build'; | ||
|
||
// Read your localization files | ||
const messages = { | ||
en: await parseMessagesFile('path/locales/en.yml'), | ||
de: await parseMessagesFile('path/locales/de.yml'), | ||
// ... | ||
}; | ||
|
||
// Generate JSON files for the browser | ||
await generateChromeMessagesFile('dist/_locales/en/messages.json', messages.en); | ||
await generateChromeMessagesFile('dist/_locales/de/messages.json', messages.de); | ||
// ... | ||
|
||
// Generate a types file based on your default_locale | ||
await generateTypeFile('wxt-i18n-structure.d.ts', messages.en); | ||
``` | ||
|
||
Then run the script: | ||
|
||
```sh | ||
node generate-i18n.js | ||
``` | ||
|
||
If your build tool has a dev mode, you'll also want to rerun the script whenever you change a localization file. | ||
|
||
### Type Safety | ||
|
||
Once you've generated `wxt-i18n-structure.d.ts` (see the [Custom](#custom) section), you can use it to pass the generated type into `createI18n`: | ||
|
||
```ts | ||
import type { WxtI18nStructure } from './wxt-i18n-structure'; | ||
|
||
export const i18n = createI18n<WxtI18nStructure>(); | ||
``` | ||
|
||
And just like that, you have type safety! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Editor Support | ||
|
||
For better DX, you can configure your editor with plugins and extensions. | ||
|
||
[[toc]] | ||
|
||
## VS Code | ||
|
||
Install the [I18n Ally Extension](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally) to: | ||
|
||
- Go to translation definition | ||
- Inline previews of text | ||
- Hover to see other translations | ||
|
||
You'll need to configure it the extension so it knows where your localization files are and what function represents getting a translation: | ||
|
||
`.vscode/i18n-ally-custom-framework.yml`: | ||
|
||
```yml | ||
# An array of strings which contain Language Ids defined by VS Code | ||
# You can check available language ids here: https://code.visualstudio.com/docs/languages/identifiers | ||
languageIds: | ||
- typescript | ||
|
||
# Look for t("...") | ||
usageMatchRegex: | ||
- "[^\\w\\d]t\\(['\"`]({key})['\"`]" | ||
|
||
# Disable other built-in i18n ally frameworks | ||
monopoly: true | ||
``` | ||
`.vscode/settings.json`: | ||
|
||
```json | ||
{ | ||
"i18n-ally.localesPaths": ["src/locales"], | ||
"i18n-ally.keystyle": "nested" | ||
} | ||
``` | ||
|
||
## Zed | ||
|
||
As of time of writing, Aug 18, 2024, no extensions exist for Zed to add I18n support. | ||
|
||
## IntelliJ | ||
|
||
Unknown - Someone who uses IntelliJ will have to open a PR for this! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# Installation | ||
|
||
[[toc]] | ||
|
||
### With WXT | ||
|
||
1. Install `@wxt-dev/i18n` via your package manager: | ||
|
||
```sh | ||
pnpm i @wxt-dev/i18n | ||
``` | ||
|
||
2. Add the WXT module to your `wxt.config.ts` file and setup a default locale: | ||
|
||
```ts | ||
export default defineConfig({ | ||
modules: ['@wxt-dev/i18n/module'], | ||
manifest: { | ||
default_locale: 'en', | ||
}, | ||
}); | ||
``` | ||
|
||
3. Create a localization file at `<srcDir>/locales/<default_locale>.yml` or move your existing localization files there. | ||
|
||
```yml | ||
# <srcDir>/locales/en.yml | ||
helloWorld: Hello world! | ||
``` | ||
|
||
:::tip | ||
`@wxt-dev/i18n` supports the standard messages format, so if you already have localization files at `<srcDir>/public/_locale/<lang>/messages.json`, you don't need to convert them to YAML or refactor them - just move them to `<srcDir>/locales/<lang>.json` and they'll just work out of the box! | ||
::: | ||
|
||
4. To get a translation, use the auto-imported `i18n` object or import it manually: | ||
|
||
```ts | ||
import { i18n } from '#i18n'; | ||
i18n.t('helloWorld'); // "Hello world!" | ||
``` | ||
And you're done! Using WXT, you get type-safety out of the box. | ||
### Without WXT | ||
1. Install `@wxt-dev/i18n` via your package manager: | ||
```sh | ||
pnpm i @wxt-dev/i18n | ||
``` | ||
2. Create a messages file at `_locales/<lang>/messages.json` or move your existing translations there: | ||
```json | ||
{ | ||
"helloWorld": { | ||
"message": "Hello world!" | ||
} | ||
} | ||
``` | ||
:::info | ||
For the best DX, you should to integrate `@wxt-dev/i18n` into your build process. This enables: | ||
1. Plural forms | ||
2. Simple messages file format | ||
3. Type safety | ||
See [Build Integrations](./build-integrations) to set it up. | ||
::: | ||
3. Create the `i18n` object, export it, and use it wherever you want! | ||
```ts | ||
import { createI18n } from '@wxt-dev/i18n'; | ||
export const i18n = createI18n(); | ||
i18n.t('helloWorld'); // "Hello world!"; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Introduction | ||
|
||
:::info | ||
You don't have to use `wxt` to use this package - it will work in any bundler setup. See [Installation without WXT](./installation#without-wxt) for more details. | ||
::: | ||
|
||
`@wxt-dev/i18n` is a simple, type-safe wrapper around the `browser.i18n` APIs. It provides several benefits over the standard API: | ||
|
||
1. Simple messages file format | ||
2. Plural form support | ||
3. Integrates with the [I18n Ally VS Code extension](./editor-support#vscode) | ||
|
||
It also provides several benefits over other non-web extension specific i18n packages: | ||
|
||
1. Does not bundle localization files into every entrypoint | ||
2. Don't need to fetch the localization files asynchronously | ||
3. Can localize extension name in manifest | ||
4. Can access localized strings inside CSS files | ||
|
||
However, it does have one major downside: | ||
|
||
1. Like the `browser.i18n` API, to change the language, users must change the browser's language |
Oops, something went wrong.