Integrating Multi-Language in Next.js with Custom Hooks and Redux
Tags: nextjs, webdev, react, redux
Published: 2024-03-30 03:36:34

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9knl573yetuovplhyioe.gif)
Today, I'll walk you through implementing multi-language support in Next.js using only custom hooks and Redux. The beauty of this method is its compatibility with any version of Next.js or even React.js. Let's dive in!

Firstly, let's set up a Redux reducer using Redux Toolkit called **LanguageStore**:

```jsx
import { createSlice } from '@reduxjs/toolkit'

export const LanguageStore = createSlice({
    name: 'LanguageStore',
    initialState: {
        language: 'vi',
    },
    reducers: {
        setLanguage: (state, actions) => {
            state.language = actions.payload
        },
    }
})

export const { setLanguage } = LanguageStore.actions

export default LanguageStore.reducer;
```
Next, create language data files. I've prepared two language files: `vi.json` for Vietnamese and `en.json` for English.

Here's an example of `vi.json`:

```json
{
    "about": "Giới thiệu",
    "menu": "Thực đơn",
    "news": "Tin tức",
    "gallery": "Thư viện",
    "order": "Đặt bàn ngay",
}
```
And `en.json`:
```json
{
    "about": "About us",
    "menu": "Menu",
    "news": "News",
    "gallery": "Library",
    "order": "Book Now",
}
```
Now, let's create `useLanguage.js`, a custom hook:
```jsx
import { useSelector } from 'react-redux';
import vi from "../helper/translates/vi.json"
import en from "../helper/translates/en.json"
const useLanguage = () => {
    const LanguageStore = useSelector((state) => state?.LanguageStore)
    const listLangue = {
        en: en,
        vi: vi,
    }

    const t = (text_params) => {
        let text = ''
        const langValue = LanguageStore?.language
        const getTextList = listLangue?.[langValue]
        if (listLangue?.[langValue]) {
            if (getTextList?.[text_params]) {
                text = getTextList?.[text_params]
            }
        }
        return text
    }
    return {
        t
    };
};

export default useLanguage;
```

Great! Now, let's put it to use:
```jsx
// Navbar.jsx
import useLanguage from "@/app/hooks/useLanguage";
import { setLanguage } from "@/app/store/reducer/LanguageStore";
import { useDispatch, useSelector } from "react-redux";
export const linkList = [
    {
      id: 1,
      url: "/ve-chung-toi",
      languageFlag: "about",
      title: "Giới thiệu",
    },
    {
      id: 2,
      url: "/menu",
      languageFlag: "menu",
      title: "Thực đơn",
    },
    {
      id: 3,
      url: "/tin-tuc",
      languageFlag: "news",
      title: "Tin tức",
    },
    {
      id: 4,
      url: "/thu-vien",
      languageFlag: "gallery",
      title: "Thư viện",
    },
  ];
function Navbar() {
  const { t } = useLanguage();
  const { language } = useSelector((state) => state.LanguageStore);
 const handleLanguageChange = (value) => {
    dispatch(setLanguage(value.value));
  };
  const languageOptions = [
    {
      value: "vi",
      label: (
        <Stack direction={"row"} alignItems="center" gap={"4px"}>
          <Image alt="" src={"/vn-language.svg"} width={24} height={24} />
          <Typography>VN</Typography>
        </Stack>
      ),
    },
    {
      value: "en",
      label: (
        <Stack direction={"row"} alignItems="center" gap={"4px"}>
          <Image alt="" src={"/en-language.svg"} width={24} height={24} />
          <Typography>EN</Typography>
        </Stack>
      ),
    },
  ];
return (
   <>
            {linkList.map((item) => (
              <Link 
                   href={item.url} 
                   key={item.id}>
                <Typography
                  textTransform={"uppercase"}
                  color={"#88231F"}
                  fontWeight={router.pathname === item.url ? 700 : 400}
                  fontSize={"14px"}
                  lineHeight={"24px"}
                >
                  {/* {item.title} */}
                  {t(item.languageFlag)}
                </Typography>
              </Link>
            ))}
            <CustomSelect
              options={languageOptions}
              defaultValue= 
                  {languageOptions.find((item) => 
                    item.value === language)}
              handleChange={handleLanguageChange}
            />
   </>
  )
}
```
And that's it! You're all set to use multi-language support in your Next.js app. I hope you find this tutorial helpful. Happy coding!