• Stars
    star
    5,429
  • Rank 7,570 (Top 0.2 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created about 6 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The easiest way to translate your NextJs apps.

next-i18next

CircleCI Package Quality npm version npm

The easiest way to translate your Next.js apps (with pages setup).

If you are using next-i18next (pages directory) in production and like to unleash some super powers, you may have a look at this blog post.

If you're using Next.js 13 with app directory, there is no need for next-i18next, you can directly use i18next and react-i18next, like described in this blog post.

What is this?

Although Next.js provides internationalised routing directly, it does not handle any management of translation content, or the actual translation functionality itself. All Next.js does is keep your locales and URLs in sync.

To complement this, next-i18next provides the remaining functionality โ€“ย management of translation content, and components/hooks to translate your React components โ€“ while fully supporting SSG/SSR, multiple namespaces, codesplitting, etc.

While next-i18next uses i18next and react-i18next under the hood, users of next-i18next simply need to include their translation content as JSON files and don't have to worry about much else.

A live demo is available here. This demo app is the simple example - nothing more, nothing less.

Why next-i18next?

Easy to set up, easy to use: setup only takes a few steps, and configuration is simple.

No other requirements: next-i18next simplifies internationalisation for your Next.js app without extra dependencies.

Production ready: next-i18next supports passing translations and configuration options into pages as props with SSG/SSR support.

How does it work?

Your next-i18next.config.js file will provide configuration for next-i18next. After configuration, appWithTranslation allows us to use the t (translate) function in our components via hooks.

Then we add serverSideTranslation to getStaticProps or getServerSideProps (depending on your case) in our page-level components.

Now our Next.js app is fully translatable!

Setup

1. Installation

yarn add next-i18next react-i18next i18next

You need to also have react and next installed.

2. Translation content

By default, next-i18next expects your translations to be organised as such:

.
โ””โ”€โ”€ public
    โ””โ”€โ”€ locales
        โ”œโ”€โ”€ en
        |   โ””โ”€โ”€ common.json
        โ””โ”€โ”€ de
            โ””โ”€โ”€ common.json

This structure can also be seen in the simple example.

If you want to structure your translations/namespaces in a custom way, you will need to pass modified localePath and localeStructure values into the initialisation config.

3. Project setup

First, create a next-i18next.config.js file in the root of your project. The syntax for the nested i18n object comes from Next.js directly.

This tells next-i18next what your defaultLocale and other locales are, so that it can preload translations on the server:

next-i18next.config.js

/** @type {import('next-i18next').UserConfig} */
module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'de'],
  },
}

Now, create or modify your next.config.js file, by passing the i18n object into your next.config.js file, to enable localised URL routing:

next.config.js

const { i18n } = require('./next-i18next.config')

module.exports = {
  i18n,
}

There are three functions that next-i18next exports, which you will need to use to translate your project:

appWithTranslation

This is a HOC which wraps your _app:

import { appWithTranslation } from 'next-i18next'

const MyApp = ({ Component, pageProps }) => (
  <Component {...pageProps} />
)

export default appWithTranslation(MyApp)

The appWithTranslation HOC is primarily responsible for adding a I18nextProvider.

serverSideTranslations

This is an async function that you need to include on your page-level components, via either getStaticProps or getServerSideProps (depending on your use case):

import { serverSideTranslations } from 'next-i18next/serverSideTranslations'

export async function getStaticProps({ locale }) {
  return {
    props: {
      ...(await serverSideTranslations(locale, [
        'common',
        'footer',
      ])),
      // Will be passed to the page component as props
    },
  }
}

Note that serverSideTranslations must be imported from next-i18next/serverSideTranslations โ€“ this is a separate module that contains NodeJs-specific code.

Also, note that serverSideTranslations is not compatible with getInitialProps, as it only can execute in a server environment, whereas getInitialProps is called on the client side when navigating between pages.

The serverSideTranslations HOC is primarily responsible for passing translations and configuration options into pages, as props โ€“ you need to add it to any page that has translations.

useTranslation

This is the hook which you'll actually use to do the translation itself. The useTranslation hook comes from react-i18next, but needs to be imported from next-i18next directly.
Do NOT use the useTranslation export of react-i18next, but ONLY use the on of next-i18next!

import { useTranslation } from 'next-i18next'

export const Footer = () => {
  const { t } = useTranslation('footer')

  return (
    <footer>
      <p>{t('description')}</p>
    </footer>
  )
}

4. Declaring namespace dependencies

By default, next-i18next will send all your namespaces down to the client on each initial request. This can be an appropriate approach for smaller apps with less content, but a lot of apps will benefit from splitting namespaces based on route.

To do that, you can pass an array of required namespaces for each page into serverSideTranslations. You can see this approach in examples/simple/pages/index.tsx. Passing in an empty array of required namespaces will send no namespaces.

Note: useTranslation provides namespaces to the component that you use it in. However, serverSideTranslations provides the total available namespaces to the entire React tree and belongs on the page level. Both are required.

5. Declaring locale dependencies

By default, next-i18next will send only the active locale down to the client on each request. This helps reduce the size of the initial payload sent to the client. However in some cases one may need the translations for other languages at runtime too. For example when using getFixedT of useTranslation hook.

To change the behavior and load extra locales just pass in an array of locales as the last argument to serverSideTranslations.

  import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

  export async function getStaticProps({ locale }) {
    return {
      props: {
-       ...(await serverSideTranslations(locale, ['common', 'footer'])),
+       ...(await serverSideTranslations(locale, ['common', 'footer'], null, ['en', 'no'])),
      },
    };
  }

As a result the translations for both no and en locales will always be loaded regardless of the current language.

Note: The extra argument should be added to all pages that use getFixedT function.

Fallback locales

By default, next-i18next will add the defaultLocale as fallback. To change this, you can set fallbackLng. All values supported by i18next (string, array, object and function) are supported by next-i18next too.

Additionally nonExplicitSupportedLngs can be set to true to support all variants of a language, without the need to provide JSON files for each of them. Notice that all variants still must be included in locales to enable routing within next.js.

Note: fallbackLng and nonExplicitSupportedLngs can be used at once. There is only one exception: You can not use a function for fallbackLng when nonExplicitSupportedLngs is true,

module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'fr', 'de-AT', 'de-DE', 'de-CH'],
  },
  fallbackLng: {
    default: ['en'],
    'de-CH': ['fr'],
  },
  nonExplicitSupportedLngs: true,
  // de, fr and en will be loaded as fallback languages for de-CH
}

Be aware that using fallbackLng and nonExplicitSupportedLngs can easily increase the initial size of the page.

fyi: Setting fallbackLng to false will NOT serialize your fallback language (usually defaultLocale). This will decrease the size of your initial page load.

6. Advanced configuration

Passing other config options

If you need to modify more advanced configuration options, you can pass them via next-i18next.config.js. For example:

module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'de'],
  },
  localePath:
    typeof window === 'undefined'
      ? require('path').resolve('./my-custom/path')
      : '/public/my-custom/path',
  ns: ['common'],
}

Unserializable configs

Some i18next plugins (which you can pass into config.use) are unserializable, as they contain functions and other JavaScript primitives.

You may run into this if your use case is more advanced. You'll see Next.js throw an error like:

Error: Error serializing `._nextI18Next.userConfig.use[0].process` returned from `getStaticProps` in "/my-page".
Reason: `function` cannot be serialized as JSON. Please only return JSON serializable data types.

To fix this, you'll need to set config.serializeConfig to false, and manually pass your config into appWithTranslation:

import { appWithTranslation } from 'next-i18next'
import nextI18NextConfig from '../next-i18next.config.js'

const MyApp = ({ Component, pageProps }) => (
  <Component {...pageProps} />
)

export default appWithTranslation(MyApp, nextI18NextConfig)
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'

import nextI18NextConfig from '../next-i18next.config.js'

export const getStaticProps = async ({ locale }) => ({
  props: {
    ...(await serverSideTranslations(
      locale,
      ['common', 'footer'],
      nextI18NextConfig
    )),
  },
})

Client side loading of translations via HTTP

Since v11.0.0 next-i18next also provides support for client side loading of translations.

In some use cases, you might want to load a translation file dynamically without having to use serverSideTranslations. This can be especially useful for lazy-loaded components that you don't want slowing down pages.

More information about that can be found here.

Reloading Resources in Development

Because resources are loaded once when the server is started, any changes made to your translation JSON files in development will not be loaded until the server is restarted.

In production this does not tend to be an issue, but in development you may want to see updates to your translation JSON files without having to restart your development server each time. To do this, set the reloadOnPrerender config option to true.

This option will reload your translations whenever serverSideTranslations is called (in getStaticProps or getServerSideProps). If you are using serverSideTranslations in getServerSideProps, it is recommended to disable reloadOnPrerender in production environments as to avoid reloading resources on each server call.

Options

Key Default value Note
defaultNS 'common'
localePath './public/locales' Can be a function, see note below.
localeExtension 'json' Ignored if localePath is a function.
localeStructure '{{lng}}/{{ns}}' Ignored if localePath is a function.
reloadOnPrerender false
serializeConfig true
use (for plugins) []
onPreInitI18next undefined i.e. (i18n) => i18n.on('failedLoading', handleFailedLoading)

localePath as a function is of the form (locale: string, namespace: string, missing: boolean) => string returning the entire path including filename and extension. When missing is true, return the path for the addPath option of i18next-fs-backend, when false, return the path for the loadPath option. More info at the i18next-fs-backend repo.
If the localePath is a function, make sure you also define the ns option, because on server side we're not able to preload the namespaces then.

All other i18next options and react-i18next options can be passed in as well.

Custom interpolation prefix/suffix

By default, i18next uses {{ as prefix and }} as suffix for interpolation. If you want/need to override these interpolation settings, you must also specify an alternative localeStructure setting that matches your custom prefix and suffix.

For example, if you want to use { and } the config would look like this:

{
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'nl'],
  },
  interpolation: {
    prefix: '{',
    suffix: '}',
  },
  localeStructure: '{lng}/{ns}',
}

Custom next-i18next.config.js path

If you want to change the default config path, you can set the environment variable I18NEXT_DEFAULT_CONFIG_PATH.

For example, inside the .env file you can set a static path:

I18NEXT_DEFAULT_CONFIG_PATH=/path/to/project/apps/my-app/next-i18next.config.js

Or you can use a trick for dynamic path and set the following inside next.config.js:

process.env.I18NEXT_DEFAULT_CONFIG_PATH = `${__dirname}/next-i18next.config.js`;

// ... Some other imports

const { i18n } = require('./next-i18next.config');

// ... Some other code

module.exports = {
  i18n,
  ...
};

This means that the i18n configuration file will be in the same directory as next.config.js and it doesn't matter where your current working directory is. This helps for example for nx when you have monorepo and start your application from project root but the application is in apps/{appName}.

Notice If your config next-i18next.config.js is not in the same directory as next.config.js, you must copy it manually (or by custom script).

Notes

Vercel and Netlify

Some serverless PaaS may not be able to locate the path of your translations and require additional configuration. If you have filesystem issues using serverSideTranslations, set config.localePath to use path.resolve. An example can be found here.

Docker

For Docker deployment, note that if you use the Dockerfile from Next.js docs do not forget to copy next.config.js and next-i18next.config.js into the Docker image.

COPY --from=builder /app/next.config.js ./next.config.js
COPY --from=builder /app/next-i18next.config.js ./next-i18next.config.js

Asynchronous i18next backends

If you choose to use an i18next backend different to the built-in i18next-fs-backend, you will need to ensure the translation resources are loaded before you call the t function. Since React suspense is not yet supported for SSR, this can be solved in 2 different ways:

1) Preload the namespaces:

Set the ns option, like in this example. Doing this will ensure all translation resources are loaded on initialization.

2) Check the ready flag:

If you cannot or do not want to provide the ns array, calls to the t function will cause namespaces to be loaded on the fly. This means you'll need to handle the "not ready" state by checking ready === true or props.tReady === true. Not doing so will result in rendering your translations before they loaded, which will cause "save missing" be called despite the translations actually existing (just yet not loaded). This can be done with the useTranslation hook or the withTranslation HOC.

Static HTML Export SSG

Are you trying to generate a static HTML export by executing next export and are getting this error?

Error: i18n support is not compatible with next export. See here for more info on deploying: https://nextjs.org/docs/deployment

But there's a way to workaround that with the help of next-language-detector. Check out this blog post and this example project.

Translate in child components

You have multiple ways to use the t function in your child component:

  1. Pass the t function via props down to the children
  2. Pass the translated text via props down to the children, like in this example: https://github.com/i18next/next-i18next/blob/master/examples/simple/components/Header.tsx#L12
  3. Use the useTranslation function, like in this example:
    const { t } = useTranslation('footer')
  4. Use the withTranslation function

And in general, you always needs to be sure serverSideTranslations contains all namespaces you need in the tree.

Contributors

Thanks goes to these wonderful people (emoji key):

Rob Capellini
Rob Capellini

๐Ÿ’ป โš ๏ธ
Alexander Kachkaev
Alexander Kachkaev

๐Ÿ“ข ๐Ÿ’ฌ ๐Ÿค” ๐Ÿ’ป โš ๏ธ
Mathias Wรธbbe
Mathias Wรธbbe

๐Ÿ’ป ๐Ÿค” โš ๏ธ
Lucas Feliciano
Lucas Feliciano

๐Ÿค” ๐Ÿ‘€
Ryan Leung
Ryan Leung

๐Ÿ’ป
Nathan Friemel
Nathan Friemel

๐Ÿ’ป ๐Ÿ“– ๐Ÿ’ก ๐Ÿค”
Isaac Hinman
Isaac Hinman

๏ธ๏ธ๏ธ๏ธโ™ฟ๏ธ ๐Ÿ’ฌ ๐Ÿ”Š ๐Ÿ“ ๐Ÿ› ๐Ÿ’ผ ๐Ÿ’ป ๐Ÿ–‹ ๐Ÿ”ฃ ๐ŸŽจ ๐Ÿ“– ๐Ÿ“‹ ๐Ÿ’ก ๐Ÿ’ต ๐Ÿ” ๐Ÿค” ๐Ÿš‡ ๐Ÿšง ๐Ÿง‘โ€๐Ÿซ ๐Ÿ“ฆ ๐Ÿ”Œ ๐Ÿ“† ๐Ÿ”ฌ ๐Ÿ‘€ ๐Ÿ›ก๏ธ ๐Ÿ“ข โš ๏ธ ๐Ÿ”ง ๐ŸŒ โœ… ๐Ÿ““ ๐Ÿ“น
Adriano Raiano
Adriano Raiano

๏ธ๏ธ๏ธ๏ธโ™ฟ๏ธ ๐Ÿ’ฌ ๐Ÿ”Š ๐Ÿ“ ๐Ÿ› ๐Ÿ’ผ ๐Ÿ’ป ๐Ÿ–‹ ๐Ÿ”ฃ ๐ŸŽจ ๐Ÿ“– ๐Ÿ“‹ ๐Ÿ’ก ๐Ÿ’ต ๐Ÿ” ๐Ÿค” ๐Ÿš‡ ๐Ÿšง ๐Ÿง‘โ€๐Ÿซ ๐Ÿ“ฆ ๐Ÿ”Œ ๐Ÿ“† ๐Ÿ”ฌ ๐Ÿ‘€ ๐Ÿ›ก๏ธ ๐Ÿ“ข โš ๏ธ ๐Ÿ”ง ๐ŸŒ โœ… ๐Ÿ““ ๐Ÿ“น
Felix Mosheev
Felix Mosheev

๐Ÿ’ฌ ๐Ÿ’ป ๐Ÿ“ข โš ๏ธ
Sรฉbastien Vanvelthem
Sรฉbastien Vanvelthem

๐Ÿ’ป ๐Ÿ“– ๐Ÿ’ก ๐Ÿšง ๐Ÿ““

This project follows the all-contributors specification. Contributions of any kind welcome!


Gold Sponsors


localization as a service - locize.com

Needing a translation management? Want to edit your translations with an InContext Editor? Use the original provided to you by the maintainers of i18next!

locize

With using locize you directly support the future of i18next and next-i18next.


More Repositories

1

react-i18next

Internationalization for react done right. Using the i18next i18n ecosystem.
JavaScript
9,188
star
2

i18next

i18next: learn once - translate everywhere
JavaScript
7,594
star
3

i18next-browser-languageDetector

language detector used in browser environment for i18next
JavaScript
842
star
4

i18next-scanner

Scan your code, extract translation keys/values, and merge them into i18n resource files.
JavaScript
554
star
5

i18next-parser

Parse your code to extract translation keys/values and manage your catalog files
JavaScript
468
star
6

i18next-http-backend

i18next-http-backend is a backend layer for i18next using in Node.js, in the browser and for Deno.
JavaScript
434
star
7

i18next-node

[deprecated] can be replaced with v2 of i18next
JavaScript
261
star
8

i18next-xhr-backend

[deprecated] can be replaced with i18next-http-backend
JavaScript
254
star
9

i18next-express-middleware

[deprecated] can be replaced with i18next-http-middleware
JavaScript
207
star
10

i18next-gettext-converter

converts gettext .mo or .po to 18next json format and vice versa
JavaScript
193
star
11

next-app-dir-i18next-example

Next.js 13/14 app directory feature in combination with i18next
JavaScript
169
star
12

jquery-i18next

jQuery-i18next is a jQuery based Javascript internationalization library on top of i18next. It helps you to easily internationalize your web applications.
HTML
168
star
13

i18next-gitbook

HTML
163
star
14

ng-i18next

translation for AngularJS using i18next
JavaScript
161
star
15

i18next-http-middleware

i18next-http-middleware is a middleware to be used with Node.js web frameworks like express or Fastify and also for Deno.
JavaScript
148
star
16

next-app-dir-i18next-example-ts

Next.js 13/14 app directory feature in combination with i18next
TypeScript
105
star
17

react-i18next-gitbook

CSS
95
star
18

i18next-fs-backend

i18next-fs-backend is a backend layer for i18next using in Node.js and for Deno to load translations from the filesystem.
JavaScript
92
star
19

i18next-localstorage-backend

This is a i18next cache layer to be used in the browser. It will load and cache resources from localStorage and can be used in combination with the chained backend.
JavaScript
83
star
20

i18next-icu

i18nFormat plugin to use ICU format with i18next
JavaScript
79
star
21

i18next-vue

Internationalization for Vue 2 & 3 using the i18next ecosystem
TypeScript
70
star
22

i18next-node-fs-backend

[deprecated] can be replaced with i18next-fs-backend
JavaScript
65
star
23

i18next-chained-backend

An i18next backend to chain multiple backends (add fallbacks, caches, ...)
JavaScript
64
star
24

i18nextify

enables localization of any page with zero effort.
JavaScript
61
star
25

next-language-detector

This package helps to handle language detection in next.js when using static servers only.
JavaScript
57
star
26

i18next-resources-to-backend

This package helps to transform resources to an i18next backend
JavaScript
53
star
27

i18next-android

i18next internationalization library for Android
Java
42
star
28

i18next-webtranslate

[deprecated] Translation User Interface for i18next - successor locize.com
JavaScript
41
star
29

i18next-resources-for-ts

This package helps to transform resources to be used in a typesafe i18next project.
JavaScript
31
star
30

i18next-ios

i18next internationalization library for iOS
Objective-C
29
star
31

i18next-sprintf-postProcessor

sprintf post processor for i18next
JavaScript
28
star
32

i18next-localStorage-cache

[deprecated] caching layer for i18next using browsers localStorage
JavaScript
25
star
33

i18next-intervalPlural-postProcessor

post processor for i18next enabling interval plurals
JavaScript
25
star
34

i18next-fluent

i18nFormat plugin to use mozilla fluent format with i18next
JavaScript
22
star
35

i18next-multiload-backend-adapter

This is a i18next backend to enable another backend's multiload behaviour of loading multiple lng-ns combinations with one request.
JavaScript
16
star
36

next-app-dir-i18next-no-locale-path-example

JavaScript
15
star
37

i18next-emoji-postprocessor

This is a postProcessor plugin for i18next using in Node.js and in the browser that replaces all words with emojis.
JavaScript
10
star
38

i18next-v4-format-converter

This package helps to convert old i18next translation resources to the new i18next v4 json format.
JavaScript
9
star
39

i18next.com

[obsolete] was replaced by i18next-gitbook! i18next.com website
JavaScript
7
star
40

grunt-i18next

Bundle language resource files for i18next.
JavaScript
6
star
41

i18next-translation-parser

parses i18next translations to AST
JavaScript
6
star
42

i18next-node-remote-backend

[deprecated] can be replaced with i18next-http-backend
JavaScript
6
star
43

omi-i18n

omi-i18n solution for omi.js using i18next ecosystem
JavaScript
5
star
44

i18next-fluent-backend

i18next backend to load fluent formatted .ftl files via xhr
JavaScript
4
star
45

i18next-polyglot

i18nFormat plugin to use airbnb/polyglot.js format with i18next
JavaScript
4
star
46

i18next-cli-app-example

i18next in a cli app
JavaScript
2
star
47

bs-react-i18next

Bucklescript + ReasonReact binding for react-i18next components.
OCaml
1
star