Next.js 如何在 i18n 场景下处理 404 页面

问题

使用 Next.js 框架,app route 模式,404 页面在国际化场景下无法正常使用。

在 Next.js 中的 app route 模式,约定了很多页面的路径,比如 layout.tsxpage.tsx。对于 404 页面,可以使用 not-found.tsx:

tsx 复制代码
import Link from "next/link";

export default function NotFound() {
  return (
    <div>
      <h2>Not Found</h2>
      <p>Could not find requested resource</p>
      <Link href="/">Return Home</Link>
    </div>
  );
}

再说回国际化,国际化方案一般使用动态路由,在 app 目录下创建 [lang] 文件夹。

这样就可以在页面中通过 params 获取到当前语言,然后根据语言加载对应的资源。

ts 复制代码
export default function RootLayout({ children, params: { lang } }) {

那么所有的页面都应该在 [lang] 目录下,包括 404 页面。就像这样 app/[lang]/not-found.tsx

问题来了,这样写的话,输入一个不存在的路径,会显示 Next.js 默认的 404 页面,而不是我们自定义的 404 页面。

解决方案

app/[lang] 目录下创建 [...not_found]/page.tsx 文件,用于捕获所有的 404 页面。

tsx 复制代码
// 从 next/navigation 中导入我们自定义的 notFound 方法
import { notFound } from "next/navigation";

export default function NotFoundCatchAll() {
  notFound();
}

这样就 OK 啦~

但是还有一个问题,notFound 不接收任何 Props,所以我们无法在 404 页面中获取到当前语言。

如果你想对 404 页面的文案做国际化,就还需要再做处理。

很简单,不使用 Next.js 的 notFound 方法,自己写一个 components/notFound.tsx 组件。

tsx 复制代码
export default async function NotFound({ lang }) {
  const { t } = await useTranslation(lang, "not-found");
  return <div>{t("404")}</div>;
}

然后在 app/[lang]/[...not_found]/page.tsx 中使用这个组件。

tsx 复制代码
import NotFound from "@/components/common/not-found";

export default function NotFoundCatchAll({ params: { lng } }) {
  return <NotFound lng={lng} />;
}

中文404页面

英文404页面

至此大功告成,完美解决 Next.js 在国际化场景下的 404 页面问题,可以删掉 app/[lang]/not-found.tsx 文件了。

总结

Next.js 一言难尽。

相关推荐
小王和八蛋2 分钟前
前端存储与离线应用实战:Cookie、LocalStorage、PWA 及 Service Worker 核心知识点
前端·javascript
JarvanMo5 分钟前
终极指南:在 Flutter 中通过 sign_in_with_apple 实现 Apple 登录
前端
古茗前端团队7 分钟前
视频播放弱网提示实现
react.js
Learner11 分钟前
Python异常处理
java·前端·python
tao35566714 分钟前
VS Code登录codex,报错(os error 10013)
java·服务器·前端
军军君0117 分钟前
Three.js基础功能学习七:加载器与管理器
开发语言·前端·javascript·学习·3d·threejs·三维
哈__19 分钟前
入门小白到精通,玩转 React Native 鸿蒙跨平台开发:Button 按钮组件与点击事件
react native·react.js·harmonyos
哈__19 分钟前
React Native 鸿蒙开发:内置 Share 模块实现无配置社交分享
javascript·react native·react.js
JarvanMo20 分钟前
情迷服务器驱动 UI:我在 Flutter 开发中的爱与哀愁
前端
tzy23323 分钟前
分享一个 HTTP(S) 代理&抓包工具,拦截和Mock Web客户端请求和服务端响应
前端·网络协议·http