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 ๐Ÿ˜Š ๐Ÿ˜‡

Top comments (0)