使用 React Intl 在 Create React App 建立多國語系靜態網頁
Published in
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
引入FormattedMessage
和IntlProvider
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>
);
}
FormattedMessage Demo
多語系時間
- 從
react-intl
importFormattedDate
,會根據瀏覽器所在地變日期顯示方式
<FormattedDate
value={new Date()}
year="numeric"
month="long"
day="numeric"
weekday="long"
/>
- 以 Chrome 為例,在 Browser 切換語言系統:
點擊Google Chrome 瀏覽器右上角三個點的按鈕 > 設定 > 進階 > 語言 > 英文(美國)> 將 Google Chrome 的介面文字設定為這種語言
!!! 注意 BROWSER SUPPORT
FormattedDate 並沒有支援 IE11. 如果需要支援 IE11 可以參考官方文件上的做法
Say hello! 我是 Angel,這裏的內容如果有幫到你,希望能獲得一些拍手作為鼓勵
工作上的合作歡迎隨時透過 Mail 聯繫我 contact@aneglho.design–
Thanks for watching!