Files
fad-trade-next/app/[locale]/about/[section]/page.tsx
砂糖 450337a019 refactor(about): 重构关于页面路由为静态路径
将关于页面的查询参数路由改为静态路径结构,如/about/company
更新i18n消息中的链接路径
添加新的[section]页面处理逻辑
优化静态生成参数和错误处理
2025-12-11 09:10:41 +08:00

120 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import MDXComponents from "@/components/mdx/MDXComponents";
import { Locale, LOCALES } from "@/i18n/routing";
import { constructMetadata } from "@/lib/metadata";
import fs from "fs/promises";
import { Metadata } from "next";
import { getTranslations } from "next-intl/server";
import { MDXRemote } from "next-mdx-remote-client/rsc";
import path from "path";
import remarkGfm from "remark-gfm";
// 强制静态渲染
export const dynamic = "force-static";
const options = {
parseFrontmatter: true,
mdxOptions: {
remarkPlugins: [remarkGfm],
rehypePlugins: [],
},
};
// 增强添加参数校验防止undefined
async function getMDXContent(locale: string, section: string) {
// 兜底校验:确保参数是字符串
const validLocale = locale?.trim() || "en"; // 兜底为默认语言
const validSection = section?.trim() || "company"; // 兜底为默认section
// 校验LOCALES是否包含当前locale
if (!LOCALES.includes(validLocale)) {
console.error(`Locale "${validLocale}" not found in LOCALES!`);
return "";
}
const filePath = path.join(
process.cwd(),
"content",
"about",
validSection, // 使用校验后的section
`${validLocale}.mdx` // 使用校验后的locale
);
try {
// 先检查文件是否存在,避免读取不存在的文件
await fs.access(filePath);
const content = await fs.readFile(filePath, "utf-8");
return content;
} catch (error) {
console.error(`Error accessing/reading MDX file (${filePath}):`, error);
return "";
}
}
// 修正路由参数类型locale + section
type Params = {
locale: string;
section: string;
};
type MetadataProps = {
params: Params;
};
export async function generateMetadata({
params,
}: MetadataProps): Promise<Metadata> {
const { locale, section } = params;
const t = await getTranslations({ locale, namespace: "About" });
return constructMetadata({
page: `About - ${section}`,
title: t(`title`) || t("title"), // 适配不同section的标题
description: t(`description`) || t("description"),
locale: locale as Locale,
path: `/about/${section}`,
canonicalUrl: `/about/${section}`,
});
}
// 页面组件从params获取locale和section路由参数
export default async function AboutPage({
params,
}: {
params: Promise<Params>;
}) {
const { locale, section } = await params;
console.log(`Rendering AboutPage for locale: ${locale}, section: ${section}`);
// 调用带校验的getContent函数
const content = await getMDXContent(locale, section);
return (
<article className="w-full md:w-3/5 px-2 md:px-12">
<MDXRemote
source={content}
components={MDXComponents}
options={options}
/>
</article>
);
}
// 关键生成locale + section的所有静态组合覆盖vi/organization等
export async function generateStaticParams() {
const sections = ['company', 'awards', 'base', 'culture', 'history', 'organization'];
// 确保LOCALES包含"vi"越南语否则会生成undefined
if (!LOCALES.includes("vi")) {
console.warn("⚠️ LOCALES does not include 'vi'! Add it to fix /vi/about/* paths.");
// 临时兜底如果没有vi手动添加或检查你的i18n/routing.ts
// LOCALES.push("vi");
}
// 生成所有locale × section的组合
return LOCALES.flatMap((locale) =>
sections.map((section) => ({
locale,
section,
}))
);
}