A lot of people, like me, are trying to get jobs outside their own country so to be able to do that we need to learn and master other languages. In the programming world (and to be honest, in almost all areas that involve technology in some degree), the universal language is the english.
With that, beyond mastering communicating (which I mean, talking and listening) in those languages, we need to write our CV, blog posts and copies in this universal language. So, today I'll be writing about how to manage a multi-language website using Next.js.
Setting up the Project
Let's set up our Next.js project using the create-next-app
lib, which give us a pretty good template (you can follow up to see options in here)
npx create-next-app@latest
# or
yarn create next-app
# or
pnpm create next-app
Altought Next.js providers internationalised routing, it doesn't handle management of translation content, so to be able to achieve that we're going to install next-i18next
dependency for our project:
yarn add next-i18next react-i18next i18next
# or
npm install --save next-i18next react-i18next i18next
Configuring Next.js with I18n
Following the next-i18next
documentation, we need set up the project for it:
- First, create a
next-i18next.config.js
file in the root of your project.
- Inside it we need to add the locales configuration, based on your locale languages, which in my case is:
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'pt-BR'],
},
}
- Next, we're going to modify the
next.config.js
file, by passing the i18n config that we previously set up on ournext-i18next.config.js
file.
const { i18n } = require('./next-i18next.config')
module.exports = {
{...}
i18n,
}
- Now we need to create a
locales
folder insidepublic
and create our different languages folder with acommon.json
file each. It's important to say that thecommon.json
it's basically a set of texts that will be used for all components, but you can create others for specific components)
└── public
└── locales
├── en
| └── common.json
└── pt-BR
└── common.json
- Mostly important and the last step of the configuration, we need to connect the I18n with our app. Open the
pages/_app.js
directory and wrap the default export withappWithTranslation
fromnext-i18next
, following as below:
import '../styles/globals.css'
import { appWithTranslation } from 'next-i18next'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default appWithTranslation(MyApp)
That's all! Now we have all configuration set up and we can start using it.
Implementing different languages in components using SSR
It's important to know that next-i18next
added support for using SSR, which basically can be done by using the getStaticProps
or getServerSideProps
from Next.js. But let's continue:
- Let's define some example text in all our different locale folders, I will be creating a title field:
// locale/en/common.json
{
"title": "Building a multi-language website with Next.js"
}
// locale/pt-BR/common.json
{
"title": "Construindo um website com suporte a diversas linguagens, utilizando Next.js"
}
- As mentioned above, to have Next.js support, we need to use
getStaticProps
orgetServerSideProps
(you can check usage details of each here). With the decision in place, we're going to importserverSideTranslations
fromnext-i18next
and add to our choosen method.
getStaticProps
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
export const getStaticProps = async ({ locale }) => {
return {
props: {
...(await serverSideTranslations(locale, ['common'])),
}
}
}
getServerSideProps
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
export const getServerSideProps = async ({ locale }) => {
return {
props: {
...(await serverSideTranslations(locale, ['common'])),
}
}
}
Another really important thing to remember is that we can have specific translations (as I mentioned prior) for each component. Let's say I created a new file in our locales named example.json
, and we want to add the translation to the same component. We would do:
export const getStaticProps = async ({ locale }) => {
return {
props: {
...(await serverSideTranslations(locale, ['common',
'example']))
}
}
}
- Last, the display!! Let's add the translation itself to our Component. Let's import
useTranslations
fromreact-i18next
dependency and destructure it to get propertyt
(which will be then used for translating):
import { useTranslation } from 'react-i18next'
export default function Home() {
const { t } = useTranslation('common')
return (
<div>
<main>
<h1>
{t('title')}
</h1>
</main>
</div>
)
}
export const getStaticProps = async ({ locale }) => {
return {
props: {
...(await serverSideTranslations(locale, ['common']))
}
}
}
Seeing the Results
Accessing your YOUR_URL/$LANGUAGE
, which in my case is http://localhost:3000/${CURRENT_LANGUAGE}
.
English - http://localhost:3000/en
Portuguese - http://localhost:3000/pt-BR
Conclusion
There we have it! I hope the post it's clear and you guys were able to follow. Feel free to tag me into any doubts and providing any feedbacks. In part 2, we're going to understand on how to build a simple toggle for changing languages! Stay tuned
To check all the work done here, you can go to the GitHub Repository