使用Next.js的主要目的是實現SSR優化SEO,固然在使用過程當中遇到過不少問題。很是感謝 luffyZh 分享的文章,讓我少走不少彎路。(Tip:剛開始搭建的同窗, 建議先去看 luffyZh 和 官方文檔 瞭解基礎知識再來看本文章哦 #^.^# )。前端
言歸正傳,antd官方是推薦使用react-intl實現國際化的,下面分享一下我在Next.js中實現國際化的過程,有不對或可優化的歡迎指正哦。react
- npm i react-intl -S
示例:express
locales/
--| en.js // 存放語言文本鍵值對
--| en-US.js // 導出存放語言的對象
--| zh.js
--| zh-CN.js
複製代碼
zh.jsnpm
tip: 默認對象只能使用"debugObj.hello"這種方式,我們經常使用的 debugObj{ hello:'你好' } 在這裏使用會致使組件中取不到值。bash
export default {
title:'標題',
dynamicName:" 動態賦值:{val}",
"debugObj.hello":"你好 Debug對象",
};
複製代碼
npm i flat -S
複製代碼
export default {
home: {
title:'標題'
}
};
複製代碼
zh-CN.jsantd
import appLocaleData from 'react-intl/locale-data/zh';
import zhMessages from './zh.js';
import antdZh from 'antd/lib/locale-provider/zh_CN'; //antd語言包
let appLocale = {
messages: {
...zhMessages,
},
antd: antdZh,
locale: 'zh-CN',
data: appLocaleData,
};
export default appLocale;
複製代碼
_app.jsapp
import { Fragment } from 'react';
import App, { Container } from 'next/app';
import { LocaleProvider } from 'antd';
import { addLocaleData, IntlProvider } from 'react-intl';
// 處理對象嵌套
// import Flat from 'flat';
//導入中英文對象
import _ZH from '../locales/zh-CN';
import _EN from '../locales/en-US';
let appLocale = {
messages: {
...zhMessages,
},
antd: antdZh,
locale: 'zh-CN',
data: appLocaleData,
};
class PageContainer extends App {
getLocale(languages){
const appLocale = this.getLocaleDatas(languages);
addLocaleData(...appLocale.data);
return appLocale;
}
getLocaleDatas(lang) {
let result = {};
switch (lang) {
case 'zh-CN':
result = _ZH;
break;
case 'en-US':
result = _EN;
break;
default:
result = _ZH;
}
return result;
}
// 該render在F5刷新,服務端執行一次後再到前端客戶端執行一次
render () {
const { Component, pageProps, router } = this.props;
// router.query.lang當前語言 - 須要經過修改server.js傳入query.lang
// 根據url設置語言
const languages = router.query.lang || 'zh-CN';
const appLocale = this.getLocale(languages);
return (
<Fragment>
<Container>
{/* antd語言 */}
<LocaleProvider locale={appLocale.antd}>
{/* 引用語言包 */}
<IntlProvider
locale={appLocale.locale}
{/* 語言包對象嵌套 */}
// messages={Flat(appLocale.messages)}
{/* 默認 */}
messages={appLocale.messages}
formats={appLocale.formats}
>
<Component {...pageProps} router={router} />
</IntlProvider>
</LocaleProvider>
</Container>
</Fragment>
);
}
}
export default appLocale;
複製代碼
server.jsfrontend
const express = require('express');
const cp = require('child_process');
const next = require('next');
const PORT = '3006';
const dev = true;
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
// 處理語言包
const LangExp = new RegExp(/^(\/zh-CN)|(\/en-US)/i);
server.get(LangExp, (req, res) => {
let path = req.path;
let lang = path.match(LangExp)[0];
let url = path.replace(lang, '');
lang = lang.slice(1, lang.length);
// 跳轉默認主頁
if (!url){
url = `/home`;
}
console.log(url, lang, '----------route---');
return app.render(req, res, url, { lang });
});
// 重定向默認路徑
server.get('/', (req, res) => {
res.redirect("/zh-CN/home");
});
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(PORT, err => {
if (err) throw err;
const serverUrl = `http://localhost:${PORT}`;
console.log(`> Ready on ${serverUrl}`);
});
});
複製代碼
home.jside
//FormattedMessage編譯後是一個span標籤
import { Component } from 'react';
import {Button} from 'antd';
import Link from 'next/link';
import { FormattedMessage,injectIntl, intlShape } from 'react-intl';
class Home extends Component {
static propTypes = {
intl: intlShape.isRequired
}
constructor(props){
super(props);
this.intl = this.props.intl;
this.lang = {
title:{
id:'title'
}
};
}
render(){
return (
{/* 用法一 */}
<FormattedMessage id="title"/>
<br/>
{/* 對象 */}
<FormattedMessage id="debugObj.hello"/>
<br/>
{/* 動態賦值 */}
<FormattedMessage id="dynamicName" values={{val:'888999'}}/>
<br/>
{/* 用法二 */}
<FormattedMessage {...this.lang.title}/>
<br/>
{/* 在input placeholder中使用 */}
<input placeholder={ this.intl.formatMessage({id:'title.title'}) } />
<br/>
<br/>
{/* 語言切換 */}
<Link href={`/zh-CN/home`}>
<Button type="primary">中文</Button>
</Link>
<Link href={`/en-US/home`}>
<Button type="primary">English</Button>
</Link>
);
}
}
export default injectIntl(Home)
複製代碼
貼個摸魚羣二維碼,能夠進來一塊兒摸摸魚,探討一下。函數