Translate Nextjs apps using next-translate
Martin Pacheco
Posted on April 29, 2023
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
Install the next-translate library
npm install next-translate
Add the plugin next-translate-plugin
npm install next-translate-plugin -D
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'],
},
}
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;
}
})
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;
}
})
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
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"
}
locales/common/es.json
{
"hero-title" : "Traduciendo apps en Nextjs",
"hero-description" : "Las librerías de internacionalización son útiles"
}
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>
)
}
6. Run your app
Run npm run dev
and got to the this different urls:
English
http://localhost:3000/en
Spanish
http://localhost:3000/es
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>
);
}
At end, you can use sites like i18next to translate json files keeping the keys untouched, so translations can be easier.
Happy translations!
Posted on April 29, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.