Next.js从Page Router转App Router后,SEO元数据该放何处?
Next.js App Router 适配 SEO 元数据配置方案
方案一:使用 Next.js 内置 Metadata API(推荐)
App Router 原生支持 Metadata API,无需额外依赖next-seo,可直接在根布局(app/layout.tsx)中定义全局默认元数据,子页面可按需覆盖。
步骤1:转换 SEO 配置格式
将原_app.tsx中的defaultSeo配置映射到Metadata类型,对应关系如下:
- 基础标题、描述对应
title、description字段 - OpenGraph 元数据对应
openGraph字段 - Twitter 元数据对应
twitter字段 - Facebook App ID 通过
other字段自定义 meta 标签 - 视口、网站图标通过
viewport、icons字段配置
步骤2:修改根布局layout.tsx
替换原简洁版metadata,补充完整配置并迁移其他元素:
import { Metadata } from "next"; import { Providers } from "@/components/providers/providers"; import { FB_PIXEL_ID } from "@/lib/fbmeta/metaPixel"; export const metadata: Metadata = { title: "test", defaultTitle: "test", description: "test", // 视口设置 viewport: "width=device-width, initial-scale=1.0, maximum-scale=1.0", // 网站图标 icons: { icon: "/favicons/favicon.png", }, // OpenGraph 配置 openGraph: { type: "website", url: process.env.NEXT_PUBLIC_BASE_URL, images: [ { url: `${process.env.NEXT_PUBLIC_BASE_URL}/ogp.png`, width: 1200, height: 630, alt: "test", }, ], }, // Twitter 配置 twitter: { handle: "****", site: "*****", cardType: "summary_large_image", // 可选,按需设置卡片类型 }, // Facebook App ID 自定义 meta 标签 other: { "fb:app_id": process.env.NEXT_PUBLIC_FACEBOOK_APP_ID, }, }; type Props = Readonly<{ children: React.ReactNode; }>; export default function RootLayout(props: Props) { return ( <html suppressHydrationWarning> <head /> <body> {/* Facebook 像素 noscript 代码 */} <noscript> <img style={{ display: "none" }} src={`https://www.facebook.com/tr?id=${FB_PIXEL_ID}&ev=PageView&noscript=1`} /> </noscript> <Providers>{props.children}</Providers> </body> </html> ); }
方案二:继续使用next-seo的DefaultSeo组件
若习惯使用next-seo,可继续在 App Router 中使用,需满足:
next-seo版本需在 v6.0.0 以上(支持 App Router)- 将
DefaultSeo放在根布局的组件结构中(无需嵌套在<head>标签内)
修改根布局layout.tsx
import { Providers } from "@/components/providers/providers"; import { DefaultSeo, DefaultSeoProps } from "next-seo"; import { FB_PIXEL_ID } from "@/lib/fbmeta/metaPixel"; const defaultSeo: DefaultSeoProps = { title: "test", defaultTitle: "test", description: "test", openGraph: { type: "website", url: process.env.NEXT_PUBLIC_BASE_URL, images: [ { url: `${process.env.NEXT_PUBLIC_BASE_URL}/ogp.png`, width: 1200, height: 630, alt: "test", }, ], }, twitter: { handle: "****", site: "*****", }, facebook: { appId: `${process.env.NEXT_PUBLIC_FACEBOOK_APP_ID}`, }, }; type Props = Readonly<{ children: React.ReactNode; }>; export default function RootLayout(props: Props) { return ( <html suppressHydrationWarning> <head /> <body> <DefaultSeo {...defaultSeo} /> {/* 视口、图标可通过 next-seo 的 additionalMetaTags/additionalLinkTags 配置,或同时使用内置 Metadata */} <noscript> <img style={{ display: "none" }} src={`https://www.facebook.com/tr?id=${FB_PIXEL_ID}&ev=PageView&noscript=1`} /> </noscript> <Providers>{props.children}</Providers> </body> </html> ); }
注意事项
- 子页面需自定义 SEO 数据时,方案一可在页面文件中导出
metadata覆盖全局配置;方案二可使用NextSeo组件单独配置 - 若同时使用内置 Metadata 和
next-seo,两者配置的元标签不会冲突,优先以页面级配置为准
内容的提问来源于stack exchange,提问作者aaa
相关产品推荐
相关产品推荐

