best-i18n
Integrations

Vite

best-i18n/vite — for Vite and everything built on it

The Vite plugin covers Vite itself and anything running on it: TanStack Start, React Router, SvelteKit, Astro. rolldown-vite keeps the Vite plugin API, so it uses this plugin unchanged.

// vite.config.ts
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import { i18n } from 'best-i18n/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    i18n({
      messagesDir: fileURLToPath(new URL('./messages', import.meta.url)),
      locales: ['en', 'zh'],
      baseLocale: 'en',
      // set (e.g. from an env var) to build a single locale as pure literals
      staticLocale: process.env.I18N_STATIC_LOCALE,
    }),
    // ...other plugins
  ],
})

The .po files under messagesDir are the source of truth — the plugin reads them directly, no compile step in between. Editing a message file in dev triggers a full reload.

With staticLocale set, the build inlines that one locale as plain string literals — one deployable bundle per locale, each with zero i18n overhead. See Writing messages for what compiles, and Extract and translate for the catalog workflow.

TanStack Start

TanStack Start uses this plugin unchanged, with a request middleware and router URL rewriting on top. It has its own page: TanStack Start.

Svelte 5 and SvelteKit

Svelte runs on this same plugin with one extra option, svelte: true, plus a few hooks on the SvelteKit side. It has its own page: Svelte.

Solid and SolidStart v2

Solid runs on this same plugin with one extra option, solid: true, plus a middleware and a router hook on the SolidStart side. It has its own page: Solid.

Vue 3 and Nuxt 4

Vue runs on this same plugin with one extra option, vue: true; Nuxt gets a module, best-i18n/nuxt, that adds the plugin and binds the locale per request. Both have their own page: Vue.

On this page