前言
- 最近有一个项目,需要在保证页面功能的情况下,还要保证网站的seo友好。鉴于这种情况,我选择了nextjs框架,并使用其静态导出功能,在保证seo友好的同时,还不需要相对应的后端服务器。
- 然而,在实际搭框架的过程中,我发现现有的多语言插件,很多对静态导出模式+ssg模式的支持并不友好,不得不花更多时间来找解决方案。
问题
- 现有主流多语言库对静态导出与ssg功能支持度不高,尤其是nextjs官方支持的国际化路由首先就不支持静态导出模式
- 很多多语言库对app路由支持不佳,使用app路由配置起来会很麻烦
- 需要对ssg模式友好,最终要能构建出seo友好的网站
开发环境
- "next": "15.1.2" 使用app路由,并在next.config.ts配置文件中,配置了静态导出的模式,该模式可以构建出无需后端服务器的静态html文件。
- 使用typescript语言
解决方案
- 最终我是选择了next-intl这个库来做多语言功能,原因有如下几点
- 配置简单
- 对静态导出模式友好
- 对app路由支持友好
- 既然选好了插件,接下来便是配置
- 安装,使用
pnpm i next-intl
安装该插件
- 修改next.config.ts配置文件
import type { NextConfig } from "next";
import createNextIntlPlugin from 'next-intl/plugin';
const withNextIntl = createNextIntlPlugin();
const nextConfig: NextConfig = {
/* config options here */
output: 'export',
};
export default withNextIntl(nextConfig);
- 在根目录下,创建
i18n/request.ts
文件
import {getRequestConfig} from 'next-intl/server';
export default getRequestConfig(async () => {
// This typically corresponds to the `[locale]` segment.
const locale = 'pt'
return {
locale,
messages: (await import(`../locales/${locale}.json`)).default
};
});
- 该文件的作用是在此读取cookie或者请求的header,来自行选择加载的多语言文件
- 接下来,在根目录下,创建
/locales/
文件夹,在这个文件夹里放置多语言文件
- 示例,创建en.json文件
{
"HomePage": {
"title": "It's a title",
"desc": "it's a desc",
}
- 最后,在项目代码中使用该插件,我是这么用的
- 在page.js文件中,引入该插件提供的provider,并注入en.json这个语言文件的内容
import { NextIntlClientProvider } from 'next-intl';
import enLanguage from "@/locales/en.json";
import Main from "./Main"
import Link from 'next/link';
export default function Home() {
return (
<NextIntlClientProvider messages={enLanguage}>
<Main></Main>
</NextIntlClientProvider>
);
}
- 如此,我们便可以在这个page组件内部及其子组件中使用该插件了,如上,我在/en路径下的page文件,引入了en.json文件,代表这个页面使用英文
- 具体使用如下
import { useTranslations } from 'next-intl';
export default function HeaderSection() {
const t = useTranslations('HomePage');
return (
<div className="text-center mb-12">
<div className="inline-flex items-center gap-2 mb-4">
<div className="w-8 h-8 rounded-full bg-[#009c3b]" />
<h1 className="text-4xl font-bold">{t('title')}</h1>
<div className="w-8 h-8 rounded-full bg-[#ffdf00]" />
</div>
<p className="text-muted-foreground text-lg">
{t('desc')}
</p>
</div>
);
}
- 就这样,一个配置简单,适合小型项目的多语言功能便整合完毕
参考文章
- https://dev.to/ikramdeveloper/i18n-with-nextjs-output-export-1pbc