Skip to content

Optimization ​

Performance ​

As described in "Different Distribution files" section, Vue I18n offer the following two built ES modules for Bundler.

  • message compiler + runtime: vue-i18n.esm-bundler.js
  • runtime only: vue-i18n.runtime.esm-bundler.js

For bundler, it’s configured to bundle vue-i18n.esm-bundler.js with @intlify/unplugin-vue-i18n as default. If you want to reduce the bundle size further, you can configure the bundler to use vue-i18n.runtime.esm-bundler.js, which is runtime only.

The use of ES Module vue-i18n.runtime.esm-bundler.js means that all locale messages have to pre-compile to Message functions or AST resources. What that means, is that it improves performance because vue-i18n only executes Message functions, so no compilation.

NOTE

Before v9.3, the locale messages will be compiled to Message functions, after v9.3 or later these will be compiled to AST with @intlify/bundle-tools.

NOTE

Before v9.3, all locale messages are compiled with @intlify/unplugin-vue-i18n, so the message compiler is not bundled, bundle size can be reduced.

After v9.3, since the message compiler is also bundled, the bundle size cannot be reduced. This is a trade-off. For the reason, see JIT compilation.

NOTE

If CSP is enabled in before v9.3, vue-i18n.esm-bundler.js would not work with compiler due to eval statements. These statements violate the default-src 'self' header. Instead you need to use vue-i18n.runtime.esm-bundler.js.

NOTICE

From v9.3, the CSP issue can be worked around by JIT compilation of the vue-i18n message compiler. See JIT compilation for details.

How to configure ​

We can configure these modules with module path using the module resolve alias feature (e.g. resolve.alias vite and webpack) of some bundler, but It takes time and effort. Intlify project provides plugins/loaders for some bundlers, for simplicity

unplugin-vue-i18n ​

unplugin is an unified plugin system for bundle tool such as vite, webpack, rollup, esbuild and etc.

Intlify project is providing unplugin-vue-i18n for vite and webpack.

If you do the production build, Vue I18n will automatically bundle the runtime only module

Install plugin ​

sh
npm install @intlify/unplugin-vue-i18n -D
sh
yarn add @intlify/unplugin-vue-i18n -D
sh
pnpm add -D @intlify/unplugin-vue-i18n

Configure plugin for vite ​

js
// vite.config.ts
import { defineConfig } from 'vite'
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'url'
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'

export default defineConfig({
  /* ... */
  plugins: [
    /* ... */
    VueI18nPlugin({
      /* options */
      // locale messages resource pre-compile option
      include: resolve(dirname(fileURLToPath(import.meta.url)), './path/to/src/locales/**'),
    }),
  ],
})

Configure plugin for webpack ​

js
// webpack.config.js
const path = require('path')
const VueI18nPlugin = require('@intlify/unplugin-vue-i18n/webpack')

module.exports = {
  /* ... */
  plugins: [
    /* ... */
    VueI18nPlugin({
      /* options */
      // locale messages resource pre-compile option
      include: path.resolve(__dirname, './path/to/src/locales/**'),
    })
  ]
}

Important options ​

include ​

The include option specifies the file paths of your locale message resources that should be pre-compiled at build time. You must configure this option to cover all your locale message files, otherwise messages that are not pre-compiled will not work correctly in the production build (e.g., interpolation placeholders like {name} won't be replaced).

js
VueI18nPlugin({
  include: resolve(dirname(fileURLToPath(import.meta.url)), './src/locales/**'),
})
runtimeOnly ​

By default, @intlify/unplugin-vue-i18n uses the runtime-only build for production, which excludes the message compiler for smaller bundle size. This means all locale messages must be pre-compiled at build time.

If you load locale messages dynamically at runtime (e.g., from an API or database), you need to set runtimeOnly: false to include the runtime message compiler:

js
VueI18nPlugin({
  runtimeOnly: false,  // Include runtime message compiler
  include: resolve(dirname(fileURLToPath(import.meta.url)), './src/locales/**'),
})

Troubleshooting

If your translations work in development but interpolation placeholders are not replaced in production (e.g., {name} appears literally instead of the value), it's likely one of these issues:

  1. The include option doesn't cover all your locale message files — messages not matched by include won't be pre-compiled
  2. You're loading messages dynamically at runtime — set runtimeOnly: false to include the message compiler

More configuration ​

For the full list of options (runtimeOnly, include, exclude, ssr, module, etc.), see the @intlify/unplugin-vue-i18n documentation.

Quasar CLI ​

No need to do anything. Quasar CLI takes care of the optimizations for you.

Feature build flags ​

Reduce bundle size with tree-shaking ​

The esm-bundler builds now exposes global feature flags that can be overwritten at compile time:

  • __VUE_I18N_FULL_INSTALL__ (enable/disable, in addition to vue-i18n APIs, components and directives all fully support installation: true)
  • __VUE_I18N_LEGACY_API__ (enable/disable vue-i18n legacy style APIs support. Legacy API has been removed in v12, default: false)

The build will work without configuring these flags, however it is strongly recommended to properly configure them in order to get proper tree shaking in the final bundle.

For details on how to configure these flags for your bundler, see Configure feature flags for bundler below.

JIT compilation ​

Support Version

🆕 9.3+

Before v9.3, vue-i18n message compiler precompiled locale messages like AOT (Ahead Of Time).

However, it had the following issues:

  • CSP issues: hard to work on service/web workers, edge-side runtimes of CDNs and etc.
  • Back-end integration: hard to get messages from back-end such as database via API and localize them dynamically

To solve these issues, JIT (Just In Time) style compilation is supported message compiler.

Each time localization is performed in an application using $t or t functions, message resources will be compiled on message compiler.

You need to configure the following feature flag with esm-bundler build and bundler such as vite:

  • __INTLIFY_JIT_COMPILATION__ (enable/disable message compiler for JIT style, default: false)
  • __INTLIFY_DROP_MESSAGE_COMPILER__ (enable/disable whether to tree-shake message compiler when we will be bundling, this flag works when __INTLIFY_JIT_COMPILATION__ is enabled. default: false)

NOTICE

This feature is opted out as default, because compatibility with previous version before v9.3.

NOTICE

From v10, JIT compilation is enabled by default, so it is no longer necessary to set the __INTLIFY_JIT_COMPILATION__ flag in the bundler.

Configure feature flags for bundler ​

NOTE

The replacement value must be boolean literals and cannot be strings, otherwise the bundler/minifier will not be able to properly evaluate the conditions.

Pre translations with extensions ​

You can use pre-translation(server-side rendering) with vue-i18n-extensions package.

For usage, see the vue-i18n-extensions documentation.

SSR (Server-Side Rendering) ​

Configure plugin for SSR ​

For SSR applications, you need to configure the ssr option in @intlify/unplugin-vue-i18n:

ts
// vite.config.ts
import { defineConfig } from 'vite'
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'

export default defineConfig({
  plugins: [
    VueI18nPlugin({
      ssr: true, // Enable SSR support
    }),
  ],
})

Locale messages for each request ​

Create the messages object for each request, or do not write into it after you pass it to createI18n(), because an object created at the module level is shared by every request in the same server process.

Released under the MIT License.