Code Splitting
fluenti compile always generates tree-shakeable locale modules — every message is a /* @__PURE__ */ annotated export so bundlers can eliminate unused translations. For bundle size optimization and cache tuning, see the Performance guide. Fluenti splits this into two separate concerns:
- Build-time strategy via
splittinginfluenti.config.ts - Runtime locale loading via
loadMessages()orchunkLoader
How It Works
Section titled “How It Works”- Run
fluenti compileto generate per-locale ES modules with named exports and@__PURE__annotations - Each message becomes a tree-shakeable named export — unused messages are removed from the production bundle
- Pick a build-time strategy with
splitting: 'dynamic' | 'static' | false - If you want async locale switches, configure
loadMessages()orchunkLoader - When
setLocale()is called, the locale chunk is loaded before switching
1. Pick a build-time strategy
Section titled “1. Pick a build-time strategy”Configure the Vite build strategy in fluenti.config.ts:
import { defineConfig } from '@fluenti/cli'
export default defineConfig({ splitting: 'dynamic', defaultBuildLocale: 'en',})| Strategy | What ships | Best for |
|---|---|---|
false | All locales bundled together | Small apps or very small catalogs |
'static' | One build locale inlined directly into the bundle | SSR / SSG when each build only needs one locale |
'dynamic' | Default build locale in the initial bundle, other locales as separate chunks | SPAs or multi-locale apps |
2. Compile catalogs
Section titled “2. Compile catalogs”Compile your catalogs:
npx fluenti compileThis generates:
locales/compiled/en.js— named exports per message withexport defaultre-exportlocales/compiled/zh-CN.js— same exports, translatedlocales/compiled/index.js— locale list and lazy loaders
The Vite plugin reads the compiled locale modules automatically; you do not need to import internal virtual modules yourself.
3. Enable runtime lazy locale loading
Section titled “3. Enable runtime lazy locale loading”Configure your framework runtime if you want setLocale() to fetch locale chunks on demand:
const i18n = createFluenti({ locale: 'en', messages: { en }, lazyLocaleLoading: true, chunkLoader: (locale) => import(`./locales/compiled/${locale}.js`),})<I18nProvider locale="en" messages={{ en }} loadMessages={(locale) => import(`./locales/compiled/${locale}.js`)}> <App /></I18nProvider><I18nProvider locale="en" messages={{ en }} lazyLocaleLoading={true} chunkLoader={(locale) => import(`./locales/compiled/${locale}.js`)}> <App /></I18nProvider>If you do not configure loadMessages() / chunkLoader, setLocale() only switches between already-loaded catalogs. That is still valid with any build-time splitting strategy.
Build vs Dev Mode
Section titled “Build vs Dev Mode”| Mode | Behavior |
|---|---|
| Dev | All locales loaded eagerly for instant HMR |
| Build | Only defaultBuildLocale is bundled; others are lazy chunks |
Preload on Hover
Section titled “Preload on Hover”<template> <button v-for="loc in locales" :key="loc" @mouseenter="preloadLocale(loc)" @click="setLocale(loc)" > {{ loc }} </button></template>
<script setup>import { useI18n } from '@fluenti/vue'const { setLocale, preloadLocale } = useI18n()const locales = ['en', 'ja', 'zh-CN']</script>import { useI18n } from '@fluenti/react'
function LocaleSwitcher() { const { setLocale, preloadLocale } = useI18n() const locales = ['en', 'ja', 'zh-CN']
return locales.map((loc) => ( <button key={loc} onMouseEnter={() => preloadLocale(loc)} onClick={() => setLocale(loc)} > {loc} </button> ))}import { useI18n } from '@fluenti/solid'
function LocaleSwitcher() { const { setLocale, preloadLocale } = useI18n() const locales = ['en', 'ja', 'zh-CN']
return locales.map((loc) => ( <button onMouseEnter={() => preloadLocale(loc)} onClick={() => setLocale(loc)} > {loc} </button> ))}