A Simple Way To Internationlize Your VS Code Extension
Tags: vscode, i18n, extension
Published: 2020-04-06 10:46:08

For a good vscode Extension, it is a bad thing if it does not support i18n. This article introduces a simple i18n approach, hoping that it will be helpful to Extension developers.

Here, we will borrow some code from another famous Extension ([code-settings-sync](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync)), please read on, :).

Let's demonstrate it with a simple Extension project. For VS Code language setting:

- In the case of Chinese, the command name is in Chinese, and the message notification box that pops up after entering the command is also in Chinese.
- Correspondingly, in the case of English, the above items are also in English.

For those familiar with Extension development, this is actually a project generated by Yeoman Extension generator, just with i18n support.

## Create project and add publisher

First, create an Extension project.

```shell
yo code
```

Suppose the Extension project is named: i18n, go to the project directory, add publisher in package.json, for example.

```json
"publisher": "dteam",
```

## Copy localize.ts

Next, copy [localize.ts](https://github.com/shanalikhan/code-settings-sync/blob/master/src/localize.ts) from code-settings-sync project to the src directory while searching for "rootPath = extensions.getExtension ..." and replace it with the following code:

```typescript
rootPath = extensions.getExtension("dteam.i18n")? .extensionPath;
```

Where `dteam.i18n` is the id of current Extension, and its format is: `publisher.name`. At this point, the infrastructure part of i18n is ready, and the next step is to write the corresponding language package.

## Edit language packages

Basically, i18n works on the same principle, using the language-independent message_id in the program, then judging the language of the current environment at runtime, loading the corresponding language package, and finally replacing the message_id with the actual content.

Here, the language package is placed in the project root, at the same level as package.json. And the language package format is: **package.nls{0}.json**. Corresponding language packs in both English and Chinese, with the following names and contents.

- package.nls.json, English

```json
{
  "extension.helloWorld.title": "Greet",
  "extension.helloWorld.message": "Hello, world!"
}
```

- package.nls.zh-cn.json, Chinese

```json
{
  "extension.helloWorld.title": "问候",
  "extension.helloWorld.message": "你好，世界！"
}
```

## Use message id

Next, use message id to replace the display content to complete internationalization. There are two places.

- command name, modify package.json

```json
{
  "command": "extension.helloWorld",
  "title": "%extension.helloWorld.title%"
}
```

- Message notification, change extension.ts

```typescript
vscode.window.showInformationMessage(localize("extension.helloWorld.message"));
```

## Run

Running and switching languages will see actual results.

## Finally

Since [code-settings-sync](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync) itself is licensed as MIT, there is no problem copying the code to use in the project. At the same time, since it already has well-developed internationalization features (e.g. support for messaging parameters), it is easiest to copy it and use it directly.

While it is necessary to change the ID of the Extension in [localize.ts](https://github.com/shanalikhan/code-settings-sync/blob/master/src/localize.ts) every time it is used, as far as I can see this is actually the easiest way to do it. While it is possible to pass `context` to dynamize the Extension directory, this also results in the need to pass in parameters during initialization, which is not as simple and easy to use as it is now. And, considering the fact that the source code is copied and reused here, it's tolerable to change the code directly to another place for easy of use.

Finally, if you've adopted [gts](https://github.com/google/gts) as we have, then remember to exclude `src/localize.ts` from lint checking in `tslint.json`, because there's no point in checking it for code that's already imported from external engineering.

---

PS: This article is an experiment with [DeepL](https://www.deepl.com/en/translator) which did most part of translation from [its original Chinese version](https://blog.dteam.top/posts/2020-03/vscode-extension-i18n.html). I want to see how it is good at its job, do you like it, ;)?