+2

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õ: npx create-react-app .
  • Đợi một lúc để ứng dụng được khởi tạo
  • Trong cmd đó ta gõ tiếp: cd react-i18n-app
  • 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ỉ
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 tương ứng

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 React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
import reportWebVitals from './reportWebVitals'

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals()

5. Hiển thị

import { useTranslation } from "react-i18next";

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ữ

import { useTranslation } from 'react-i18next'
import { useState } from 'react'

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

  return (
    <button
      className="btn btn-primary me-2"
      onClick={() => {
        setCurrentLanguage(currentLanguage === "en" ? "vi" : "en")
        i18n.changeLanguage(currentLanguage === "en" ? "vi" : "en")
      }}
    >
      Change language EN - VI
    </button>
  )
}

7. Demo

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


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.