Vue 3 i18n Notes

Recently, I've been working on a front-end project with i18n support, and I'd like to note the steps here.

Step 1: Install dependency

pnpm add vue-i18n@9

As of now, we have no other choice.

Step 2: Create Language Packs

At first, we need to define what a language pack contains:

// src/locales/defines.ts
export type locale = {
    "hello": string,
    "stateOrProvinceName": string
}

Secondly, create our language pack:

// src/locales/zh-CN.ts
import { locale } from "./defines";

export default {
    "hello": "你好",
    "stateOrProvinceName": "州省名称"
} as locale

At last, store all of them in a single file:

// src/utils/i18n.ts
import zhCN from '../locales/zh-CN'
import enUS from '../locales/en-US'

const messages = {
    "zh-CN": zhCN,
    "en-US": enUS
}

Step 3: Use in Vue SFC

At this point, you have only defined the language pack, to use it you need to register the plugin first:

// src/utils/i18n.ts
import { createI18n } from 'vue-i18n'
import { langEnum, locale } from '../locales/defines'

export const i18n = createI18n({
    locale: navigator.language.startsWith("zh") ? "zh-CN" : "en-US",
    messages
})

Note the locales here, where you need to define the logic for selecting language packs. As my requirements here are simple, use Chinese when the user language is Chinese, otherwise always use English, in many cases this is not enough and you need to customize your logic yourself.

Use the Vue plugin:

// main.ts
import { createApp } from "vue";
import { i18n } from './util/i18n'

createApp()
    .use(i18n)
    .mount("#app")

Now you can use $t() in the Vue template to get the string for the current language:

<template>
    <p>{{ $t('hello') }}</p>
</template>

It will be rendered as:

<p>你好</p>

However not all the text is defined in the template, this is not enough.

Step 4: Use in TypeScript

Edit src/util/i18n.ts:

import { langEnum, locale } from '../locales/defines'

export const t = (query: keyof locale) => {
    let currLang: langEnum = navigator.language in messages
        ? navigator.language as langEnum
        : "en-US"
    return messages[currLang][query]
}

Usage:

console.log(t('hello')) // 你好

All done. Enjoy your i18n-ready application!