+4

Setup đa ngôn ngữ i18n trong ReactJS

Hướng dẫn một số bước cơ bản để setup đa ngôn ngữ i18n cho ứng dụng của bạn.

Link thư viện: https://react.i18next.com/guides/quick-start

Link demo online: https://codesandbox.io/s/react-i18n-c0yrc4?file=/src/App.tsx

1. Tạo ứng dụng React cơ bản

  • Tạo một folder với tên react-i18n-app
  • Mở cmd và gõ: npm create vite@latest
  • Select a framework: React
  • Select a variant: Javascript
  • Use rolldown-vite: No
  • Install with npm and start now? Yes
  • Đợi một lúc để ứng dụng được khởi tạo
  • Cài đặt hai package để hỗ trợ đa ngôn ngữ: npm install react-i18next i18next
  • Khởi chạy ứng dụng: npm start

2. Giao diện ban đầu

  • Mở file bên dưới và thêm thư viện bootstrap để css cho nhanh
<link
  href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css"
  rel="stylesheet"
  integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
  crossorigin="anonymous"
/>
  • Code giao diện tí nhỉ
import './App.css'

export default function App() {
  return (
    <div className="container text-center">
      <h1 className="my-3">React i18n</h1>
      <button className="btn btn-primary me-2">Change language EN - VI</button>
      <span className="badge rounded-pill text-bg-danger me-1">Search</span>
      <span className="badge rounded-pill text-bg-danger me-1">Cancel</span>
      <span className="badge rounded-pill text-bg-danger me-1">Delete</span>
      <span className="badge rounded-pill text-bg-danger me-1">Save</span>
    </div>
  )
}
  • Giao diện sẽ được cơ bản như này

image.png

  • Mong muốn khi click vào button Change language EN - VI sẽ đổi text của bốn label bên cạnh

3. Tạo các file ngôn ngữ Anh - Việt

  • Tạo file tiếng Anh
{
  "common": {
    "button": {
      "search": "Search",
      "cancel": "Cancel",
      "delete": "Delete",
      "save": "Save"
    }
  }
}
  • Tạo file tiếng Việt
{
  "common": {
    "button": {
      "search": "Tìm kiếm",
      "cancel": "Hủy",
      "delete": "Xóa",
      "save": "Lưu"
    }
  }
}

4. Config ngôn ngữ

  • Để tiện theo dõi thì mình tạo file riêng để config ngôn ngữ
import i18next from 'i18next'
import { initReactI18next } from 'react-i18next'
import translationEN from '../locales/en/translation.json'
import translationVI from '../locales/vi/translation.json'

const resources = {
  en: { translation: translationEN },
  vi: { translation: translationVI }
};

i18next.use(initReactI18next).init({
  lng: 'en', // if you're using a language detector, do not define the lng option
  debug: true,
  resources
})
  • Load file này vào trong file index luôn
import './config-translation' // <=== thêm here
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <App />
  </StrictMode>,
)

5. Hiển thị

import { useTranslation } from "react-i18next";
import './App.css'

export default function App() {
  const { t } = useTranslation();

  return (
    <div className="container text-center">
      <h1 className="my-3">React i18n</h1>
      <button className="btn btn-primary me-2">Change language EN - VI</button>
      <span className="badge rounded-pill text-bg-danger me-1">
        {t("common.button.search")}
      </span>
      <span className="badge rounded-pill text-bg-danger me-1">
        {t("common.button.cancel")}
      </span>
      <span className="badge rounded-pill text-bg-danger me-1">
        {t("common.button.delete")}
      </span>
      <span className="badge rounded-pill text-bg-danger me-1">
        {t("common.button.save")}
      </span>
    </div>
  );
}

6. Click chuyển ngôn ngữ

Thêm sự kiện onClick để chuyển ngôn ngữ

import { useTranslation } from 'react-i18next'
import './App.css'
import { useState } from 'react'

export default function App() {
  const { t, i18n } = useTranslation()
  const [currentLanguage, setCurrentLanguage] = useState('en')

  return (
    <div className="container text-center">
      <h1 className="my-3">React i18n</h1>
      <button
        className="btn btn-primary me-2"
        onClick={() => {
          setCurrentLanguage(currentLanguage === "en" ? "vi" : "en")
          i18n.changeLanguage(currentLanguage === "en" ? "vi" : "en")
        }}
      >
        Change language EN - VI
      </button>
      <span className="badge rounded-pill text-bg-danger me-1">
        {t("common.button.search")}
      </span>
      <span className="badge rounded-pill text-bg-danger me-1">
        {t("common.button.cancel")}
      </span>
      <span className="badge rounded-pill text-bg-danger me-1">
        {t("common.button.delete")}
      </span>
      <span className="badge rounded-pill text-bg-danger me-1">
        {t("common.button.save")}
      </span>
    </div>
  )
}

7. Demo

Demo online tại đây: https://codesandbox.io/s/react-i18n-c0yrc4?file=/src/App.tsx


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí