Next.js provides built-in internationalized routing capabilities. At the same time, it does not offer a translation content management system. All it does is keep your locales and URLs synchronized. To actually create a multilingual site in Next.js, you need to handle the translations yourself. That is cumbersome and boilerplate. Thankfully, there is next-i18next
, a Next.js 18n library that makes localization easier.
At the end of this tutorial, you will know how to set up i18n in Next.js. Let’s get started!
What Is next-i18next?
next-i18next
is a full-featured localization framework for Next.js applications. It provides an easy way to manage internationalization and localization. Set it up and you can start adding your translated content into some JSON files. The library with take care of the rest.
The framework relies on i18next
and react-i18next
. These are the two most popular i18n libraries for JavaScript and React, respectively. In detail, next-i18next
adds support for server-side rendering (SSR), static site generation (SSG), and incremental static regeneration (ISR). Note that if you are using Next.js 13 with the app
directory, you do not need next-i18next
. You can directly use i18next
and react-i18next
as explained in the guide mentioned in the documentation.
With next-i18next
, you can build a Next.js site that supports multiple languages with no effort. Check out what it has to offer in the official live demo!
Why Is next-i18next Better Than Other i18n Libraries?
There are many Next.js i18n libraries available. For example, react-intl
has millions of weekly downloads. Yet, none of them is as complete as next-i18next
. Specifically, it is easy to use, requires little setup, and offers a lot of features. This is what makes it the best Next.js i18n library.
Integrating next-i18next
into a Next.js app takes only a few steps. Configuring it is even simpler. You can then start passing translations to your page-level components as props through getServerSideProps()
or getStaticProps()
. This complements the internationalized routing functionality offered by Next.js, equipping you with everything you need to deal with localized content.
Some key features provided by next-i18next
include:
- Support for SSR and SSG
- Components and hooks to translate your React components
- Code-splitting capabilities with translations stored in JSON files and not in components
- Customizable language-switching behavior
- Support for placeholders, pluralization, and namespaces from
i18next
- Automatic language detection based on user’s browser language
Overall, next-i18next
is a powerful and flexible i18n framework. It is now time to learn how to use it to build a multi-language Next.js site!
How to Set Up next-i18next in Next.js
In this step-by-step section, you will see how to integrate next-i18next
into an existing Next.js site.
Prerequisites
To follow this tutorial, you first need a Next.js app to localize. If you want to start from scratch, you can initialize a Next.js project with:
npx create-next-app@latest
Code language: CSS (css)
Answer all questions, wait for the dependencies to be installed, and run the command below to launch the development server:
npm run dev
If the initialization process terminated as expected, you should be seeing the default Create Next App page that follows:
Fantastic! You now have a Next.js project ready to be turned into a multilingual site!
Install next-i18next
Add next-i18next
to your project’s dependencies with:
npm install next-i18next react-i18next i18next
Note that the installation command also involves react-i18next
and i18next
. This is because those two libraries are next-i18next
‘s peer dependencies. In other words, next-i18next
will not work without them.
Configure Your Next.js App
Create a next-i18next.config.js
file in the root of your project. That is the configuration file required by next-i18next
. Initialize it as follows:
// next-i18next.config.js
module.exports = {
i18n: {
// all the locales supported in the application
locales: ['en', 'it', 'es'],
// the default locale to be used when visiting
// a non-localized route (e.g. `/about`)
defaultLocale: 'en'
},
}
Code language: JavaScript (javascript)
This file has to export an i18n
object with a structure as defined by Next.js. In particular, that should contain a locales
array with the languages supported by your site and a defaultLocale
variable with one of the locales included in the array. Note that locales must be specified using their UTS locale identifiers.
To enable the Next.js localized routing feature, you then need to pass the i18n
object to the next.config.js
file:
// next.config.js
const { i18n } = require('./next-i18next.config')
const nextConfig = {
i18n,
reactStrictMode: true,
}
module.exports = nextConfig
Code language: JavaScript (javascript)
Finally, update your src/pages/_app.js
file with this code:
// src/pages/_app.js
import { appWithTranslation } from 'next-i18next'
const App = ({ Component, pageProps }) => (
<Component {...pageProps} />
)
export default appWithTranslation(App)
Code language: JavaScript (javascript)
In detail, you need to wrap your top-level App
component with appWithTranslation()
. This is a React HOC (High-Order Component) that enables the i18n features exposed by next-i18next
globally in your Next.js app.
Perfect! Your Next.js app is now ready to accept some translation content.
Structure Your Project
next-i18next
expects your translation JSON files to be organized in the public
folder as such:
public
└── locales
├── en
| └── common.json
├── es
| └── common.json
└── it
└── common.json
Code language: PHP (php)
You can customize this default behavior by setting the localePath
and localeStructure
values in your next-i18next.config.js
file.
This is what your project structure now looks like:
Note the structure of the locales
folder in the public
directory. For now, the common.json
files are empty.
Define a Localized Page
It is now time to build a Next.js page with some multilingual content. Modify the home page of your site by updating the src/pages/index.js
file:
// src/pages/index.js
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import { useTranslation } from 'next-i18next'
export default function Home() {
const { t } = useTranslation()
return (
<>
<h1>{t("HELLO_WORLD")}</h1>
</>
)
}
export async function getStaticProps(context) {
// extract the locale identifier from the URL
const { locale } = context
return {
props: {
// pass the translation props to the page component
...(await serverSideTranslations(locale)),
},
}
}
Code language: JavaScript (javascript)
Let’s understand how this component works, breaking it down into smaller steps.
The getStaticProps()
Next.js function takes care of defining the rendering strategy for the page. As explained in the official doc, you can retrieve the current locale read from the page URL from the context provided to the function. In particular, /
, /es
, and /it
all redirect to the home page, but:
- In
/
,locale
isen
becausedefaultLocale
isen
- In
/es
,locale
ises
- In
/it
,locale
isit
This is how the Next.js internationalization routing functionality works.
Then, the serverSideTranslations()
HOC from next-i18next
accepts the locale as a parameter and is responsible for passing translations and configuration options as props to the frontend component pages. You need to add the result of this function to the props of any page that requires translations.
Keep in mind that you can use this same backend logic in both getStaticProps()
or getServerSideProps()
.
The page-level component or any components under its tree can now use the useTranslation()
hook from next-i18next
. As stressed in the doc, do not import useTranslation()
from react-i18next
. This hook returns the t
function, which accepts a key string and returns the value read from the corresponding common.json
translation file. If no matching translations are found, it returns the key string.
Verify that behavior by launching the development server with:
npm run dev
Open http://localhost:3000
in your browser.
Since all common.json
file are empty, no matter what /
, /es
, or /it
page you visit, you will always see:
Time to add some translations!
Translate Your Content
In your common.json
files, add a HELLO_WORLD
key:
/en/common.json
:{ "HELLO_WORLD": "Hello, World!" }
/es/common.json
:{ "HELLO_WORLD": "¡Hola, mundo!" }
/it/common.json
:{ "HELLO_WORLD": "Ciao, mondo!" }
Do not forget that every time you modify something in the public
folder, you need to restart the development server to see the changes. Kill the current instance and relaunch it. Unlike the .env
files, the files under public
are not hot reloaded.
Multilingual site in Next.JS: last steps
Open the three localized versions of your home page in your browser, you will see:
http://localhost:3000/
:
http://localhost:3000/es
:
http://localhost:3000/it
:
Et voilà! You just learn how to build a multilingual site in Next.js!
You can find the entire code of the i18n Next.js sample app developed here in the GitHub repository supporting the tutorial. Clone it and launch the blog locally with:
git clone https://github.com/Tonel/i18n-next-demo
cd i18n-next-demo
npm i
npm run dev
Code language: PHP (php)
Visit http://localhost:3000
and enjoy your localized demo app!
Conclusion
In this article, you saw how to create a multi-language app in Next.js. With the help of next-i18next
, you can easily implement i18n in Next.js, making it easy to integrate translated content into your site.
First, you understood what i18n features Next.js natively offers and why you need an extra dependency to handle translation logic. You learned why next-i18next
is the best i18n library for that, and how to set it up in a step-by-step tutorial. Building a localized site in Next.js has never been easier!
Thanks for reading! We hope you found this article helpful!
You might also want to read about
How to Create an MDX Blog in TypeScript With Next.js
How to optimize Next.JS for production