Next.js 配置 react-intl 实现语言国际化

栏目: IOS · Android · 发布时间: 6年前

内容简介:使用Next.js的主要目的是实现SSR优化SEO,当然在使用过程中遇到过很多问题。非常感谢luffyZh 分享的文章,让我少走很多弯路。(Tip:刚开始搭建的同学, 建议先去看luffyZh 和官方文档 了解基础知识再来看本文章哦 #^.^# )。言归正传,antd官方是推荐使用react-intl实现国际化的,下面分享一下我在Next.js中实现国际化的过程,有不对或可优化的欢迎指正哦。示例:

使用Next.js的主要目的是实现SSR优化SEO,当然在使用过程中遇到过很多问题。非常感谢luffyZh 分享的文章,让我少走很多弯路。(Tip:刚开始搭建的同学, 建议先去看luffyZh 和官方文档 了解基础知识再来看本文章哦 #^.^# )。

言归正传,antd官方是推荐使用react-intl实现国际化的,下面分享一下我在Next.js中实现国际化的过程,有不对或可优化的欢迎指正哦。

一、npm 加载 react-intl

  • npm i react-intl -S

二、在根目录添加locales文件夹,用于存放不同语言的js文件

示例:

locales/
--| en.js  // 存放语言文本键值对
--| en-US.js // 导出存放语言的对象
--| zh.js  
--| zh-CN.js 
复制代码

zh.js

tip: 对象只能使用"debugObj.hello"这种方式,咱们常用的 debugObj{ hello:'你好' } 在这里使用会导致组件中取不到值

export default {
  title:'标题',
  dynamicName:" 动态赋值:{val}",
  "debugObj.hello":"你好 Debug对象",
};
复制代码

zh-CN.js

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;
复制代码

三、在/pages/_app.js中引入LocaleProvide(antd组件语言)和IntlProvider(react-intl)组件,在render函数中包裹根组件。

_app.js

import { Fragment } from 'react';
import App, { Container } from 'next/app';
import { LocaleProvider } from 'antd';
import { addLocaleData, IntlProvider } from 'react-intl';

//导入中英文对象
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={appLocale.messages}
                formats={appLocale.formats}
                >
                  <Component {...pageProps} router={router} />
              </IntlProvider>
            </LocaleProvider>
        </Container>
      </Fragment>
    );
  }
}

export default appLocale;
复制代码

四、修改server.js,通过正则匹配URL语言名称,该名称可以在_app.js的render函数中this.props获取

server.js

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.js

//FormattedMessage编译后是一个span标签
import { Component } from 'react';
import {Button} from 'antd';
import Link from 'next/link';
import { FormattedMessage  } from 'react-intl'; 
export default class Home extends Component {
    constructor(props){
        super(props);
        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/>
          
          <br/>
          <br/>
          {/* 语言切换 */}
          <Link href={`/zh-CN/home`}>
            <Button type="primary">中文</Button>
          </Link>

          <Link href={`/en-US/home`}>
            <Button type="primary">English</Button>
          </Link>
        );
    }
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Ordering Disorder

Ordering Disorder

Khoi Vinh / New Riders Press / 2010-12-03 / USD 29.99

The grid has long been an invaluable tool for creating order out of chaos for designers of all kinds—from city planners to architects to typesetters and graphic artists. In recent years, web designers......一起来看看 《Ordering Disorder》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码