next-translate

repository·canary·Indexed 25 days ago

https://github.com/aralroca/next-translate

A lightweight i18n library for Next.js (version 3.2.0) providing a build-time plugin for optimized translation loading and a developer API. It supports Next.js 16 App Directory Server and Client Components via createTranslation and useTranslation, as well as a Trans component for complex HTML translations. Features include TypeScript support, Turbopack integration, remote translation loading, and customizable interpolation and namespace management.

Tokens
11.6K
Snippets
32
Records
50
Agent score
83%

What's inside next-translate

  1. Configure next-translate-plugin in next.config.js

    canary

    You must wrap your next.config.js with the next-translate-plugin.

    Standard Webpack Configuration

    If you have a simple config:

    const nextTranslate = require('next-translate-plugin')
    module.exports = nextTranslate()

    If you have an existing configuration (e.g., for Webpack), pass your config object to nextTranslate():

    const nextTranslate = require('next-translate-plugin')
    module.exports = nextTranslate({
      webpack: (config, { isServer, webpack }) => {
        return config;
      }
    })

    Turbopack Configuration (Next.js 16+)

    If you are using Turbopack, you must pass { turbopack: true } as the second argument to avoid startup errors. Otherwise, the plugin will attempt to inject Webpack configurations that Turbopack does not support.

    const nextTranslate = require('next-translate-plugin')
    
    // For Next.js 16+ with Turbopack enabled
    module.exports = nextTranslate({}, { turbopack: true })

    For a more robust detection in Next.js 16+:

    const nextTranslate = require('next-translate-plugin')
    const isTurbopack = !process.argv.includes('--webpack')
    
    module.exports = nextTranslate(
      {
        // your Next.js config here
      },
      { turbopack: isTurbopack }
    )
    const nextTranslate = require('next-translate-plugin')
    
    module.exports = nextTranslate({}, { turbopack: true })
  2. Use next-translate with Next.js 13+ App Directory

    canary

    To use next-translate with the Next.js App Router, you must use the next-translate-plugin. The plugin automatically detects the use of the app folder.

    When using the App Router, the standard Next.js i18n routing configuration does not work correctly. Instead, it is recommended to use a dynamic path [lang] at the first level of your app directory (e.g., /app/[lang]/page.tsx).

    You must update your i18n.js (or .json) configuration to include the /[lang] prefix in your page paths.

    module.exports = {
      locales: ['en', 'ca', 'es'],
      defaultLocale: 'en',
      pages: {
        '*': ['common'],
        '/[lang]': ['home'],
        '/[lang]/second-page': ['home'],
      },
    }
  3. Persist user language via cookies

    canary

    To ensure a user's language preference is remembered across sessions, you can manually set a cookie named NEXT_LOCALE. Next.js and next-translate look for this cookie to determine the forced locale.

    // Example of setting the NEXT_LOCALE cookie
    function persistLocaleCookie() {
      const date = new Date()
      const expireMs = 100 * 24 * 60 * 60 * 1000 // 100 days
      date.setTime(date.getTime() + expireMs)
      document.cookie = `NEXT_LOCALE=${locale};expires=${date.toUTCString()};path=/`
    }
  4. Install next-translate and the plugin

    canary

    To use next-translate, you need to install both the core library and the build-time plugin. The core library provides the i18n API for your code, while the plugin handles the efficient loading of translation namespaces during the Next.js build process.

    1. Install the core library: yarn add next-translate

    2. Install the plugin as a devDependency: yarn add next-translate-plugin -D

    yarn add next-translate
    yarn add next-translate-plugin -D
  5. Initialize a Next.js project with next-translate example

    canary

    You can quickly scaffold a new Next.js project using the official with-next-translate example from the Vercel repository.

    npx create-next-app --example with-next-translate with-next-translate-app
    # or
    yarn create next-app --example with-next-translate with-next-translate-app
  6. Resolve static property conflicts using hoist-non-react-statics

    canary

    By default, the Higher-Order Components (HOCs) provided by next-translate (such as appWithI18n) do not use hoist-non-react-statics. This is intended to avoid including unnecessary knowledge base (kb) overhead, as static values other than getInitialProps are rarely used in pages.

    If you encounter conflicts with static properties on your pages, you can manually add hoist-non-react-statics (or an alternative) to your i18n.js configuration using the staticsHoc key.

    const hoistNonReactStatics = require('hoist-non-react-statics')
    
    module.exports = {
      locales: ['en', 'ca', 'es'],
      defaultLocale: 'en',
      // add this to resolve static conflicts:
      staticsHoc: hoistNonReactStatics,
      // ... rest of conf
    }
  7. Run next-translate Demos

    canary

    You can explore various implementation patterns by cloning the repository and running the provided examples:

    • Basic Demo: Standard setup.
    • Complex Demo: Includes TypeScript, Webpack 5, MDX, and custom directory structures.
    • App Directory Demo: Uses the Next.js 13+ App Router and layouts system.
    • Without Webpack Loader Demo: Manually loads namespaces (not recommended).
  8. Migrate from next-translate 0.x to 1.0.0

    canary

    To upgrade from next-translate@0.x to next-translate@1.0.0, follow these steps to unify your configuration under the webpack loader and remove obsolete build steps or wrappers.

    1. Update Dependencies

    Update next-translate to ^1.0.0 using your package manager:

    yarn add next-translate@^1.0.0
    # or
    npm install next-translate@^1.0.0

    2. Update next.config.js

    Replace your manual i18n configuration with the nextTranslate wrapper:

    const nextTranslate = require("next-translate");
    
    module.exports = nextTranslate();

    3. Clean up i18n configuration

    Remove obsolete keys from your i18n.json file, such as currentPagesDir, finalPagesDir, localesPath, and package.

    If you were using localesPath to load namespaces from a custom directory, migrate from i18n.json to i18n.js and implement the loadLocaleFrom function:

    module.exports = {
      // ...rest of config
      loadLocaleFrom: (lang, ns) =>
        import(`./locales/${lang}/${ns}.json`).then((m) => m.default),
    }

    4. Remove Build Step artifacts (if applicable)

    If you were using the "build step" method:

    • Remove next-translate from your package.json scripts (e.g., remove it from dev and build).
    • Remove /pages from your .gitignore.
    • Rename your pages_ directory to pages.

    5. Remove appWithI18n wrapper (if applicable)

    If you were using the appWithI18n wrapper in _app.js, remove the import and the wrapper function, exporting your component directly:

    import React from 'react'
    import type { AppProps } from 'next/app'
    // Remove these:
    // import appWithI18n from 'next-translate/appWithI18n'
    // import i18nConfig from '../i18n'
    
    import '../styles.css'
    
    function MyApp({ Component, pageProps }: AppProps) {
      return <Component {...pageProps} />
    }
    
    // Change this:
    // export default appWithI18n(MyApp, i18nConfig)
    // To this:
    export default MyApp

    6. Update Plural Keys

    Replace all _plural suffixes in your translation files with _other to support the new 6-form plural system:

    {
      "lorem-ipsum_other": "The value is {{count}}"
    }
  9. Enable type safety for translations in TypeScript

    canary

    To enable type-safe translation keys and autocomplete when using useTranslation or getT, you must create a next-translate.d.ts file in your project. This file defines your translation namespaces and maps them to your JSON locale files using the Paths utility from next-translate.

    import type { Paths, I18n, Translate } from 'next-translate'
    
    type Tail<T> = T extends [unknown, ...infer Rest] ? Rest : never;
    
    export interface TranslationsKeys {
      // Map your namespace names to the path of your default language JSON files
      common: Paths<typeof import('./locales/en/common.json')>
      home: Paths<typeof import('./locales/en/home.json')>
      // Add all other namespaces here...
    }
    
    type TranslationNamespace = keyof TranslationsKeys;
    
    export interface TranslateFunction<Namespace extends TranslationNamespace>  {
      (
        key: TranslationsKeys[Namespace],
        ...rest: Tail<Parameters<Translate>>
      ): string
      <T extends string>(template: TemplateStringsArray): string
    };
    
    export interface TypeSafeTranslate<Namespace extends TranslationNamespace>
      extends Omit<I18n, 't'> {
      t: TranslateFunction<Namespace>
    }
    
    declare module 'next-translate/useTranslation' {
      export default function useTranslation<
        Namespace extends TranslationNamespace
      >(namespace: Namespace): TypeSafeTranslate<Namespace>
    }
    
    declare module 'next-translate/getT' {
      export default function getT<
        Namespace extends TranslationNamespace
      >(locale?: string, namespace: Namespace): Promise<TranslateFunction<Namespace>>  
    }