Next.js API
@linguanahq/next integrates Linguana with Next.js 16 App Router. Peer dependencies: next >=16 <17, react and react-dom >=19 <20. Follow the Next.js guide for setup.
Entry points
| Import | Use in | Exports |
|---|---|---|
@linguanahq/next/plugin | next.config.* | withLinguana, LinguanaNextOptions |
@linguanahq/next/server | Server Components, layouts, metadata, route code | LinguanaProvider, getLocale, getTranslations |
@linguanahq/next/client | Client Components | useTranslation, LanguageSelector |
@linguanahq/next | Server and Client Components | T, resolved to the server or client implementation automatically |
@linguanahq/next/styles.css | Root layout | Optional language selector styles |
@linguanahq/next/server is marked server-only; importing it into a Client Component fails the build. @linguanahq/next/compiler-runtime and @linguanahq/next/loader are used by compiled output and the bundler; do not import them directly.
withLinguana(options)
import { withLinguana, type LinguanaNextOptions } from "@linguanahq/next/plugin";
export default withLinguana(options)(nextConfig);Returns a function that accepts a NextConfig object or a Next.js configuration function (sync or async) and returns an async configuration function. Options are validated immediately.
| Option | Type | Required | Default | Exposure | Purpose |
|---|---|---|---|---|---|
projectId | string | Yes | - | Public | Project identity for messages, manifests, and catalogs |
sourceLocale | string | No | "en" | Public | Source language for message IDs and fallback |
environment | string | No | "development" | Public | Build and catalog environment |
root | string | No | Current working directory | Build | Application root for scanning and the loader |
include | string | string[] | No | All eligible source in root | Build | Glob patterns to extract. Required for source outside root |
exclude | string | string[] | No | See below | Build | Additional glob patterns to skip |
output | string | No | .linguana/manifest.json | Build | Manifest path, relative to root |
strict | StrictPolicy | No | false | Build | Promote diagnostics to build failures, as in the Vite plugin |
upload | boolean | No | false | Build | Upload the manifest after next build. Requires token |
apiUrl | string | With upload | https://api.linguana.dev | Build | API origin for upload and translation. Set it explicitly |
token | string | With upload | - | Secret | Project build token. Never reaches the browser |
translation | object | No | - | Paid build policy | Development-only build translation; see below |
runtime | RuntimeOptions | No | - | Public | Runtime language and catalog settings; see below |
Unlike the Vite plugin, providing a token does not enable upload; set upload: true explicitly.
translation
translation: {
enabled: true,
maxChargeMicros: 100_000,
waitTimeoutMs: 300_000,
publish: "development",
}Requires upload: true, token, environment: "development", enabled: true, and publish: "development". maxChargeMicros must be a positive safe integer; waitTimeoutMs, when set, must be positive. Build translation behaves as described in the Vite integration API.
runtime
Runtime options are serialized into public configuration and shipped to the browser. Put only browser-safe values here.
| Option | Type | Default | Purpose |
|---|---|---|---|
publishableKey | string | - | Public catalog-read key for hosted configuration and catalogs |
catalogEndpoint | string | - | API origin for published catalogs |
configEndpoint | string | catalogEndpoint | API origin for hosted runtime configuration (available languages and default language) |
defaultLocale | string | Hosted default, then sourceLocale | Language used when neither cookie nor Accept-Language matches |
availableLocales | LocaleOption[] | Hosted configuration, then embedded catalog languages | Languages offered and accepted. Setting this skips the hosted configuration request |
catalogs | Catalog[] | - | Embedded catalogs, validated when the configuration loads. They take priority over hosted catalogs |
cookieName | string | "linguana_locale" | Language cookie name. Letters, digits, _, and - only |
LocaleOption has code, displayName, and nativeName, plus optional tier and fallbackLocale.
Configuration behavior
- Adds the Linguana loader for
*.js,*.jsx,*.ts, and*.tsxto Turbopack rules (excluding dependencies) and as a webpack pre-loader (excludingnode_modules), before your existing rules. - Writes public runtime configuration to
.linguana/next/runtime.jsonwhen it changes. - After a successful
next buildcompilation, scans eligible source, writes the manifest, and uploads it whenuploadis enabled. This runs once per build and composes with your owncompiler.runAfterProductionCompilehook. - Applying
withLinguanatwice with the same options is a no-op; different options fail.
Default exclusions
Dependencies (node_modules), .next, .linguana, .git, dist, build, .output, and coverage directories; tests (*.test.*, *.spec.*, __tests__); declarations (*.d.ts); configuration files (*.config.*); next-env.d.ts; and the Next.js output directory.
LinguanaProvider
import { LinguanaProvider } from "@linguanahq/next/server";
<LinguanaProvider>{children}</LinguanaProvider>Async Server Component for the root layout. It reads the request's cookies and Accept-Language header, resolves the language and catalogs, and provides them to Server and Client Components beneath it. Takes only children; configuration comes from withLinguana.
getLocale()
const locale: string = await getLocale();Returns the language resolved for the current request. Use it for <html lang>.
getTranslations()
const { locale, t, translate } = await getTranslations();| Member | Signature | Purpose |
|---|---|---|
locale | string | Request language |
t | (source, values?, options?) => ReactNode | Translate an explicit message. options accepts id and context |
translate | (id, source, values?, components?) => ReactNode | Lower-level lookup by message ID |
Wrap results in String() where a string is required, such as metadata titles. Resolution runs once per request and is shared by every server helper.
T
import { T } from "@linguanahq/next";
<T id="guide-link" defaultMessage="Read <link>the guide</link>" components={{ link: <a href="/guide" /> }} />Props match the React T component: id?, required defaultMessage, values?, components?, and context?. In Server Components it is an async component; in Client Components it uses the client runtime.
useTranslation()
"use client";
import { useTranslation } from "@linguanahq/next/client";
const { locale, t, setLocale, ready, availableLocales, diagnostics } = useTranslation();Returns the React useTranslation() values with Next.js language switching:
| Member | Purpose |
|---|---|
locale, sourceLocale | Current and source languages |
t, translate | Explicit message helpers |
availableLocales | Languages offered for this request |
setLocale(locale) | Validate the target catalog, store the language cookie, and refresh server content |
ready | false while a language change is loading or refreshing |
diagnostics | Sampled runtime diagnostics, including failed language changes |
setLocale ignores languages not in availableLocales. If the target catalog cannot be loaded within five seconds or fails verification, the current language stays and a catalog-load-failed diagnostic is added. Throws Next.js translations require LinguanaProvider in the root layout. outside the provider.
LanguageSelector
import { LanguageSelector } from "@linguanahq/next/client";
<LanguageSelector label="Language" className="language" />| Prop | Type | Default |
|---|---|---|
label | string | "Language" |
className | string | - |
Renders a search input and an accessible select listing nativeName — displayName for each language. The select is disabled while a change is in progress. The root element has the data-linguana-language-selector attribute for styling.
Hosted requests
With publishableKey and an endpoint, the server reads:
GET {configEndpoint}/api/v1/runtime/projects/{projectId}/environment/{environment}for languages, whenavailableLocalesis not set.GET {catalogEndpoint}/api/v1/catalogs/{projectId}/{environment}/{locale}for a target catalog not embedded.
Requests send the x-linguana-key header, bypass the Next.js data cache, and time out after five seconds. See Catalog delivery.
Diagnostics
Server diagnostics are written with console.warn and prefixed [linguana]. They include catalog verification and loading failures, and missing-translation and invalid-translation events, sampled once per message per request. Client diagnostics are available through useTranslation().diagnostics with the codes described in the React API.
Configuration errors
| Message | Cause |
|---|---|
Linguana requires projectId. | projectId is missing or blank |
Linguana sourceLocale must be a valid locale. | sourceLocale is not a valid locale tag |
Linguana upload requires a build token. | upload: true without token |
Linguana translation requires upload, a token, and development publication. | translation without upload, token, development environment, enabled: true, and publish: "development" |
translation.maxChargeMicros must be a positive safe integer. | Invalid charge ceiling |
translation.waitTimeoutMs must be positive. | Invalid wait timeout |
Invalid Linguana cookieName. | Cookie name contains unsupported characters |
Linguana requires Next.js 16. | Installed Next.js is not version 16 |
Linguana cookie-based translation requires a Next.js server; remove output: 'export'. | Static export is configured |
Linguana does not yet support cacheComponents; disable it for cookie-based translation. | cacheComponents: true is configured |
Conflicting withLinguana configurations. | The wrapper was applied twice with different options |
See Next.js troubleshooting for fixes.
See also
Reference the @linguanahq/next config wrapper, server helpers, client hooks, components, and errors.
Last updated October 6, 2026
Did this page get you to a working result?