Translating your Next.js application

by Mileta

Next.js provides server-side rendering for React applications. In this post, we will learn how to translate the text in a Next.js app by using next-translate.

Before we proceed ensure you have the following installed on your system:

  • node
  • npm
  • yarn

Project setup

First, we need to create a project. We will do this by using the create-next-app that is provided by the NextJS team.

In terminal type :

1 npx create-next-app

This will run an interactive prompt that will ask for the project name. You can name it whatever you like. For the sake of this post, we named ours next-translate. It will also install all the required dependencies for the project to work. After that go inside the newly created project and run yarn dev command. After that visit localhost:3000 and you will see the starter page template that looks like this.


We don't need these components and pages from the starter template so now you'll need to delete the styles/Home.module.css file, and api directory that can be found inside of pages. Open up pages/index.js, delete everything from there, and paste this

1 2 3 4 5 6 7 const Home = () => { return ( <h1>Home</h1> ) } export default Home

We will also have an about page so let's create one now.

1 2 3 4 5 6 7 const About = () => { return ( <h1>About</h1> ) } export default About

After getting this done we need to install a library for translating our pages. Open up a terminal in your project directory and type yarn add next-translate IF everything is installed and working correctly we can move on to translating our app.


First, we need to create next.config.js in the project root, and after doing that paste the code below. It is required for the plugin to be properly loaded.

1 2 3 const nextTranslate = require('next-translate') module.exports = nextTranslate()

After that, we need to add the i18n.json configuration file in the project root. We need this so that next-translate knows what locales are we going to have and which translation file is assigned to which page.

1 2 3 4 5 6 7 8 { "locales": ["en", "me"], "defaultLocale": "en", "pages": { "/": ["home"], "/about": ["about"] } }
  • In the locales array we specify all the locales that we want to use in our project (uses ISO format)
  • defaultLocale is required so that next-translate knows what is our default language (uses ISO format)
  • In pages we specify namespaces used in each page. To add namespaces to all pages use (eg: {"*": ["common"]}). You can also use regex to specify what locales are used in pages. \ \ After creating configuration files we now need to specify namespaces. By default, they are specified inside the /locales` root directory.
1 2 3 4 5 6 ├── en │ ├── about.json │ └── home.json └── me ├── about.json └── home.json

In these .json files we will specify translations for all our pages. Note that file names match ones from the i18n.json configuration that we wrote earlier. The basic content of en/home.json looks like this

1 2 3 4 5 { "title": "Home Page", "description": "This is a home page description written in the English language.", "current-language": "Current locale is set to /{{language}}" }

You probably noticed {{language}} syntax. This allows us to use variables in our translations if we have dynamic content. Using translation in the app is pretty simple and straightforward. First we import useTranslation hook from next-translate/useTranslation. Using that hook we then import namespace and function that will allow us to use translations from .json files that we specified in /locales directory. This is what our updated index.js looks like.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import useTranslation from "next-translate/useTranslation" const Home = () => { const { t, lang } = useTranslation("home") const title = t("title") const description = t("description") const language = t("language", { language: lang }) return ( <> <h1>{title}</h1> <h4>{description}</h4> <p>{language}</p> </> ) } export default Home

Let's explain line by line what is happening here.

By using the useTranslation hook we got access to 2 variables, t, and lang. t is used for translating, and in lang we have access to the currently active locale.

By adding a parameter to the useTranslation hook we are specifying the default namespace for that page. That parameter is optional since the next-translate plugin will load only the namespace that the page needs. It does so by reading the i18n.json configuration that we created in the root directory.

t("title") will load translation from /locales/(en/me)/home.json file. We can then assign it to a variable and use it on the page.

By using t("language", { language: lang }) we are loading translation that is assigned to language, while also passing variable to it. It will return as a translation with a variable added to it.

Routing to different locales

From version 10 of NextJS Internationalized Routing is supported by default, which means that we can load different locales without using external libraries.

Let's say that you have 2 different locales en and me. We need to give the user an option to switch to a different locale if he/she wants to. We can achieve this easily by using the Link component from next/link.

Link component

In NextJS Link component is used for client-side routing, and if we want to send the user to another page we can use this code snippet

1 2 3 4 5 import Link from "next/link"; <Link href="/about"> <a>About</a> </Link>

but if we want to send the user to the /about page with a different locale we can pass the locale prop to Link component like this

1 2 3 <Link href="/about" locale="en"> <a>About</a> </Link>

This also means that next-translate will automatically read that locale and serve translated content without any additional checks.

As we can see, translation in NextJS is convenient, easy to set-up, and use. You can find the code by clicking here. It is a GitHub repository with the code from this article that you can use and modify. The project in this repository contains basic styling and routing.


Development, NextJS