Adding path-based internationalization with i18next in React and Next.js Server Side (SSR)

Tiempo de lectura: 3 minutos

Today we are going to learn how we can add Server Side Internationalization so that our Next.js server directly returns translated pages to benefit SEO.

The first thing we have to do is to install the necessary dependencies:

npm install i18next next-i18next @types/i18next @types/react-i18next --save

Then we are going to create a configuration file next-i18next.config.js at the root of the project:

module.exports = {
  debug: process.env.NODE_ENV === 'development',
  i18n: {
    locales: ['es', 'en'],
    defaultLocale: 'es',
  },
};

In my case, I am going to translate to Spanish and English. By default, I have selected the Spanish language.

Now let’s import the configuration into our next.config.msj file, add:

/** @type {import('next').NextConfig} */
import pkg from './next-i18next.config.js';
const { i18n } = pkg;
const nextConfig = {
  i18n,
};

export default nextConfig;

Well, now we have to create the translation files.

To do this, let’s go to public and create a folder called locales, inside we create two folders, one called es/ and another called en/:

Here we are going to create our translation .json files. Let’s create one called common.json (we always have to have common.json created since it is the default one) and create it in both es/ and en/.

Content es/common.json

{
    "title_app": "Mi prueba con i18next",
  }

Content en/common.json

{
    "title_app": "My test with i18next",
  }

Now we have to go or create a file _app.tsx inside pages/ (here I explaincómo crearlo) and add:

import { appWithTranslation } from 'next-i18next';

function MyApp({ Component, pageProps }: AppProps) {
  .....
}

export default appWithTranslation(MyApp);

We must add the import and the export default provided.

To create the language page redirection by path, we are going to create a middleware.tsx file (here I explain what a middleware is in Next.js)

import { NextRequest, NextResponse } from 'next/server'

const PUBLIC_FILE = /\.(.*)$/

export async function middleware(req: NextRequest) {
  if (
    req.nextUrl.pathname.startsWith('/_next') 
    req.nextUrl.pathname.includes('/api/') 
    PUBLIC_FILE.test(req.nextUrl.pathname)
  ) {
    return
  }

  if (req.nextUrl.locale === 'default') {
    const locale = req.cookies.get('NEXT_LOCALE')?.value  'es'

    // If the locale is 'es', do not redirect
    if (locale === 'es') {
      return
    }

    return NextResponse.redirect(
      new URL(`/${locale}${req.nextUrl.pathname}${req.nextUrl.search}`, req.url)
    )
  }
}

In this file, I have indicated that it redirects all calls without interfering in the initial routing of Next.js whether or not the language path /en or /es is included.

I have forced it so that by default it does not include the path for the default language (es) in this way the translations will behave:

mysite.web/ -> Spanish

mysite.web/en -> English

Now we need to configure each screen where we want to apply Server Side Rendering (SSR) translations

Let’s go for example to index.tsx and add:

Import i18next:

import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

Add the i18next translation hook:

const Home: React.FC<HomeProps> = ({ articles }) => {

  const { t } = useTranslation();

....

To use the translation we will put:

        {t('common:title_app')}

We indicate common: to refer to the file where the translation is.

Now we can move on to the server-side rendering part, since as it is now it will only translate on the client side.

We go or create the function export async function getServerSideProps(context: any) {

This function applies to Server Side rendering.

We add:

  let { locale } = context;

  // If locale is not defined, set a default value
  if (!locale) {
    locale = 'es'; // Replace 'es' with your default location
  }

  return {
      props: {
        ...(await serverSideTranslations(locale, ['common'])),
      },
    };

We get the locale, as it can detect by default the translation either from the path or from the browser itself.

I indicate that if it fails to get the locale, use «es» by default.

Finally, I return serverSideTranslations to the React component. Here I include the files I am going to need, in my case it is only common.json if we want to add more it would be like this:

        ...(await serverSideTranslations(locale, ['common', "translations_2" , "translations_3"])),

If we want to translate within the

Leave a Comment