Configuration
Project settings live in one config file. The CLI, the editor and the UI read the same file, so they always agree. Editor settings change only the editor experience. They never override the config.
Config files
x18n looks for these file names, in this order. The first match wins:
x18n.config.tsx18n.config.mtsx18n.config.jsx18n.config.mjsx18n.config.ymlx18n.config.yamlx18n.config.json
The CLI starts in the current directory and goes up through the parent directories. It stops at the first config file, or at the directory that holds .git. Two options change the search:
--root <dir>looks only in<dir>, and uses it as the project root.--config <file>uses that file.
Without a config file, x18n reads the project's i18n-ally settings (i18n-ally.* in .vscode/settings.json, and .vscode/i18n-ally-custom-framework.yml), so an i18n-ally project works with no changes. The settings act as defaults: detection still adds what they leave out, and when their locale paths match no file, x18n looks for locale directories itself. Without i18n-ally settings either, x18n runs on detection alone. x18n doctor prints what it uses: the config file, .vscode/settings.json, or none (detection only).
Detection reads the dependencies of the project's package.json, of the parent directories up to the git root, and of the workspace packages listed in pnpm-workspace.yaml or the workspaces field, so a monorepo that lists the i18n library in one app is detected from its root.
TypeScript
x18n.config.ts is the main format. defineConfig gives types and completion. The presets are in @x18n/cli/presets:
import { vueI18n } from '@x18n/cli/presets'
import { defineConfig } from '@x18n/core'
export default defineConfig({
sourceLocale: 'en',
presets: [vueI18n()],
resources: [{ pattern: 'src/locales/{locale}.json' }],
checks: {
'unused-key': 'error',
},
})The default export can also be a function that returns the config, or a promise of it.
YAML and JSON
YAML and JSON configs suit projects without Node dependencies, such as PHP, Ruby or Flutter projects. They hold the same options, except plugin objects. Presets and plugins are strings: a built-in preset name, a package name or a path.
# yaml-language-server: $schema=https://x18n.antfu.dev/schema/config.json
sourceLocale: en
presets: [vue-i18n]
plugins:
- ./x18n/acme.x18n-plugin.yml
resources:
- pattern: 'src/locales/{locale}.json'{
"$schema": "https://x18n.antfu.dev/schema/config.json",
"sourceLocale": "en",
"presets": ["vue-i18n"],
"resources": [{ "pattern": "src/locales/{locale}.json" }]
}The $schema line gives validation and completion in the editor. x18n schema config prints the same JSON Schema.
x18n validates every config against this schema, the serializable part of a TS config too. An unknown key is an error (X18N0001), so a typo in a key name does not pass silently.
Locale files
A resource is a file, or a block in a file, that holds the messages of one locale and one namespace. The resources option tells x18n where the resources are. Each entry has a path pattern, relative to the project root:
| Token | Matches |
|---|---|
{locale} | The locale code, as written in the path: en, zh_CN, pt-BR. |
{locale?} | An optional locale. A file without it belongs to the source locale. |
{namespace} | One path segment that names the namespace. |
{namespaces} | One or more path segments. a/b.json becomes the namespace a.b. |
{ext} | The extension of any registered format: json, jsonc, json5, yml, yaml, po, pot, properties, ftl, ini, php, js, mjs, cjs, ts, mts, cts. |
*, ** | Globs. |
Some examples:
| Layout | Pattern |
|---|---|
locales/en.json | locales/{locale}.json |
locales/en/common.json | locales/{locale}/{namespace}.json |
public/locales/en/pages/home.json | public/locales/{locale}/{namespaces}.json |
A pattern without {locale}, such as package.nls.json, holds the source locale. To give its files another locale, set locale:
import { defineConfig } from '@x18n/core'
export default defineConfig({
resources: [
{ pattern: 'webapp/i18n/i18n_{locale}.properties' },
{ pattern: 'webapp/i18n/i18n.properties', locale: 'en' },
],
})Without resources, the presets add their usual paths. The paths of all applied presets add up. If they match nothing, x18n looks for directories named locales, locale, i18n, lang, langs, language, languages, translations, messages, _locales or l10n, and guesses the pattern from the files in them.
x18n uses locale codes exactly as written. It does not change zh_CN to zh-CN. If two codes differ only in spelling, the locale-code-conflict check reports them.
Presets
A preset is a group of plugins for one i18n library. The default is presets: 'auto': x18n runs the detection of every built-in preset against the dependencies in package.json, composer.json, pubspec.yaml and Gemfile. The manifests in the parent directories, up to the git root, count too. In a monorepo, this finds the dependencies of the workspace root.
If you list presets, x18n applies exactly the listed presets and detects none:
import { i18next } from '@x18n/cli/presets'
import { defineConfig } from '@x18n/core'
export default defineConfig({
presets: [i18next()],
})presets: [] turns every preset off. See Presets for the list.
How x18n merges the config
x18n builds the final config of a project in this order. A later layer wins:
- The defaults of x18n.
- The
confighooks of plugins and presets. Presets set defaults here, for example the call specs of their library. - The root config of a monorepo, if there is one. See Monorepos.
- The config of the project.
How a layer changes a value depends on the option:
- Single values (
sourceLocale,keyStyle,strict) replace the earlier value. locales,resourcesandusage.includereplace the earlier list.- Lists of rules add to the earlier list:
ignoreLocales,ignoreKeys,glossary,usage.exclude,usage.calls,usage.regex,usage.ignoreCallees,usage.keysInUse,usage.derivedKeysandextract.templates. - Objects merge key by key:
formats,checks,namespace,writeandextract.
x18n doctor lists the origin of each value: default, user, parent, or plugin:<name>.
Next steps
- Config reference: every option, with its type and default.
- Concepts: resources, keys, namespaces and usages.