Skip to content
fluenti

@fluenti/next

Wrap your Next.js config to add the Fluenti compiler plugin. Returns a function that accepts the Next.js config:

next.config.ts
import { withFluenti } from '@fluenti/next'
export default withFluenti()({
reactStrictMode: true,
})

All options are optional. Defaults are read from fluenti.config.ts in the project root. Options passed here override the config file values.

OptionTypeDefaultDescription
localesstring[]?from config fileOverride locale list
defaultLocalestring?from config fileOverride default/fallback locale (maps to sourceLocale in config)
compiledDirstring?from config filePath to compiled message catalogs (maps to compileOutDir in config)
resolveLocalestring?reads locale cookiePath to a module that default-exports () => string | Promise<string>. Used in Server Actions and other contexts where the layout doesn’t run
serverModulestring?auto-generatedPath to a custom server module. When provided, skips auto-generation
serverModuleOutDirstring?node_modules/.fluentiDirectory where generated server module files are written
dateFormatsDateFormatOptions?Custom date format presets (passed to createServerI18n)
numberFormatsNumberFormatOptions?Custom number format presets (passed to createServerI18n)
fallbackChainRecord<string, string[]>?Locale fallback chains (e.g. { 'zh-TW': ['zh-CN', 'en'] })
  1. Generates a server module at node_modules/.fluenti/server.js containing:
    • A createServerI18n instance with setLocale(), getI18n(), and server components
    • A FluentProvider async component for layouts
    • A ClientI18nProvider with statically imported message catalogs
  2. Registers a webpack loader that transforms t`...` and t() calls into __i18n.t() lookups
  3. Adds a resolve alias mapping @fluenti/next/__generated to the generated module

The loader auto-detects server vs client context:

ContextDetectioni18n source
Client'use client' directive or pages/ directoryglobalThis.__fluenti_i18n (set by I18nProvider)
Server'use server' directive or app/ directory__getServerI18n() via React.cache() store

The transform uses a Proxy to defer access until render time, so module-level t`` calls work correctly.

withFluenti() generates modules at node_modules/.fluenti/ and aliases them as @fluenti/next/__generated.

// @ts-expect-error — generated at build time
import { FluentProvider } from '@fluenti/next/__generated'
ExportTypeDescription
FluentProviderasync server componentSets server locale + wraps children in ClientI18nProvider
setLocale(locale: string) => voidSet locale for the current request (React.cache() scoped)
getI18n() => Promise<FluentInstance>Get the i18n instance for the current request
Transasync server componentRich text translation
Pluralasync server componentLocale-aware pluralization
DateTimeasync server componentDate formatting
NumberFormatasync server componentNumber formatting

Accepts locale and children. Internally calls setLocale(), initializes the server i18n instance, and renders a ClientI18nProvider with pre-imported message catalogs:

app/layout.tsx
import { cookies } from 'next/headers'
// @ts-expect-error — generated at build time
import { FluentProvider } from '@fluenti/next/__generated'
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const locale = (await cookies()).get('locale')?.value ?? 'en'
return (
<html lang={locale}>
<body>
<FluentProvider locale={locale}>{children}</FluentProvider>
</body>
</html>
)
}

Temporarily switch the request-scoped locale for a subtree render. Useful for rendering a component in a different locale within the same request:

import { withLocale } from '@fluenti/next/server'
export default async function Page() {
const jaContent = await withLocale('ja', async () => {
return <Trans>Hello</Trans> // renders in Japanese
})
return <div>{jaContent}</div>
}

For setup and usage details, see the Next.js guide and Server Components.