使用 React Intl 在 Create React App 建立多國語系靜態網頁

Angel
Its Ok to Make Mistakes
8 min readApr 13, 2021

React Intl 使用 React components 的方式來實踐 i18n context,可以輕易透過切換語言包來實作多語系網頁,並依據瀏覽器所在地顯示當地時間日期的格式。

安裝 react-intl在 Create React App 專案安裝 react-intl
多語系文字透過語言包更換
多語系時間根據 Browser 所在地語言切換

新專案安裝 react-intl

  • 建立新的 Create React App
$ npx create-react-app my-app
$ cd my-app
$ yarn start
  • 安裝 react-intl
$ npm i react-intl

多語系文字

  • App.js 引入 FormattedMessageIntlProvider
import { FormattedMessage, IntlProvider } from "react-intl";
  • IntlProvider 包在最外層,把要更改的文字使用FormattedMessage 編輯
import logo from "./logo.svg";
import "./App.css";
import { FormattedMessage, IntlProvider } from "react-intl";
function App() {
return (
<IntlProvider>
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<FormattedMessage
id="app.header"
defaultMessage="Edit src/App.js and save to reload."
/>
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
<FormattedMessage id="app.content" defaultMessage="Learn React" />
</a>
</header>
</div>
</IntlProvider>
);
}
export default App;
  • 產出正式環境所使用的 Public 資料夾後,並將語言包放在該資料夾,才能提供可動態抽換的語言包
$ yarn build
  • 建立 lang 資料夾在 public 之下,並加入 en.json / cn.json / fr.json / jp.json 語言包
  • en.json
{
"app.header" : "編輯src / App.js並保存以重新加載。" ,
"app.content" : "學習 React"
}
  • cn.json
{
"app.header" : "編輯src / App.js並保存以重新加載。" ,
"app.content" : "學習 React"
}
  • fr.json
{
"app.header" : "Modifiez les fichiers et enregistrez-les pour recharger" ,
"app.content" : "Apprendre React"
}
  • jp.json
{
"app.header" : "src / App.jsを編集し、保存して再読み込みします。" ,
"app.content" : "Reactを学ぶ"
}
  • useState在頁面上加入語言切換的下拉式選單
const [lang, setLang] = useState('en')<select
value={lang}
onChange={(evt) => {
setLang(evt.target.value);
}}
>
<option value="en">English</option>
<option value="cn">中文</option>
<option value="fr">Français</option>
<option value="jp">日本語</option>
</select>
  • 透過 React hooks useEffect使用 Async/Await function 來處理語言包的切換,並在 IntlProvider 設定 messages={locale}

import React, { useState, useEffect } from 'react'

function App() {
const [lang, setLang] = useState('en')
const [locale, setLocale] = useState(undefined)
useEffect(async() => {
const resp = await fetch(`./lang/${lang}.json`)
const data = await resp.json()
setLocale(data)
},[lang])
return (
<IntlProvider
messages={locale}
>
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<div>
<select
value={lang}
onChange={(evt) => {
setLang(evt.target.value);
}}
>
<option value="en">English</option>
<option value="cn">中文</option>
<option value="fr">Français</option>
<option value="jp">日本語</option>
</select>
</div>
<p>
<FormattedMessage
id="app.header"
defaultMessage="Edit src/App.js and save to reload."
/>
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
<FormattedMessage id="app.content" defaultMessage="Learn React" />
</a>
</header>
</div>
</IntlProvider>
);
}
React Intl FormattedMessage Demo

多語系時間

  • react-intl import FormattedDate ,會根據瀏覽器所在地變日期顯示方式
<FormattedDate
value={new Date()}
year="numeric"
month="long"
day="numeric"
weekday="long"
/>
  • 以 Chrome 為例,在 Browser 切換語言系統:
    點擊Google Chrome 瀏覽器右上角三個點的按鈕 > 設定 > 進階 > 語言 > 英文(美國)> 將 Google Chrome 的介面文字設定為這種語言

!!! 注意 BROWSER SUPPORT
FormattedDate 並沒有支援 IE11. 如果需要支援 IE11 可以參考官方文件上的做法

React Intl FormattedDate Demo

參考資料: https://formatjs.io/docs/react-intl/

Say hello! 我是 Angel,這裏的內容如果有幫到你,希望能獲得一些拍手作為鼓勵
工作上的合作歡迎隨時透過 Mail 聯繫我 contact@aneglho.design

Thanks for watching!

--

--

Angel
Its Ok to Make Mistakes

A web / UIUX designer, in digital entertainment industry, Taipei Taiwan.