diff --git a/app/docs/[...slug]/page.tsx b/app/docs/[...slug]/page.tsx index 3f251721..45dba950 100644 --- a/app/docs/[...slug]/page.tsx +++ b/app/docs/[...slug]/page.tsx @@ -93,8 +93,59 @@ export default async function DocPage({ params }: Param) { getDocContributorsByDocId(docIdFromPage); const Mdx = page.data.body; + // SEO 结构化数据 + const siteUrl = + process.env.NEXT_PUBLIC_SITE_URL || "https://involutionhell.com"; + const slugPath = (slug ?? []).join("/"); + const docUrl = slugPath ? `${siteUrl}/docs/${slugPath}` : `${siteUrl}/docs`; + + // TechArticle: 让 docs 在 Google 搜索结果上更可能展示为技术文章卡片 + const articleJsonLd = { + "@context": "https://schema.org", + "@type": "TechArticle", + headline: page.data.title, + description: page.data.description, + url: docUrl, + inLanguage: locale === "en" ? "en-US" : "zh-CN", + publisher: { + "@type": "Organization", + name: "Involution Hell", + url: siteUrl, + }, + }; + + // BreadcrumbList: 按 slug 层级生成面包屑(Google 搜索结果里的那种层级链接) + const breadcrumbItems = [ + { name: "Involution Hell", url: siteUrl }, + { name: "Docs", url: `${siteUrl}/docs` }, + ...(slug ?? []).map((seg, idx) => ({ + name: decodeURIComponent(seg), + url: `${siteUrl}/docs/${slug!.slice(0, idx + 1).join("/")}`, + })), + ]; + const breadcrumbJsonLd = { + "@context": "https://schema.org", + "@type": "BreadcrumbList", + itemListElement: breadcrumbItems.map((item, idx) => ({ + "@type": "ListItem", + position: idx + 1, + name: item.name, + item: item.url, + })), + }; + return ( <> +