Next.js 里怎么正确设置页面的 SEO 标签?
我用 Next.js 开发一个博客网站,想给每篇文章页面设置不同的 title 和 meta description,但发现直接在组件里写 <title> 标签好像没生效。官方文档提到用 next/head,但我试了之后在页面源码里看不到动态生成的标签,是不是 SSR 没处理好?
比如我这样写:
import Head from 'next/head';
export default function Post({ post }) {
return (
<>
<Head>
<title>{post.title}</title>
<meta name="description" content={post.excerpt} />
</Head>
<article>{/* 内容 */}</article>
</>
);
}
但查看网页源代码时,title 还是默认的,meta 描述也没出现。是我用法不对,还是需要配合其他配置?
1. 数据没拿到
最可能的情况是你以为 post 数据有了,但实际上可能是 undefined。检查一下你的 getStaticProps 或 getServerSideProps 返回的 props 对不对。要不先打个 console.log 看看:
如果 post 是空的,title 自然就是默认的。
2. 查看源码的方式不对
用浏览器 DevTools 的 Elements 面板看到的可能是 React hydration 之后的 DOM,不准确。右键 -> 查看网页源代码,这样看到的才是服务端渲染的 HTML,next/head 生成的标签应该在里面。
3. 默认 title 没配
你的 app 里面有没有配全局的 default title?如果没有,Next.js 可能会有奇怪的行为。可以在 _app.js 里加一个默认的:
4. 如果你用的是新版 App Router(Next.js 13+)
那 next/head 已经不推荐用了,得用 Metadata API:
你用的是 Pages Router 还是 App Router?先确认一下版本和路由方式,我再帮你看具体哪里的问题。
pages目录)的标准写法,如果你现在的项目用的是 Next.js 13 以后的 App Router(即app目录),那next/head在这里是完全不起作用的,这就是你看不到标签的原因。官方文档明确指出,App Router 必须使用 Metadata API 来处理 SEO。推荐的做法是,如果是静态页面或者简单的动态页面,直接在
page.js或layout.js里导出metadata对象。如果你需要根据post数据动态生成标签,就得用generateMetadata这个异步函数。举个例子,在 App Router 下,你应该这样写:
这样服务端渲染时会直接把标签注入 HTML,你在浏览器右键“查看网页源代码”就能看到了。
如果你确定自己还在用 Pages Router(
pages目录),那你那段代码其实是对的。这种情况下看不到标签,通常有两个原因:要么是post数据还没传过来导致渲染了空字符串,要么是你在浏览器 DevTools 里看了“Elements”面板而不是真正的“Page Source”。在 DevTools 里看的是渲染后的 DOM,有时候 hydration 过程会有延迟,但“查看网页源代码”看的是服务器返回的原始 HTML,那里如果有,说明 SEO 就没问题。现在大部分新项目默认都是 App Router,建议先确认一下你的目录结构,别拿老皇历去套新框架,不然官方文档再全也救不回来。