Next.js国际化:next-i18next
引言
next-i18next 是专门为 Next.js 项目量身定制的国际化解决方案,它基于强大的 i18next 库,能帮助开发者轻松地为 Next.js 应用添加多语言支持
next-i18next 初相识
项目简介
next-i18next 是一个专为 Next.js 应用程序打造的国际化解决方案,它建立在 i18next 和 react-i18next 这两个强大的库之上。i18next 是一个功能丰富的国际化框架,提供了全面的翻译功能,包括语言的切换、复数形式的处理、插值等;react-i18next 则是 i18next 在 React 应用中的桥梁,使得在 React 组件中使用 i18next 的功能变得更加便捷。next-i18next 集成了这两者的优势,为 Next.js 项目提供了一站式的国际化服务。
它全面支持静态站点生成(SSG)和服务器端渲染(SSR)。在 SSG 模式下,next-i18next 可以在构建时生成不同语言版本的静态页面,提高页面的加载速度和性能;对于 SSR,它能够在服务器端就完成翻译工作,将翻译后的内容直接发送给客户端,增强了用户体验,特别是对于那些对首次加载时间敏感的应用场景,如电商网站、新闻门户等,具有重要意义。
安装依赖
在项目根目录下,通过 npm 或 yarn 安装 next-i18next 及其相关依赖。next-i18next 依赖于 i18next 和 react-i18next,因此需要一并安装:
npm install --save next-i18next i18next react-i18next或者使用 yarn:
yarn add next-i18next i18next react-i18next
next-i18next 配置全解析
创建配置文件
在项目根目录下创建next-i18next.config.js文件,这是 next-i18next 的核心配置文件,用于定义国际化的基本设置。以下是一个基本的配置示例:
module.exports = {i18n: {defaultLocale: 'en', // 默认语言,当用户未指定语言时使用locales: ['en', 'zh', 'de'], // 支持的语言列表localePath: typeof window === 'undefined'? require('path').resolve('./public/locales'): '/locales' // 翻译文件的存储路径,在服务器端和客户端环境下的不同设置},// 其他配置项,如命名空间、回退语言策略等
};
在上述配置中,defaultLocale指定了默认语言为英语(en)。这意味着当用户首次访问应用且没有明确选择语言时,应用将以英语呈现内容。locales数组列出了应用支持的所有语言,这里包括英语(en)、中文(zh)和德语(de)。你可以根据项目的实际需求添加或删除语言。
localePath配置项用于指定翻译文件的存储路径。通过typeof window === 'undefined'判断当前环境是服务器端还是客户端。
在服务器端,使用require('path').resolve('./public/locales')将路径解析为项目根目录下的public/locales文件夹,这是一个相对稳定的服务器端路径表示;
在客户端,直接使用/locales,这是基于浏览器路径的表示,确保客户端能够正确访问到翻译文件
集成到 Next.js
在next.config.js文件中引入并配置国际化相关设置,使 next-i18next 与 Next.js 项目集成。修改next.config.js如下:
const { i18n } = require('./next-i18next.config');module.exports = {i18n,// 其他Next.js配置项,如页面路径、样式加载等
};
上述代码中,首先通过const { i18n } = require('./next-i18next.config');
从next-i18next.config.js文件中导入i18n配置对象。然后,在next.config.js的module.exports中直接使用i18n,这样 Next.js 就会识别并应用这些国际化配置。
实战:用 next-i18next 实现多语言切换
准备翻译文件
在项目的public/locales目录下,按照语言代码创建对应的文件夹,每个文件夹中放置该语言的 JSON 翻译文件。例如,对于英语(en)和中文(zh),可以创建以下结构:
public/
└── locales/├── en/│ └── common.json└── zh/└── common.json
在common.json文件中,定义需要翻译的文本内容。例如,en/common.json文件内容如下:
{"greeting": "Hello","welcome": "Welcome to our application"
}
zh/common.json文件内容如下:
{
"greeting": "你好",
"welcome": "欢迎来到我们的应用"
}
这里的greeting和welcome是翻译键,对应不同语言的翻译值。通过这种键值对的方式,可以方便地管理和维护翻译内容,并且在后续的代码中,只需要根据翻译键来获取对应的翻译文本 。
页面组件集成
在页面组件中,使用next-i18next提供的高阶组件appWithTranslation来包裹顶级组件,通常是_app.js文件中的MyApp组件。这样可以为整个应用提供翻译上下文。
import { appWithTranslation } from 'next-i18next';
import MyApp from '../pages/_app';export default appWithTranslation(MyApp);
在具体的页面组件中,使用useTranslation钩子来获取翻译函数t,从而实现文本的翻译。例如,在index.js页面组件中:
import { useTranslation } from 'next-i18next';const IndexPage = () => {const { t } = useTranslation('common');return (<div><h1>{t('greeting')}</h1><p>{t('welcome')}</p></div>);
};export default IndexPage;
useTranslation('common')表示从common命名空间中获取翻译内容。
通过const { t } = useTranslation('common');解构出翻译函数t,然后在组件中使用{t('greeting')}和{t('welcome')}来显示对应的翻译文本。
当语言切换时,t函数会根据当前的语言环境返回相应语言的翻译内容 。
服务器端翻译加载
对于动态生成的页面,在getStaticProps或getServerSideProps函数中,使用serverSideTranslations函数来获取服务器端的翻译数据。这确保了在静态生成或服务器端渲染时,页面能够正确地加载翻译内容。
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';export async function getStaticProps({ locale }) {return {props: {...(await serverSideTranslations(locale, ['common'])),// 其他props数据},};
}
serverSideTranslations(locale, ['common'])函数接收当前的语言环境locale和需要加载的命名空间数组['common']作为参数。
它会返回一个包含翻译数据的对象,通过展开运算符...将这些翻译数据合并到props中,传递给页面组件。这样,在页面渲染时,就可以使用这些预加载的翻译数据,避免了客户端再去请求翻译文件,提高了页面的加载速度和性能 。
优化
动态加载语言包
在大型应用中,一次性加载所有语言包可能会导致初始加载时间过长,影响用户体验。
next-i18next 支持动态加载语言包,让你仅在需要时加载特定语言的资源文件。
首先,在next-i18next.config.js中配置load选项为currentOnly,表示只加载当前语言的资源:
module.exports = {i18n: {defaultLocale: 'en',locales: ['en', 'zh', 'de'],localePath: typeof window === 'undefined'? require('path').resolve('./public/locales'): '/locales',load: 'currentOnly'},
};
然后,在组件中使用useTranslation钩子时,可以通过fallbackLng选项指定回退语言,确保在当前语言包加载失败时仍有可用的翻译:
import { useTranslation } from 'next-i18next';const MyComponent = () => {const { t } = useTranslation('common', { fallbackLng: 'en' });return (<div><p>{t('message')}</p></div>);
};export default MyComponent;
这样,当用户切换语言时,next-i18next 会自动加载对应的语言包,而不是在应用启动时全部加载,有效提升了应用的加载性能和响应速度 。
多级菜单和路径国际化
在处理具有多级菜单和深层导航结构的应用时,确保所有链接都能正确处理语言前缀是至关重要的。Next.js 的动态路由功能为实现这一目标提供了便利。
假设你的应用有一个多级菜单,其中包含不同语言版本的页面链接。在next-i18next的配置下,你需要在链接中正确添加语言前缀。例如,在next/link组件中:
import Link from 'next/link';
import { useRouter } from 'next/router';const MenuItem = ({ href, label }) => {const router = useRouter();const { locale } = router;return (<Link href={`/${locale}${href}`}><a>{label}</a></Link>);
};export default MenuItem;
href={/\({locale}\){href}}动态地将当前语言代码locale添加到链接路径前,确保无论用户在哪个语言环境下,点击链接都能正确导航到对应语言版本的页面。
对于动态路由页面,如pages/post/[id].js,你可以在getStaticProps或getServerSideProps中获取当前语言环境,并根据需要返回相应语言的内容:
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';export async function getStaticProps({ params, locale }) {const postId = params.id;// 根据postId和locale获取相应语言的文章数据const post = await getPostByLocale(postId, locale);return {props: {...(await serverSideTranslations(locale, ['common'])),post},};
}
通过这种方式,可以确保在深层导航结构中,无论是静态页面还是动态页面,都能正确地处理语言国际化,为用户提供一致的多语言浏览体验 。
常见问题与解决方案
在使用 next-i18next 的过程中,开发者可能会遇到一些常见问题,下面将列举并提供相应的解决方案 。
翻译文件加载失败
- 问题描述:在应用启动或语言切换时,可能会出现翻译文件无法加载的情况,导致页面显示原始的翻译键,而不是翻译后的文本。这可能是由于翻译文件路径配置错误、文件缺失或网络问题等原因引起。
- 解决方案:
- 检查路径配置:仔细核对next-i18next.config.js中的localePath配置项,确保它指向正确的翻译文件存储目录。在服务器端和客户端环境下,路径的表示可能不同,需要分别确认。例如,在服务器端,使用require('path').resolve('./public/locales')确保路径解析正确;在客户端,/locales应与实际的文件路径相对应。
- 确认文件存在:检查localePath指定目录下,是否存在对应语言和命名空间的翻译文件。例如,如果配置了支持英语(en)和中文(zh),并且使用了common命名空间,那么public/locales/en/common.json和public/locales/zh/common.json文件应该存在且内容正确。
- 网络请求排查:在浏览器的开发者工具中,查看网络请求,确认翻译文件的请求是否成功。如果出现 404 错误,说明文件未找到;如果是其他网络错误,如 500 错误,可能是服务器端的问题,需要进一步检查服务器日志,排查文件读取或传输过程中的错误 。
语言切换异常
- 问题描述:当用户切换语言时,页面内容没有及时更新为新语言的翻译,或者出现闪烁、卡顿等异常现象。这可能是由于语言切换逻辑未正确实现,或者组件没有正确响应语言变化。
- 解决方案:
- 使用正确的切换方法:确保在切换语言时,使用next-i18next提供的changeLanguage方法,并且在组件中正确处理语言切换后的更新。例如,在useTranslation钩子所在的组件中,当changeLanguage被调用时,组件会自动重新渲染,以显示新语言的翻译内容。如果组件没有自动更新,可以尝试使用useEffect钩子,监听语言变化并手动触发更新。
- 避免重复初始化:在应用中,确保i18next实例只被初始化一次,避免在不必要的地方重复调用init方法,以免导致配置冲突和语言切换异常。通常在应用的入口文件(如_app.js)中进行一次初始化即可。
- 优化性能:对于大型应用,语言切换时可能会因为加载大量翻译数据而导致卡顿。可以采用动态加载语言包的方式,减少初始加载的数据量,提高语言切换的响应速度。同时,合理使用缓存机制,避免频繁重复加载相同的翻译文件 。
服务器端渲染时翻译问题
- 问题描述:在服务器端渲染(SSR)过程中,可能出现翻译数据未正确加载或传递的问题,导致页面在服务器端渲染的结果与客户端不一致,或者出现翻译缺失的情况。
- 解决方案:
- 正确配置服务器端翻译:在getStaticProps或getServerSideProps函数中,使用serverSideTranslations函数获取服务器端的翻译数据,并将其正确传递给页面组件。确保函数接收的locale参数正确,它决定了加载哪个语言的翻译数据。
- 处理异步操作:由于serverSideTranslations是异步函数,需要正确处理异步操作,确保翻译数据在页面渲染前已经加载完成。可以使用await关键字等待翻译数据的获取,避免在数据未准备好时就进行页面渲染 。
相关文章:
Next.js国际化:next-i18next
引言 next-i18next 是专门为 Next.js 项目量身定制的国际化解决方案,它基于强大的 i18next 库,能帮助开发者轻松地为 Next.js 应用添加多语言支持 next-i18next 初相识 项目简介 next-i18next 是一个专为 Next.js 应用程序打造的国际化解决方案&#…...
计算机视觉:卷积神经网络(CNN)基本概念(一)
第一章:计算机视觉中图像的基础认知 第二章:计算机视觉:卷积神经网络(CNN)基本概念(一) 第三章:计算机视觉:卷积神经网络(CNN)基本概念(二) 第四章:搭建一个经典的LeNet5神经网络 一、引言 卷积神经网络&…...
Python的那些事第二十三篇:Express(Node.js)与 Python:一场跨语言的浪漫邂逅
摘要 在当今的编程世界里,Node.js 和 Python 像是两个性格迥异的超级英雄,一个以速度和灵活性著称,另一个则以强大和优雅闻名。本文将探讨如何通过 Express 框架将 Node.js 和 Python 结合起来,打造出一个高效、有趣的 Web 应用。我们将通过一系列幽默风趣的实例和表格,展…...
核货宝外贸订货系统:批发贸易企业出海的强劲东风
在全球贸易一体化的汹涌浪潮中,批发贸易企业正积极探寻海外市场的广阔天地,试图开辟新的增长版图。然而,出海之路绝非坦途,众多难题如暗礁般潜藏在前行的航道上。从复杂繁琐的跨境交易流程、变幻莫测的国际市场需求,到…...
最新智能优化算法: 阿尔法进化(Alpha Evolution,AE)算法求解23个经典函数测试集,MATLAB代码
一、阿尔法进化算法 阿尔法进化(Alpha Evolution,AE)算法是2024年提出的一种新型进化算法,其核心在于通过自适应基向量和随机步长的设计来更新解,从而提高算法的性能。以下是AE算法的主要步骤和特点: 主…...
数据结构与算法面试专题——堆排序
完全二叉树 完全二叉树中如果每棵子树的最大值都在顶部就是大根堆 完全二叉树中如果每棵子树的最小值都在顶部就是小根堆 设计目标:完全二叉树的设计目标是高效地利用存储空间,同时便于进行层次遍历和数组存储。它的结构使得每个节点的子节点都可以通过简…...
MongoDB索引介绍
索引简述 索引是什么 索引在数据库技术体系中占据了非常重要的位置,其主要表现为一种目录式的数据结构,用来实现快速的数据查询。通常在实现上,索引是对数据库表(集合)中的某些字段进行抽取、排列之后,形成的一种非常易于遍历读取…...
【一文读懂】WebRTC协议
WebRTC(Web Real-Time Communication)协议 WebRTC(Web Real-Time Communication)是一种支持浏览器和移动应用程序之间进行 实时音频、视频和数据通信 的协议。它使得开发者能够在浏览器中实现高质量的 P2P(点对点&…...
【弹性计算】容器、裸金属
容器、裸金属 1.容器和云原生1.1 容器服务1.2 弹性容器实例1.3 函数计算 2.裸金属2.1 弹性裸金属服务器2.2 超级计算集群 1.容器和云原生 容器技术 起源于虚拟化技术,Docker 和虚拟机和谐共存,用户也找到了适合两者的应用场景,二者对比如下图…...
【个人开发】deepspeed+Llama-factory 本地数据多卡Lora微调
文章目录 1.背景2.微调方式2.1 关键环境版本信息2.2 步骤2.2.1 下载llama-factory2.2.2 准备数据集2.2.3 微调模式2.2.3.1 zero-3微调2.2.3.2 zero-2微调2.2.3.3 单卡Lora微调 2.3 踩坑经验2.3.1 问题一:ValueError: Undefined dataset xxxx in dataset_info.json.2…...
两步在 Vite 中配置 Tailwindcss
第一步:安装依赖 npm i -D tailwindcss tailwindcss/vite第二步:引入 tailwindcss 更改配置 // src/main.js import tailwindcss/index// vite.config.js import vue from vitejs/plugin-vue import tailwindcss from tailwindcss/viteexport default …...
使用 HTML CSS 和 JAVASCRIPT 的黑洞动画
使用 HTML CSS 和 JAVASCRIPT 的黑洞动画 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Black Ho…...
计算机视觉-尺度不变区域
一、尺度不变性 1.1 尺度不变性 找到一个函数,实现尺度的选择特性。 1.2 高斯偏导模版求边缘 1.3 高斯二阶导 用二阶过零点检测边缘 高斯二阶导有两个参数:方差和窗宽(给定方差可以算出窗宽) 当图像与二阶导高斯滤波核能匹配…...
SNARKs 和 UTXO链的未来
1. 引言 SNARKs 经常被视为“解决”扩容问题的灵丹妙药。虽然 SNARKs 可以提供令人难以置信的好处,但也需要承认其局限性——SNARKs 无法解决区块链目前面临的现有带宽限制。 本文旨在通过对 SNARKs 对比特币能做什么和不能做什么进行(相对)…...
DeepSeek 通过 API 对接第三方客户端 告别“服务器繁忙”
本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 上一期分享了如何在本地部署 DeepSeek R1 模型,但通过命令行运行的本地模型,问答的交互也要使用命令行,体验并不是很好。这期分享几个第三方客户端,涵盖了桌…...
性格测评小程序07用户登录
目录 1 创建登录页2 在首页检查登录状态3 搭建登录功能最终效果总结 小程序注册功能开发好了之后,就需要考虑登录的问题。首先要考虑谁作为首页,如果把登录页作为首页,比较简单,每次访问的时候都需要登录。 如果把功能页作为首页&…...
红队视角出发的k8s敏感信息收集——日志与监控系统
针对 Kubernetes 日志与监控系统 的详细攻击视角分析,聚焦 集群审计日志 和 Prometheus/Grafana 暴露 的潜在风险及利用方法 攻击链示例 1. 攻击者通过容器逃逸进入 Pod → 2. 发现未认证的 Prometheus 服务 → 3. 查询环境变量标签获取数据库密码 → 4. 通过审…...
deepseek多列数据对比,联想到excel的高级筛选功能
目录 1 业务背景 2 deepseek提示词输入 3 联想分析 4 EXCEL高级搜索 1 业务背景 系统上线的时候经常会遇到一个问题,系统导入的数据和线下的EXCEL数据是否一致,如果不一致,如何快速找到差异值,原来脑海第一反应就是使用公…...
国产编辑器EverEdit - “切换文件类型”的使用场景
1 “切换文件类型”的使用场景 1.1 应用背景 一般的编辑器都是通过扩展名映射到对应的语法高亮规则的,比如:文件test.xml中的扩展名“xml"对应XML的语法高亮,在编辑器中打开test.xml就会给不同标识符显示不同的颜色。 但有时一些应用程…...
VSCode 接入DeepSeek V3大模型,附使用说明
VSCode 接入DeepSeek V3大模型,附使用说明 由于近期 DeepSeek 使用人数激增,服务器压力较大,官网已 暂停充值入口 ,且接口响应也开始不稳定,建议使用第三方部署的 DeepSeek,如 硅基流动 或者使用其他模型/插件,如 豆包免费AI插件 MarsCode、阿里免费AI插件 TONGYI Lin…...
JavaScript 内置对象-数组对象
在JavaScript中,数组(Array)是一种非常重要的数据结构,它允许我们以列表的形式存储多个值,并提供了丰富的内置方法来操作这些值。无论是处理简单的数值集合还是复杂的对象数组,数组对象都能提供强大的支持。…...
在linux系统中安装Anaconda,并使用conda
系统 : ubuntu20.04 显卡:NVIDIA GTX1650 目录 安装Anaconda第一步:下载合适版本的Anconda1. 查看自己Linux的操作系统及架构命令:uname -a2. 下载合适版本的Anconda 第二步:安装Aanconda1. 为.sh文件设置权限2. 执行.sh文件2.1 .…...
机械学习基础-5.分类-数据建模与机械智能课程自留
data modeling and machine intelligence - CLASSIFICATION 为什么我们不将回归技术用于分类?贝叶斯分类器(The Bayes Classifier)逻辑回归(Logistic Regression)对逻辑回归的更多直观理解逻辑 /sigmoid 函数的导数我们…...
静态页面在安卓端可以正常显示,但是在ios打开这个页面就需要刷新才能显示全图片
这个问题可能有几个原因导致,我来分析一下并给出解决方案: 首要问题是懒加载实现方式的兼容性问题。当前的懒加载实现可能在 iOS 上不够稳定。建议修改图片懒加载的实现方式: // 使用 Intersection Observer API 实现懒加载 function initLazyLoading() {const imageObserver…...
代码随想录刷题攻略---动态规划---子序列问题1---子序列
子序列(不连续)和子序列(连续)的问题 例题1: 最长递增子序列 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列,删除(或不删除)数组中的…...
八股取士--dockerk8s
一、Docker 基础 Docker 和虚拟机的区别是什么? 答案: 虚拟机(VM):虚拟化硬件,每个 VM 有独立操作系统,资源占用高,启动慢。Docker:容器化应用,共享宿主机内核…...
ubuntu系统下KVM设置桥接网络(失败)
20250216 - 概述 因实验需求,需要设置KVM下的虚拟机采用桥接模式进行通信,这种方式将使虚拟机与主机类似使用同一网段的IP。实际上,为了实现这个功能,我已经在自己mac上VMware使用过,虚拟机获得了自己独立的IP。 但…...
【ISO 14229-1:2023 UDS诊断(会话控制0x10服务)测试用例CAPL代码全解析④】
ISO 14229-1:2023 UDS诊断【会话控制0x10服务】_TestCase04 作者:车端域控测试工程师 更新日期:2025年02月15日 关键词:UDS诊断、0x10服务、诊断会话控制、ECU测试、ISO 14229-1:2023 TC10-004测试用例 用例ID测试场景验证要点参考条款预期…...
OpenAI 放王炸,将发布整合多项技术的 GPT-5,并免费无限使用,该模型有哪些技术亮点
对于 ChatGPT 的免费用户,将可以无限制地访问 GPT-5,但仅限于标准的智能级别。该级别会设定滥用限制,以防止不当使用(意思就是你得付费嘛)。 OpenAI CEO Sam Altman 今天在 X 上透露了 GPT-4.5 和 GPT-5 的最新发展计划。 OpenAI 将发布代…...
C 语言版--销售预测项目案例分享
以下是一个 C 语言销售预测项目案例,该项目模拟根据历史销售数据使用简单的移动平均法来预测未来的销售额。移动平均法是一种常见且基础的时间序列预测方法,它通过计算一定时间段内数据的平均值来预测未来的值。 项目需求 给定一系列历史销售数据,使用简单移动平均法预测下…...
