A tool to manage i18n by extracting keys from source code and generating locale files.
Create a module that exports a function that returns the current locale. This function will be used to determine the locale of generated files. The path to this module must be specified in the generate.localeLocatorPath
parameter of the configuration file. Depending on the configuration of your project (appType
parameter), the implementation of the function will be different (for example, a Vue project may need to use reactivity, while a vanilla project may need to return a simple string).
import type { UseLocaleLocator } from "@restar-inc/re-i18n/lib/vendor/vue";
import { computed, ref } from "vue";
type Locale = "ja" | "en";
const innerLocale = ref<Locale>("ja");
const useLocaleLocator: UseLocaleLocator<Locale> = (locales, defaultLocale) => {
return computed({
get: () => innerLocale.value,
set: (value) => {
if (locales.includes(value)) {
innerLocale.value = value;
} else {
innerLocale.value = defaultLocale;
}
},
});
};
export default useLocaleLocator;
If you need to format translations, create a module that exports a function that takes a key and a value as parameters and returns a formatted string. The path to this module must be specified in the generate.formatterPath
parameter of the configuration file.
import formatString from "my-amazing-formatter-lib"; // just an example
import type { I18nFormatter } from "@restar-inc/re-i18n";
type Locale = "ja" | "en";
const fmt: I18nFormatter<Locale> = (locale, str, opts) => {
return formatString(str, opts, locale);
};
export default fmt;
Create a re-i18n.config.json
file in the root of your project. Follow the example below to configure it. Refer to the ./src/schemas/config.ts
file for details.
{
"defaultLocale": "ja",
"locales": ["ja", "en"],
"appType": "vue",
"pattern": "src/{app,lib}/**/*.{ts,vue}",
"json": {
"outDir": "./out/json"
},
"csv": {
"outDir": "./out/csv",
"inputDir": "./out/csv",
"delimiter": ";"
},
"xls": {
"outDir": "./out/xls",
"inputDir": "./out/xls"
},
"generate": {
"localeLocatorPath": "./src/i18n/useLocateLocator",
"formatterPath": "./src/i18n/formatter"
}
}
After following the previous steps, you can use the t
function to define translation keys in your source code. You can use a different name for the function by setting the funcName
parameter in the configuration file.
Let's suppose you have the following code:
// src/lib/myAwesomeModule.ts
function sayHello(name: string) {
return `こんにちわ${name}さん`;
}
// src/lib/MyAwesomeComponent.vue
<script setup lang="ts">
const props = defineProps({
name: String,
});
const showAlert = () => alert(`おはようございます${props.name}さん`);
</script>
<template>
<button @click="showAlert">こんばんは</button>
</template>
Set the keys as follows:
// src/MyAwesomeModule/hello.ts
function sayHello(name: string) {
return t("こんにちわ{name}さん", { name });
}
// src/MyAwesomeModule/Component.vue
<script setup lang="ts">
const props = defineProps({
name: String,
});
const showAlert = () => alert(
t("おはようございます{name}さん", { name: props.name })
);
</script>
<template>
<button @click=showAlert>{{ t("こんばんは") }}</button>
</template>
Next step is to run comman re-i18n generate
. This will generate locale files in the out
directory.
src/MyAwesomeModule
├── Component.vue
├── hello.ts
└── locales
├── en.json
├── index.ts
└── ja.json
// src/MyAwesomeModule/locales/en.json
{
"おはようございます{name}さん": "",
"こんにちわ{name}さん": "",
"こんばんは": ""
}
// src/MyAwesomeModule/locales/ja.json
{
"おはようございます{name}さん": "",
"こんにちわ{name}さん": "",
"こんばんは": ""
}
Next step is to import t
function from locale
folder:
// src/MyAwesomeModule/hello.ts
import { t } from "./locales";
...
// src/MyAwesomeModule/Component.ts
<script setup lang="ts">
import { t } from "./locales";
...
</script>
Now you can put the translations in the locale files.
For more details, see the example directory.
By default, the translation function returns a string. If you want to use reactivity, you can use the composable function useReI18n
or its shortcut t.$
.
// re-i18n.config.json
{
"funcName": "t",
"composableName": "useMyReI18n" // default `useReI18n`
}
// Component.vue
<script setup lang="ts">
import { t, useMyReI18n } from "./locales";
const MSG_1 = t("メッセージ 1"); // MSG_1 is `string`
const MSG_2 = t.$("メッセージ 2"); // MSG_2 is `ComputedRef<string>`
const MSG_3 = useMyReI18n("メッセージ 3"); // MSG_3 is `ComputedRef<string>`
</script>
NOTE:
t.$
is just a shortcut foruseReI18n
, it works exactly the same way. A typical use in the<script setup>
section is to uset.$
in nested object fields:
// Instead of this
import { t, useMyReI18n } from "./locales";
const msg1 = useMyReI18n("メッセージ 1");
const msg2 = useMyReI18n("メッセージ 2");
const MESSAGES = {
msg1,
msg2,
};
// You can do this
const MESSAGES = {
msg1: t.$("メッセージ 1"),
msg2: t.$("メッセージ 2"),
};
IMPORTANT: If you use
t.$
inside object fields, such asconst obj = { msg: t.$("message") }
, reactivity will work, but you will have to manually unwrap the value withobj.msg.value
. This is not related to this package, but is a limitation of Vue.
<script setup lang="ts">
import { t } from "./locales";
const MSG_1 = t.$("メッセージ 1");
const MSG_2 = {
msg: t.$("メッセージ 2");
}
</script>
<template>
<p>{{ MSG_1 }}</p><!-- メッセージ 1 -->
<p>{{ MSG_2.msg }}</p><!-- "メッセージ 2" -->
<p>{{ MSG_2.msg.value }}</p><!-- メッセージ 2 -->
</template>
You can also use vendor specific features. For example, if you are using Vue, you can use the ReI18n
component to display translation keys in source code and use VDOM nodes as parameters.
IMPORTANT: If you use
t
inside child nodes, reactivity will not work
First you need to specify the component name in the configuration file.
{
"componentName": "MyI18n" // default `ReI18n`
}
Then you can use it in your source code.
<script setup lang="ts">
import { MyI18n } from "./locales";
</script>
<template>
<MyI18n msg="赤い:{0} 緑:{1} 青い:{2}">
<div class="bg-red-400 w-10 h-10 rounded-full"></div>
<div class="bg-green-400 w-10 h-10 rounded-full"></div>
<div class="bg-blue-400 w-10 h-10 rounded-full"></div>
</MyI18n>
</template>
Depending on your project configuration (funcName
param),
This package provides the CLI command re-i18n
. Run it in the root of your project.
re-i18n --help
Generates locale files from source code. Uses the pattern
and appType
parameters defined in the configuration file to parse the source code, read the i18n keys, generate the i18n files, and write them to the dirName
directory. It also uses the generator.localeLocatorPath
and generator.formatterPath
functions defined in the config file to generate the main module in each locale directory.
Creates a JSON file from the source code and the i18n keys found. This is essentially an AST representation of the code used to generate i18n files. It is not intended for direct use.
For each language, a CSV file is created from the source code and the i18n keys found.
Creates an XLS file from the source code and the i18n keys found.
For each locale, it will read the CSV file and overwrite the i18n files with the new values.
Reads the XLS file and overwrites the i18n files with the new values.
Displays statistics on the number of keys in each locale.
Checks for missing and obsolete keys in the source code and i18n files.