next-i18next

repository·master·Indexed 27 days ago

https://github.com/i18next/next-i18next

A library for translating Next.js applications, providing a thin layer over i18next and react-i18next. It supports App Router, Pages Router, and mixed setups, handling Next.js-specific requirements such as middleware, server/client resource hydration, and language detection. Version 16.0.8 includes support for locale-in-path and no-locale-path modes, custom i18next backends, and a proxy system for language detection and redirects.

Tokens
15K
Snippets
36
Records
67
Agent score
91%

What's inside next-i18next

  1. Explore next-i18next examples

    master

    The repository provides several reference implementations for different Next.js routing and deployment scenarios:

    • App Router (Locale in path): app-router-simple (e.g., /en/...)
    • App Router (Cookie-based): app-router-no-locale-path (no locale in URL)
    • Mixed Routers: mixed-routers (using both App Router and Pages Router in one project)
    • Pages Router (Standard): pages-router-simple (using getStaticProps / getServerSideProps)
    • Pages Router (Static Export): pages-router-ssg (configured for output: 'export')
    • Pages Router (Client-side loading): pages-router-auto-static-optimize (using chained backend for client-side loading)
  2. Migrate App Router users from v15 to v16

    master

    If you were using i18next and react-i18next directly in v15, follow these steps to migrate to next-i18next v16 for App Router:

    1. Install the new version: npm install next-i18next@16.
    2. Create an i18n.config.ts file defining your languages and namespaces.
    3. Replace custom proxy/middleware logic with createProxy(config) in a proxy.ts file.
    4. Replace custom translation initialization/getT with initServerI18next and getT imported from next-i18next/server.
    5. Replace your custom I18nProvider with the one provided by next-i18next/client.
    6. In client components, replace useTranslation with useT from next-i18next/client.
    npm install next-i18next@16
  3. Set up the next-i18next Proxy

    master

    For Next.js 16+, create a proxy.ts file at your project root. This replaces middleware.ts and handles language detection (via cookies or Accept-Language), redirects, and setting the x-i18next-current-language header for Server Components.

    import { createProxy } from 'next-i18next/proxy'
    import i18nConfig from './i18n.config'
    
    export const proxy = createProxy(i18nConfig)
    
    export const config = {
      matcher: ['/((?!api|_next/static|_next/image|assets|favicon.ico|sw.js|site.webmanifest).*)'],
    }
  4. Configure No-Locale-Path Mode in App Router

    master

    To use clean URLs without a locale prefix (e.g., /about instead of /en/about), set localeInPath: false in your I18nConfig.

    In this mode:

    • Routes live directly under app/ (no [lng] segment).
    • Middleware detects language from cookies or Accept-Language and sets the header without redirecting.
    • Server Components use getT() to read language from the header.
    • Client Components use useT() (language comes from I18nProvider).
    • Use useChangeLanguage() to switch languages; it updates the cookie and triggers a server re-render.
    const i18nConfig: I18nConfig = {
      supportedLngs: ['en', 'de'],
      fallbackLng: 'en',
      localeInPath: false,
      resourceLoader: (language, namespace) =>
        import(`./app/i18n/locales/${language}/${namespace}.jsonspi`),
    }
  5. Explicitly pass the next-i18next configuration

    master

    If automatic configuration detection fails (common in monorepos/workspaces), you can manually provide the config object. This also allows you to use different file extensions like .mjs or .cjs.

    1. Update _app.tsx

    Pass the config as the second argument to appWithTranslation.

    // _app.tsx
    import type { AppProps } from 'next/app'
    import { appWithTranslation } from 'next-i18next'
    import nextI18NextConfig from '../next-i18next.config'
    
    const MyApp = ({ Component, pageProps }: AppProps) => (
      <Component {...pageProps} />
    )
    
    export default appWithTranslation(MyApp, nextI18NextConfig)

    2. Update getStaticProps or getServerSideProps

    Instead of calling serverSideTranslations directly, create a wrapper function (e.g., getServerTranslations) that injects your configuration.

  6. Use Custom i18next Backends

    master

    You can use any i18next backend plugin (e.g., i18next-http-backend, i18next-locize-backend) by providing it via the use option in defineConfig.

    Note: When a custom backend is provided via use, next-i18next will not add its default resource loader.

    For client-side I18nProvider, pass custom backend plugins via the use prop.

    Server-side caching: On the server, next-i18next uses a module-level singleton. Translations are loaded once and reused. In serverless environments, the cache only lasts as long as the warm function instance; for these environments, it is recommended to bundle translations at build time.

    import { defineConfig } from 'next-i18next'
    import HttpBackend from 'i18next-http-backend'
    
    export default defineConfig({
      supportedLngs: ['en', 'de'],
      fallbackLng: 'en',
      use: [HttpBackend],
      i18nextOptions: {
        backend: {
          loadPath: 'https://cdn.example.com/locales/{{lng}}/{{ns}}.json',
        },
      },
    })
  7. Set up Pages Router only

    master

    For projects using only the Pages Router, use the next-i18next/pages API. You must wrap your _app.tsx with appWithTranslation and use serverSideTranslations in getStaticProps or getServerSideProps to load resources.

    // pages/_app.tsx
    import { appWithTranslation } from 'next-i18next/pages'
    
    const MyApp = ({ Component, pageProps }) => <Component {...pageProps} />
    export default appWithTranslation(MyApp)
    // pages/index.tsx
    import { serverSideTranslations } from 'next-i18next/pages/serverSideTranslations'
    import { useTranslation } from 'next-i18next/pages'
    
    export const getStaticProps = async ({ locale }) => ({
      props: {
        ...(await serverSideTranslations(locale, ['common'])),
      },
    })
    
    export default function Home() {
      const { t } = useTranslation('common')
      return <h1>{t('title')}</h1>
    }
  8. Switch languages in locale-in-path mode

    master

    When using locale-in-path (e.g., /en/about), switch languages by navigating to the new locale prefix using next/navigation.

    'use client'
    import { usePathname, useRouter } from 'next/navigation'
    
    export function LanguageSwitcher({ supportedLngs }: { supportedLngs: string[] }) {
      const pathname = usePathname()
      const router = useRouter()
    
      const switchLocale = (locale: string) => {
        const segments = pathname.split('/')
        segments[1] = locale
        router.push(segments.join('/'))
      }
    
      return (
        <div>
          {supportedLngs.map((lng) => (
            <button key={lng} onClick={() => switchLocale(lng)}>{lng}</button>
          ))}
        </div>
      )
    }
  9. Migrate Pages Router users from v15 to v16

    master

    To migrate Pages Router users from v15 to v16, update your imports as follows:

    1. Change base imports from next-i18next to next-i18next/pages.
    2. Update serverSideTranslations import to next-i18next/pages/serverSideTranslations.
    3. Update type imports to use next-i18next/pages: import type { TFunction, WithTranslation, I18n } from 'next-i18next/pages'
  10. Configure Mixed Router Setup (App Router + Pages Router)

    master

    For projects using both App Router and Pages Router, use the basePath option to scope the App Router middleware to a specific URL prefix. This allows the Pages Router to continue using standard Next.js i18n routing for all other paths.

    1. Create a shared configuration for common settings.
    2. Configure the App Router with basePath and a resourceLoader.
    3. Configure the Pages Router using next-i18next.config.js.
    4. Use createProxy in a middleware/proxy file to handle the App Router prefix.
    5. Include the Pages Router i18n config in next.config.js.
    // i18n.config.ts (App Router config)
    import type { I18nConfig } from 'next-i18next/proxy'
    const shared = require('./i18n.shared.js')
    
    const i18nConfig: I18nConfig = {
      ...shared,
      basePath: '/app-router',
      resourceLoader: (language, namespace) =>
        import(`./public/locales/${language}/${namespace}.json`),
    }
    
    export default i18nConfig
  11. Implement Root Layout for App Router

    master

    In your app/[lng]/layout.tsx, initialize the server-side i18n instance, generate static params, and wrap your application with I18nProvider to enable client-side translation support.

    // app/[lng]/layout.tsx
    import { initServerI18next, getT, getResources, generateI18nStaticParams } from 'next-i18next/server'
    import { I18nProvider } from 'next-i18next/client'
    import i18nConfig from '../../i18n.config'
    
    initServerI18next(i18nConfig)
    
    export async function generateStaticParams() {
      return generateI18nStaticParams()
    }
    
    export default async function RootLayout({
      children,
      params,
    }: {
      children: React.ReactNode
      params: Promise<{ lng: string }>
    }) {
      const { lng } = await params
      const { i18n } = await getT()
      const resources = getResources(i18n)
    
      return (
        <html lang={lng}>
          <body>
            <I18nProvider language={lng} resources={resources}>
              {children}
            </I18nProvider>
          </body>
        </html>
      )
    }