Configuration
Fluenti is configured via a fluenti.config.ts file at your project root. The file is loaded at build time using jiti, so you can use TypeScript, ESM imports, and top-level await without any extra setup.
defineConfig()
Section titled “defineConfig()”Wrap your config in defineConfig() for full type inference and IDE autocompletion. It is an identity function with no runtime effect.
import { defineConfig } from '@fluenti/cli'
export default defineConfig({ sourceLocale: 'en', locales: ['en', 'ja', 'zh-CN'], catalogDir: './locales', format: 'po', include: ['./src/**/*.{vue,tsx,ts}'], compileOutDir: './src/locales/compiled',})defineConfig is also exported from @fluenti/core if you prefer not to depend on the CLI package.
Config File Resolution
Section titled “Config File Resolution”When no explicit path is provided, the config loader searches the working directory for:
fluenti.config.tsfluenti.config.jsfluenti.config.mjs
The first file found is used. If none exists, built-in defaults apply.
Build Options
Section titled “Build Options”These options control extraction, compilation, and output.
sourceLocale
Section titled “sourceLocale”| Type | string |
| Default | 'en' |
The locale used in your source code. Messages written in source files are treated as this locale. This locale’s catalog is auto-populated during extraction.
locales
Section titled “locales”| Type | LocaleDefinition[] |
| Default | ['en'] |
All locales your app supports. Each entry can be a plain string or a metadata object:
locales: [ 'en', { code: 'ja', name: '日本語' }, { code: 'ar', name: 'العربية', dir: 'rtl' }, { code: 'zh-CN', name: '简体中文', iso: 'zh-Hans-CN' },]The LocaleObject shape:
| Property | Type | Description |
|---|---|---|
code | string | Locale code (e.g. 'en', 'ja', 'zh-CN') |
name | string? | Human-readable display name |
iso | string? | BCP 47 language tag for SEO (e.g. 'en-US') |
dir | 'ltr' | 'rtl'? | Text direction |
domain | string? | Domain for domain-based routing |
defaultLocale
Section titled “defaultLocale”| Type | string? |
| Default | Value of sourceLocale |
Default locale for routing and detection. Usually the same as sourceLocale, but can differ when your source language is not the primary user-facing locale.
catalogDir
Section titled “catalogDir”| Type | string |
| Default | './locales' |
Directory where translation catalog files are stored. The CLI reads from and writes to this directory during extract and compile commands.
format
Section titled “format”| Type | 'po' | 'json' |
| Default | 'po' |
Catalog file format.
'po'(recommended) — gettext PO format. Compatible with Poedit, Weblate, Crowdin, and other translation tools.'json'— Simple key-value JSON. Useful for lightweight setups or when integrating with JSON-based translation services.
include
Section titled “include”| Type | string[] |
| Default | ['./src/**/*.{vue,tsx,jsx,ts,js}'] |
Glob patterns for source files to scan during message extraction.
// Vue projectinclude: ['./src/**/*.{vue,ts}']
// Next.js projectinclude: ['./src/**/*.{tsx,ts}']
// Nuxt project (no src directory)include: ['./pages/**/*.vue', './components/**/*.vue', './plugins/**/*.ts']exclude
Section titled “exclude”| Type | string[] |
| Default | ['**/*.test.*', '**/*.spec.*', '**/__tests__/**', '**/*.d.ts'] |
Glob patterns to exclude from extraction. Test files and type declarations are excluded by default.
compileOutDir
Section titled “compileOutDir”| Type | string |
| Default | './src/locales/compiled' |
Output directory for compiled message modules. The compiler writes one file per locale here (e.g. en.ts, ja.ts). These files are imported by framework integrations at runtime.
catalogExtension
Section titled “catalogExtension”| Type | '.js' | '.ts' |
| Default | '.js' |
File extension for compiled catalog output files. Use '.ts' if your build pipeline handles TypeScript directly.
splitting
Section titled “splitting”| Type | 'dynamic' | 'static' | false |
| Default | false |
Code-splitting strategy for compiled message modules.
false— All messages are bundled into a single module per locale. Simplest setup.'static'— A single locale is inlined at build time. RequiresdefaultBuildLocale.'dynamic'— Default locale in the bundle, other locales loaded on demand. Best for large apps with many locales.
See Code Splitting for details.
defaultBuildLocale
Section titled “defaultBuildLocale”| Type | string? |
| Default | — |
The locale embedded directly in the bundle when using the 'static' splitting strategy. Other locales are loaded at runtime.
idGenerator
Section titled “idGenerator”| Type | (message: string, context?: string) => string |
| Default | Built-in hash function |
Custom message ID generator. By default, Fluenti generates deterministic hash-based IDs from message content and optional context. Override this to use your own ID scheme.
idGenerator: (message, context) => { const base = context ? `${context}::${message}` : message return myCustomHash(base)}Dev Options
Section titled “Dev Options”Options that control behavior during development.
devAutoCompile
Section titled “devAutoCompile”| Type | boolean |
| Default | true |
Automatically run extract + compile when source files change in dev mode. The Vite plugin watches for file changes and triggers recompilation.
buildAutoCompile
Section titled “buildAutoCompile”| Type | boolean |
| Default | true |
Automatically run extract + compile before production builds. Set to false if you run fluenti extract && fluenti compile as a separate CI step.
devAutoCompileDelay
Section titled “devAutoCompileDelay”| Type | number |
| Default | 500 |
Debounce delay in milliseconds for dev auto-compile. Prevents excessive recompilation when multiple files change in rapid succession.
parallelCompile
Section titled “parallelCompile”| Type | boolean |
| Default | false |
Enable parallel compilation across locales using worker threads. Useful for projects with many target locales where compilation is a bottleneck.
devWarnings
Section titled “devWarnings”| Type | boolean? |
| Default | — |
Enable development warnings for missing translations. When true, missing messages return a [!]-prefixed fallback and emit console.warn. Also activatable via the FLUENTI_DEBUG environment variable.
Lifecycle Hooks
Section titled “Lifecycle Hooks”onBeforeCompile
Section titled “onBeforeCompile”| Type | () => boolean | void | Promise<boolean | void> |
Called before auto-compile runs. Return false to skip compilation for this cycle.
onBeforeCompile: () => { console.log('Compiling translations...') // Return false to skip}onAfterCompile
Section titled “onAfterCompile”| Type | () => void | Promise<void> |
Called after auto-compile completes successfully.
onAfterCompile: () => { console.log('Translation compilation complete')}Runtime Options
Section titled “Runtime Options”These options are stored in the config file but consumed at runtime by framework integrations.
fallbackChain
Section titled “fallbackChain”| Type | Record<string, string[]> |
| Default | {} |
Locale fallback chains. When a message is missing in a locale, the chain is followed in order. Use '*' as a wildcard for all locales.
fallbackChain: { 'zh-TW': ['zh-CN', 'en'], // Traditional Chinese falls back to Simplified, then English 'pt-BR': ['pt', 'en'], // Brazilian Portuguese falls back to Portuguese, then English '*': ['en'], // All other locales fall back to English}See Fallback Chains for details.
dateFormats
Section titled “dateFormats”| Type | Record<string, Intl.DateTimeFormatOptions | 'relative'> |
| Default | — |
Named date format presets used by the d() formatter and <DateTime> components.
dateFormats: { short: { dateStyle: 'short' }, long: { dateStyle: 'long', timeStyle: 'short' }, relative: 'relative',}numberFormats
Section titled “numberFormats”| Type | Record<string, Intl.NumberFormatOptions | ((locale: string) => Intl.NumberFormatOptions)> |
| Default | — |
Named number format presets used by the n() formatter and <NumberFormat> components. Values can be static options or a function that returns locale-specific options.
numberFormats: { currency: (locale) => ({ style: 'currency', currency: locale.startsWith('ja') ? 'JPY' : 'USD', }), percent: { style: 'percent', maximumFractionDigits: 1 },}Plugins
Section titled “Plugins”plugins
Section titled “plugins”| Type | FluentiPlugin[] |
| Default | — |
Plugins that hook into the extract and compile pipelines. Each plugin is an object with a name and optional lifecycle hooks.
import { pseudoLocalePlugin } from '@fluenti/core/plugins/pseudo-locale'import { messageValidatorPlugin } from '@fluenti/core/plugins/message-validator'
export default defineConfig({ // ... plugins: [ pseudoLocalePlugin({ locale: 'en-XA' }), messageValidatorPlugin(), ],})The FluentiPlugin interface:
| Hook | Signature | Description |
|---|---|---|
name | string | Plugin identifier |
onAfterExtract | (context) => void | Called after message extraction |
onBeforeCompile | (context) => void | Called before compilation per locale |
onAfterCompile | (context) => void | Called after compilation per locale |
transformMessages | (messages, locale) => messages | Transform message map before compilation |
formatters | Record<string, CustomFormatter> | Custom ICU formatters provided by the plugin |
Monorepo Inheritance
Section titled “Monorepo Inheritance”extends
Section titled “extends”| Type | string? |
| Default | — |
Path to a parent config file (relative to the current config’s directory). The child config inherits all options from the parent and can override any of them. Path-based fields (catalogDir, compileOutDir, include, exclude) are automatically rebased to the child directory.
my-monorepo/├── fluenti.config.ts # Shared base config├── packages/│ ├── app-a/│ │ └── fluenti.config.ts # extends ../../fluenti.config.ts│ └── app-b/│ └── fluenti.config.ts # extends ../../fluenti.config.tsRoot config (shared settings):
import { defineConfig } from '@fluenti/cli'
export default defineConfig({ sourceLocale: 'en', locales: ['en', 'ja'], format: 'po',})App config (inherits and overrides):
import { defineConfig } from '@fluenti/cli'
export default defineConfig({ extends: '../../fluenti.config.ts', catalogDir: '../../locales', include: ['./src/**/*.{tsx,ts}'], compileOutDir: './src/locales/compiled',})The extends chain has a maximum depth of 10 and circular references are detected with a clear error message. The extends path must be relative — absolute paths are rejected for security.
Runtime Config
Section titled “Runtime Config”These options are available when creating a runtime instance (e.g. via createFluentiCore(), createFluenti(), or I18nProvider), but not in fluenti.config.ts:
| Option | Type | Description |
|---|---|---|
locale | string | Active locale |
fallbackLocale | string? | Fallback locale when a key is missing |
messages | AllMessages | Pre-loaded message catalogs |
missing | (locale, id) => string | undefined | Called when a translation key is missing. Return a string to use as fallback. |
transform | (result, id, locale) => string | Post-translation transform applied to every resolved message |
onLocaleChange | (newLocale, prevLocale) => void | Callback fired when locale changes via setLocale() |
formatters | Record<string, CustomFormatter> | Custom ICU function formatters (e.g. {items, list}) |
devWarnings | boolean? | Show [!] prefix and console.warn for missing translations |
See the @fluenti/core API reference for full details on runtime configuration.
Programmatic API
Section titled “Programmatic API”loadConfig()
Section titled “loadConfig()”Load and resolve a config file asynchronously. Supports extends chain resolution.
import { loadConfig } from '@fluenti/core'
const config = await loadConfig() // Auto-discover from cwdconst config = await loadConfig('./custom.config.ts') // Explicit pathconst config = await loadConfig(undefined, '/my/app') // Custom working directoryloadConfigSync()
Section titled “loadConfigSync()”Synchronous variant for contexts where await is not available (e.g. webpack config). Falls back to defaults on error.
import { loadConfigSync } from '@fluenti/core'
const config = loadConfigSync()normalizeConfig()
Section titled “normalizeConfig()”Validate and normalize a config object. Useful for tools and plugins that construct config programmatically.
import { normalizeConfig } from '@fluenti/core'
const config = normalizeConfig({ sourceLocale: 'en', locales: ['en', 'ja'], catalogDir: './locales', format: 'po', include: ['./src/**/*.tsx'], compileOutDir: './src/locales/compiled',})Defaults Reference
Section titled “Defaults Reference”When no config file is found, or for any omitted options, these defaults apply:
{ sourceLocale: 'en', locales: ['en'], catalogDir: './locales', format: 'po', include: ['./src/**/*.{vue,tsx,jsx,ts,js}'], exclude: ['**/*.test.*', '**/*.spec.*', '**/__tests__/**', '**/*.d.ts'], compileOutDir: './src/locales/compiled', devAutoCompile: true, buildAutoCompile: true, devAutoCompileDelay: 500,}Related
Section titled “Related”- Configuration Guide — step-by-step setup walkthrough
- CLI Reference —
extract,compile, andstatscommands that read this config - Vite Plugin — how the Vite plugin uses config for auto-compile and virtual modules
- Code Splitting —
splittingstrategy deep dive - Fallback Chains —
fallbackChainpatterns for regional variants