Presets
A preset is a group of plugins for one i18n library. It tells x18n which calls are translate calls, how namespaces work, which placeholder syntax the messages use, and which code replaces a hard string.
| Preset | Library | Detected from |
|---|---|---|
nuxt-i18n | @nuxtjs/i18n | @nuxtjs/i18n, nuxt-i18n |
vue-i18n | vue-i18n | vue-i18n, vuex-i18n, petite-vue-i18n, vue-i18n-bridge, @intlify/* |
fluent-vue | fluent-vue | fluent-vue, fluent-vue-loader, rollup-plugin-fluent-vue, unplugin-fluent-vue |
i18next-shopify | i18next-shopify | @shopify/i18next-shopify |
react-i18next | react-i18next | react-i18next, next-i18next |
next-translate | next-translate | next-translate |
next-international | next-international | next-international |
i18next | i18next | i18next |
next-intl | next-intl | next-intl, use-intl |
react-intl | react-intl (FormatJS) | react-intl, @formatjs/* |
svelte-i18n | svelte-i18n, sveltekit-i18n | svelte-i18n, sveltekit-i18n, @sveltekit-i18n/base |
solid-primitives-i18n | @solid-primitives/i18n | @solid-primitives/i18n |
paraglide | Paraglide JS | @inlang/paraglide-js, @inlang/paraglide-sveltekit, @inlang/paraglide-next, @inlang/paraglide-astro, @inlang/paraglide-vite |
ngx-translate | ngx-translate | @ngx-translate/core |
transloco | Transloco | @jsverse/transloco, @ngneat/transloco |
lingui | Lingui | @lingui/core, @lingui/react, @lingui/macro |
ember-intl | ember-intl | ember-intl |
polyglot | Polyglot.js | node-polyglot |
globalize | Globalize | globalize |
i18n-tag | es2015-i18n-tag | es2015-i18n-tag |
i18n-js | i18n-js | i18n-js |
ui5 | SAPUI5, OpenUI5 | @ui5/cli |
chrome-extension | Chrome and WebExtension i18n | default_locale in manifest.json, src/manifest.json or public/manifest.json |
vscode-extension | VS Code extension API | vscode, @types/vscode |
laravel | Laravel | laravel/framework in composer.json |
php-joomla | Joomla | joomla/application, joomla/cms in composer.json |
php-gettext | gettext in PHP | never: list it in presets |
ruby-rails | Ruby on Rails | rails, rails-i18n, railties in Gemfile |
jekyll | jekyll-multiple-languages-plugin | jekyll-multiple-languages-plugin in Gemfile |
flutter | flutter_i18n | flutter_i18n in pubspec.yaml |
general | none | always |
Detection
With the default presets: 'auto', x18n tests each preset in the order of the table. Most presets apply when the project depends on one of the listed packages. x18n reads the dependencies, dev dependencies and peer dependencies in package.json, and the dependencies in composer.json, pubspec.yaml and Gemfile. The manifests in the parent directories, up to the git root, count too.
More than one preset can apply. Some presets include the plugins of another preset: react-i18next includes everything of i18next, and i18next-shopify includes everything of react-i18next. When two applied presets share a plugin, x18n adds that plugin one time.
A preset can be exclusive. When an exclusive preset applies, x18n tests no preset after it. laravel and php-gettext are exclusive. php-gettext has no detection, so it applies only when you list it.
Run x18n doctor to see the result. Each preset shows as detected, not-detected, listed, or after-exclusive.
List presets
To pick the presets yourself, list them. x18n then applies exactly the listed presets and detects none:
import { general, vueI18n } from '@x18n/cli/presets'
import { defineConfig } from '@x18n/core'
export default defineConfig({
presets: [vueI18n(), general()],
})presets: [vue-i18n, general]In TS, the presets are functions from @x18n/cli/presets: nuxtI18n, vueI18n, fluentVue, i18nextShopify, reactI18next, nextTranslate, nextInternational, i18next, nextIntl, reactIntl, svelteI18n, solidPrimitivesI18n, paraglide, ngxTranslate, transloco, lingui, emberIntl, polyglot, globalize, i18nTag, i18nJs, ui5, chromeExtension, vscodeExtension, laravel, phpJoomla, phpGettext, rubyRails, jekyll, flutter and general. In YAML and JSON, use the names in the first column of the table. presets: [] turns every preset off.
What a preset adds
Each preset page lists what the preset adds:
- Translate calls: the callee names that count as translate calls, and where the key, the namespace and the key prefix come from. These become
usage.calls. - Defaults: namespace rules, derived keys and resource patterns.
- Placeholders: the syntax of the placeholders in messages.
- Extraction templates: the code that replaces a hard string.
Your config adds to these defaults. For example, usage.calls in the config adds callees to the ones of the preset. See How x18n merges the config.
Resource defaults
The resource patterns of all applied presets add up. For example, a project with next-intl and ngx-translate uses the patterns of both presets.
- If your config has
resources, x18n uses only your patterns. They replace the patterns of every preset. - If the patterns of the presets match no file, x18n guesses the locale directories, as it does without presets. See Locale files.
- A pattern without
{locale}, such aswebapp/i18n/i18n.properties, holds the source locale. To give it another locale, setlocaleon the resource.
Placeholders
A placeholder syntax tells x18n how placeholders look in messages. The placeholder-mismatch check and x18n apply compare the placeholders of each translation with the source value. Translate prompts list them.
| Syntax | Example | Used by |
|---|---|---|
| braces | {name}, {0} | vue-i18n, nuxt-i18n, i18next-shopify, next-international, ui5, vscode-extension, flutter |
| linked | @:key, @.lower:key | vue-i18n, nuxt-i18n |
| double braces | {{name}}, {{name, format}}, {{- raw}} | i18next, react-i18next, i18next-shopify, next-translate, ngx-translate, transloco |
| nesting | $t(key) | i18next, react-i18next, i18next-shopify |
| ICU | {name}, {count, plural, one {# item} other {# items}} | next-intl, react-intl, svelte-i18n, lingui, ember-intl, globalize |
| fluent | { $name } | fluent-vue |
| percent braces | %{name} | polyglot, i18n-js, ruby-rails |
| printf | %s, %d, %1$s | php-joomla, php-gettext |
| colon | :name | laravel |
| dollars | $name$ | chrome-extension |
A linked message (@:key) and a nesting placeholder ($t(key)) name another key. That key then counts as used. The invalid-syntax check reports a linked message whose key does not exist, and ICU messages that do not parse or that lack an other case.
Plugins can use all of these syntaxes from @x18n/builtins/placeholders. A YAML plugin can declare a shape such as %{name}.
Extraction templates
x18n extract replaces a hard string with code from a template. A template has these tokens:
| Token | Becomes |
|---|---|
{key} | The new key. |
{attr} | The attribute name, for attribute kinds. |
{args} | The arguments of a template string: , { name: user.name }. Empty when there are none. |
Each hard string has a kind, which tells where it is:
| Kind | Example |
|---|---|
jsx-text | <p>Hello</p> in JSX |
jsx-attribute | <input placeholder="Search" /> in JSX |
vue-template-text | Text in a Vue template |
vue-attribute | An attribute in a Vue template |
svelte-text | Text in a Svelte component |
svelte-attribute | An attribute in a Svelte component |
js-string | A string literal in JS or TS |
js-template | A template string in JS or TS |
x18n picks the first template that matches the kind (kinds) and the file (files). It tries the templates of extract.templates first, then those of the presets, then these defaults:
| Kinds | Template |
|---|---|
jsx-text | {t('{key}'{args})} |
jsx-attribute | {attr}={t('{key}'{args})} |
vue-template-text | {{ $t('{key}'{args}) }} |
vue-attribute | :{attr}="$t('{key}'{args})" |
svelte-text | {$t('{key}'{args})} |
svelte-attribute | {attr}={$t('{key}'{args})} |
| any | t('{key}'{args}) |
A template can add imports: lines that x18n adds once to the file when they are missing, such as import { useI18n } from 'vue-i18n'.
import { defineConfig } from '@x18n/core'
export default defineConfig({
extract: {
keyPrefix: '{component}',
templates: [
{
template: 'i18n.t(\'{key}\'{args})',
kinds: ['js-string', 'js-template'],
files: ['src/server/**'],
imports: ['import { i18n } from \'~/i18n\''],
},
],
},
})