i18n in Next js without sub-path or domain routing.

Sanny Rai
3 min readApr 21, 2022

--

Ni18n is the solution you can implement for the problem. But if you want to know how I reached at this point and want to use in its most basic form, please proceed.

One of the task assigned to me by team lead in one of our just started next js project was to implement multilingual support. To put it very simply, my task was to create a language selector component in navbar of our web app, and selecting any particular language would convert every hardcoded text into that particular language.

I first started searching about the ways to do that in Next js official documentation. Here I found two strategies to meet my goal. They are
1. Sub-path routing.
2. Domain routing.
But sadly, later I realized our objective was to implement the feature but without adding any extra word either in form of sub-path or prefixing/suffixing domain name of our web app.

I further began googling with different search terms like “localization in next js without subpath”. Most of the results were with the default approach. Finally after hours of searching, I found a web site called i18next. It provides link to different libraries that implemented concept of i18next for different frameworks. For Next js, there are three (at the time of writing) one of which is Ni18n. Among two of the remaining, one uses the sub-path method and other didn’t make sense to me 😥.

Enough of the story, let’s try to use this library just to meet the requirement.

Create next js project if you haven’t.

The first thing we are going to do is its installation. Use following to install i18next, react-i18next and ni18n.

yarn add i18next react-i18next ni18nornpm install i18next react-i18next ni18n

Now create a file called ni18n.config.js or ni18n.config.ts (if you are using typescript) at top level of our project folder and paste following inside it.

const supportedLngs = [‘en’, ‘np’]export const ni18nConfig = {
supportedLngs,
ns: [‘translation’],
}

The above code is pretty straight forward. We are creating an object called ni18nConfig by providing list of language to be supported and list of namespaces. Namespaces are feature that helps you to separate translations that gets loaded into different files. This is more useful as our app size grows. But for now, we will place every translations in a file called translation.json inside locale folder which we will create shortly under public folder.

As mentioned above, create folder named locale inside public folder and inside it create another two folders each for our supported locale. In our case, its ‘en’ and ‘np’ and place translation files under these folders individually as show below.

These json file contains the text that you want to translated depending upon the language you choose. For testing purpose fill your translation.json file with following content.

// en/translation.json{
"hello": "Hello"
}
// np/translation.json{
"hello": "नमस्कार"
}

Translation won’t work with just this. You need to wrap your root component with the appWithI18Next function provided by ni18n which will initialize the i18next instance and provide it as a context for all the children.

import {appWithI18Next} from "ni18n";
import {ni18nConfig} from "../ni18n.config";

function MyApp({Component, pageProps}) {
return (
<Component {...pageProps} />
)
}
export default appWithI18Next(MyApp, ni18nConfig)

After this, now we can call useTranslation provided by react-i18next as shown below in any part of your app.

import { useTranslation } from ‘react-i18next’export const Greeting = () => {
const { t } = useTranslation()
return <>{t(‘hello’)}</>
}

Now the last step is to make our app sync with the language we choose. This can be done by providing desired language option in useSyncLanguage() function provided by ni18n.

import {appWithI18Next, useSyncLanguage} from "ni18n";
import {ni18nConfig} from "../ni18n.config";

function MyApp({Component, pageProps}) {
const locale =
typeof window !== 'undefined' && window.localStorage.getItem('MY_LANGUAGE')

useSyncLanguage(locale)

return (
<Component {...pageProps} />
)
}

export default appWithI18Next(MyApp, ni18nConfig)

Here we are using localStorage to store and retrieve our selected language.

To perform language change, call changeLanguage() provided by i18next by passing desired language and you should be good to go.

This is the use of this library in most basic form. To learn more, please head to official documentation of ni18n.

Here is the link to the code.

--

--