DEV Community

velan
velan

Posted on

Next.js: Multilanguage support with internationalized routing

Let's create a simple Next.js starter project with multiple languages - English (en-US), Tamil (ta-IN), Hindi (hi-IN), Kannada (kn-IN) support using Next.js native i18n.

👉 Source code of this article available at GitHub

What are we going to do

  • Creating a Next js app (v10.x.x) with boostrap.css
  • Configuring i18n in next.config.js
  • Create locale JSON
  • Read locale from the route and display in the HTML

Set up

Create a Next js app and add bootstrap, swr as dependency
npx create-next-app
npm i -s bootstrap
npm i -s swr

Run the app
npm run dev

Create a new page called home under pages

const Home = () => {
    return (
        <h1>Hey! I am home - English</h1>
    )
}

export default Home;
Enter fullscreen mode Exit fullscreen mode

Navigate to http://localhost:3000/home
image

Configuring i18n route

There are two ways to handle locale: Sub-path and domain routing. Here we explore Sub-path routing

Sub-path routing is basically prefixing locale code in front of existing routes without any impact on actual routing.

eg: /home,
/en-US/home,
/ta-IN/home,
/hi-IN/home

Now if you try to access one of the routes eg: /en-us/home, you will see 404 message. Because locale-based routing not enabled yet.
image
image

To enable locale-based routing, Create a next.config.js file in the project root as below.

module.exports = {
    i18n: {
        locales: ['en-us', 'ta-in', 'hi-in', 'kn-in'],
        defaultLocale: 'en-us'
    }
}
Enter fullscreen mode Exit fullscreen mode

💡 checkout i18n locale code reference for different languages here

💡 Do remember to stop and start the app, whenever modifying next.config.js

Now try again to access locale-based route /en-us/home
Boom, it works!! 😍
image

Let's try with another locale code /ta-in/home.
image
The page didn't break, but the language doesn't change 😦 Because we didn't create any language-specific content.

Create language-specific files

Create a new folder called locales under the public folder and create JSON files with exact names as locale codes
image
Inside of each JSON create one key-value language as a data property

eg: en-US

{
    "language": "English"
}
Enter fullscreen mode Exit fullscreen mode

ta-IN

{
    "language": "தமிழ்"
}
Enter fullscreen mode Exit fullscreen mode

hi-IN

{
    "language": "हिन्दी"
}
Enter fullscreen mode Exit fullscreen mode

Loading the language file based on route locale code

When navigating to a specific locale route, the page should show content from the respective locale JSON file.

We will be achieving that by
1 Get the locale code from the route
2 Fetch the locale JSON
3 Bind in HTML

1: Get the locale code from the route
next/router will provide us the locale code. Update the home.js file with useRouter hook.

const router = useRouter();
const locale = router.locale;
Enter fullscreen mode Exit fullscreen mode

2: Fetch locale JSON file
Make Rest call using useSWR hook with the locale code from the previous step.

const { data, error } = useSWR(`/locales/${locale}.json`, fetcher)
Enter fullscreen mode Exit fullscreen mode

3: Bind in HTML
Replace the English with the data fetched from the previous step. Final home.js will looks as below.

import { useRouter } from 'next/router'
import useSWR from 'swr'

const Home = () => {
    const router = useRouter();
    const locale = router.locale;

    const { data, error } = useSWR(`/locales/${locale}.json`, fetcher)

    return (
        <h1>Hey! I am home - {data?.language}</h1>
    )
}

const fetcher = (...args) => fetch(...args).then(res => res.json());

export default Home;
Enter fullscreen mode Exit fullscreen mode

Time for Testing! 😃 😃

Try access different route based on route code
http://localhost:3000/ta-IN/home
image
http://localhost:3000/hi-IN/home
image

Its working !! Have a great day 😊 😇

Oldest comments (0)