DEV Community

Cover image for Translate Nextjs apps using next-translate
Martin Pacheco
Martin Pacheco

Posted on • Updated on

Translate Nextjs apps using next-translate

Since there have been some changes in the versions of Nextjs (v 13.3.1 at the time of writing this post), this doc can be used as a reference to internationalize your application using the next-translate (v2.0.5) library.

1. Create an next app

npx create-next-app translation-app
Enter fullscreen mode Exit fullscreen mode

Install the next-translate library

npm install next-translate
Enter fullscreen mode Exit fullscreen mode

Add the plugin next-translate-plugin

npm install next-translate-plugin -D
Enter fullscreen mode Exit fullscreen mode

2. Internationalization configuration file

Create a file named i18n.js in the root path of the directory. This file will specify the configuration of the supported translations. You can read more about the configuration on the documentation page.

In this case the locales array will handle English (en) and Spanish (es) languages:

i18n.js file

module.exports = {
 locales: ['en', 'es'],
 defaultLocale: 'es',
 localeDetection: false,
 pages: {
   '*': ['common'],
 },
}
Enter fullscreen mode Exit fullscreen mode

You can use namespaces to define sections for the whole app, useful if handling large translations.
For this exercise the regex expression ( * ) just will share the ‘common’ namespace with all the pages.

3. Configure the next.config.js file

Add the next code to this file:

const nextTranslate = require('next-translate-plugin')

module.exports = nextTranslate({
 webpack: (config, { isServer, webpack }) => {
   return config;
 }
})
Enter fullscreen mode Exit fullscreen mode

You will end up with something like this:

next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
 reactStrictMode: true,
}
module.exports = nextConfig

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

4. Create the translation files

Translations files are json files that help to manage the diferent languages for the app.

In the root directory create a folder called locales.
Then create a folder for each language: en es

For each of those folders you will need to create json files named as the namespace specified before. In this case it is common. You will end up with an structure like this:

.
├── i18n.js
├── locales
│   ├── en
│   │   └── common.json
│   └── es
│       └── common.json
├── next.config.js
├── next-env.d.ts
├── package.json
├── package-lock.json
├── postcss.config.js
├── public
│   ├── favicon.ico
│   ├── next.svg
│   └── vercel.svg
├── README.md
├── src
│   ├── pages
│   │   ├── api
│   │   │   └── hello.ts
│   │   ├── _app.tsx
│   │   ├── _document.tsx
│   │   └── index.tsx
│   └── styles
│       └── globals.css
├── tailwind.config.js
└── tsconfig.json
Enter fullscreen mode Exit fullscreen mode

Add to each json file the key-label data needed to translate the app.

locales/common/en.json

{
   "hero-title" : "Translating Nextjs apps",
   "hero-description" : "Internationalization libraries are useful"
}
Enter fullscreen mode Exit fullscreen mode

locales/common/es.json

{
    "hero-title" : "Traduciendo apps en Nextjs",
    "hero-description" : "Las librerías de internacionalización son útiles"
}
Enter fullscreen mode Exit fullscreen mode

5. Display your translations.

Update your components as shown next.
Import the useTranslation function:
import useTranslation from 'next-translate/useTranslation'

Inside the components functions, call the t function:
const { t } = useTranslation('common')

For each text that you want to translate, call the t function and pass the key for your label:
{ t('hero-title') }

This is the entire component file:

// Home.tsx
import Image from 'next/image'
import { Inter } from 'next/font/google'

// useTranslation function from next-translate
import useTranslation from 'next-translate/useTranslation'

const inter = Inter({ subsets: ['latin'] })

export default function Home() {

  // t function from useTranslation, using the common namespace
  const { t } = useTranslation('common')

  return (
    <div className='h-screen flex flex-col justify-center items-center'>
       <h1 className='text-xl font-bold'>{ t('hero-title') }</h1>
       <p>{ t('hero-description') }</p>
   </div>
 )
}

Enter fullscreen mode Exit fullscreen mode

6. Run your app

Run npm run dev and got to the this different urls:

English
http://localhost:3000/en

App translated in english

Spanish
http://localhost:3000/es

App translated in spanish

If you want to change between languages using buttons, check the suggested methodology in the documentation

Here is an example of a component that will display all the languages options based on the locales file.

ChangeLanguage.tsx

import { locales } from '../../i18n'
import useTranslation from 'next-translate/useTranslation'
import setLanguage from 'next-translate/setLanguage'

export default function ChangeLanguage() {

    const { t, lang } = useTranslation()

    console.log( locales )

    let langs = []

    for(let l of locales){
        if( l !== lang ){
            langs.push(<button  key={l} onClick={async () => await setLanguage(l)}> { l.toUpperCase() } </button>)
        }
    }

    return (
        <div>
            { langs }
        </div>
    );
  }
Enter fullscreen mode Exit fullscreen mode

At end, you can use sites like i18next to translate json files keeping the keys untouched, so translations can be easier.

Happy translations!

Top comments (0)