Nextjs国际化之 next-i18next 业务应用

2,172 阅读2分钟

本文已参与「 新人创作礼 」活动,一起开启掘金创作之路

关于如何进行图片优化 - 适合的才是最好的

关于i18的文章,其实非常的多。网上也有非常之多的解决方案。如果你的Nextjs炉火纯青,且对Nodejs也是非常的了解,或许你看官方文档基本也是够用的。

官方文章地址:nextjs.org/docs/advanc…

官方的github的DEMO:github.com/isaachinman…

那我为啥还要讲下,当然是我其中碰到一些官方文档没有讲的非常透彻,因为这个也属于业务应用级别的。

官方文档都next-router结合国际化讲的还是不错。

但是我看了,根本没有太多的必要且非常的繁琐。

如果有一个方式可以更快的解决,那何尝不可。

首先还是要确定下版本库的版本, 这个非常重要,前端处于飞速发展的过程,标准&规范还是慢慢建立。

文章我只会放一些关键的代码片段。

"next": "12.1.5",
"next-i18next": "11.0.0",
"react": "17.0.2",
"react-dom": "17.0.2",

因为为了兼容公司的历史业务,版本选的未必最新的,但也是稳定的版本了。

module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'de' , 'zh'],
  }
};

这个一般也就中英文就好,en、zh

const { i18n } = require('./next-i18next.config');
const nextConfig = {
  i18n,
};

import { AppProps } from 'next/app';
import { appWithTranslation } from 'next-i18next';
function MyApp({
  Component,
  pageProps
}: AppProps>) {
  return (
    <Component {...pageProps} />
  );
}

export default appWithTranslation(MyApp);

基本配置都搞定 , 这个时候我们应该考虑如何去应用了。

import { NextPage } from 'next';
import React, { PureComponent, useContext } from 'react';

import ArticleButton from '@cmc/dexer/components/Buttons/ArticleButton';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { MyContext } from '../components/DashboardLayout/DashboardLayout';
function useCountContext(CounterContext) {
	const context = useContext(CounterContext);
	if (!context) {
		throw new Error('useCountContext must used within Context.Provider');
	}
	return context;
}
const Home: NextPage = () => {
	const router = useRouter();
	const context = useCountContext(MyContext);
	let { language, setLanguage } = context;
	const { t, i18n } = useTranslation();
	const handleChangeLanguage = (country) => {
		setLanguage(country);
		i18n.changeLanguage(country);
	};
	return (
		<Container title="Dashboard">
			<div>Dashboard : {t('Fee must be greater than 0')}</div>
			<button
				onClick={() => {
					handleChangeLanguage('zh');
				}}
			>
				更改为中国
			</button>
			<button
				onClick={() => {
					handleChangeLanguage('en');
				}}
			>
				change to English
			</button>
		</Container>
	);
};
// export const getStaticProps = async ( props , context ) => {
//   console.log ("language" , props)
//   // const cookie = new Cookie(req.cookies);
//   // language = cookie.get('cmc-language')
//   // const context = useCountContext(MyContext);
//   console.log (context)
//   let { locale } = props
//   return {
//     props: {
//       ...await serverSideTranslations(locale||'zh', ['common']),
//     },
//   }
// }
export const getServerSideProps = async (ctx) => {
	let { req, locales, locale } = ctx;
	let cookies = req.cookies;
	let language = cookies['cmc-language'];
	return {
		props: {
			...await serverSideTranslations(language || locale, [ 'common' ])
		}
	};
};
export default Home;

这里的代码基本就到此结束了。

这里我要讲下就是官方demo返回的是一个 getStaticProps 但是这个方法在全局中拿到的值。当然你也在_app.tsx 改造而来,但这不是我今天要重点讲的。

我选择的是getServerSideProps server来获取cookie的方式,用serverSideTranslations来家在对应的国际化文件。

这里面重要的是我从context获取到的setLanguage需要对页面进行存放cookie reload

1)让server重新请求

2)让cookie生效。

这段代码,其实官方API 提供的。i18n.changeLanguage(country); 虽无报错,貌似没有生效。

PS: 或许会有更好的办法,不刷新的也可以构建。后续我继续研究,如有发现在补一篇。这只是日常工作用来记录的碎片化代码。共勉,努力!