You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js使用Head/getStaticProps时元数据无法被社交平台正确解析

Next.js 元标签抓取失败排查与修复方案

1. 最高优先级排查:服务端初始HTML未注入动态元标签

所有社交爬虫、元标签检测工具默认不会执行页面的客户端JavaScript,只会抓取服务端直接返回的初始HTML内容。你在浏览器开发者工具的元素面板里能看到元标签,是客户端JS hydrate完成后动态注入的结果,不代表服务端返回的源码里存在这些标签。
验证方式:打开目标页面,右键选择「查看网页源代码」,在源码中搜索title、og:title等字段,如果只能找到_app.js里定义的默认标题acacia.,找不到业务页的动态标题,就确认是这个问题。
触发原因:你的actionData如果是在客户端通过useEffect等钩子异步拉取,服务端渲染阶段拿不到这部分数据,自然无法生成对应的动态元标签。
修复方案:

  • Pages Router 场景下,将actionData的获取逻辑迁移到getStaticProps(构建时生成)或getServerSideProps(每次请求服务端获取)中,将数据作为props传入页面组件,保证服务端渲染阶段就能拿到完整数据生成元标签
  • App Router 场景下,使用官方提供的generateMetadata API生成页面元数据,不要在客户端组件中定义元标签。

2. 元标签缺少唯一key导致重复标签,爬虫取值错误

Next.js的next/head组件依靠key属性、标签的name/property属性做重复标签去重。你当前代码里_app.js的title标签加了key="title",但自定义Meta组件里的title、description、og系列、twitter系列标签都没有配置对应的key,会导致head中同时存在默认元标签和业务页动态元标签,多数爬虫会优先读取第一个出现的标签,也就是默认的acacia.标题,忽略后面的动态标签。
修复方案:给所有元标签配置全局唯一的固定key,保证同key的标签只会保留最后渲染的那一个,修改Meta组件代码如下:

import Head from "next/head"
import Script from "next/script"

function Meta(props) {
    return (
        <Head>
            <title key="title">{props.title}</title>
            <meta key="description" name="description" content={props.desc} />
            <meta key="og:type" property="og:type" content="website" />
            {props.canonical && <link rel="canonical" href={`${props.canonical}`} key="canonical" />}
            <meta key="og:title" property="og:title" content={props.title} />
            <meta key="og:description" property="og:description" content={props.desc} />
            <meta key="og:site_name" property="og:site_name" content="acacia" />
            <meta key="og:url" property="og:url" content={`${props.canonical}`} />  
            <meta key="twitter:card" name="twitter:card" content="summary" /> 
            <meta key="twitter:title" name="twitter:title" content={props.title} />
            <meta key="twitter:description" name="twitter:description" content={props.desc} />
            <meta key="twitter:site" name="twitter:site" content="@acacia_app" />
            <meta key="twitter:creator" name="twitter:creator" content="@acacia_app" />
            <link key="favicon" rel="icon" type="image/png" href="/favicon.ico" />
            <link key="appleTouchIcon" rel="apple-touch-icon" href="/favicon.ico" />
            {props.image ? 
                (<meta key="og:image" property="og:image" content={`${props.image}`} />) : 
                (<meta key="og:image" property="og:image" content="你的公网默认OG图片绝对地址" />)} 
            {props.image && <meta key="twitter:image" name="twitter:image" content={`${props.image}`} />}
            {props.robot && <meta key="robots" name="robots" content={props.robot} />}
            {props.css && <link key="pageCss" rel="stylesheet" href={`${props.css}`}/>}
            {props.js && <Script key="pageJs" type="text/javascript" src={`${props.js}`} />}
        </Head>
    )
}

export default Meta

3. _document.js 配置注意事项

你贴的_document.js完整代码本身没有逻辑错误,emotion服务端样式注入的配置是正确的,不会干扰元标签渲染。
注意规则:next/document暴露的Head组件仅用于放置全站通用、不需要动态替换的静态标签(比如charset、theme-color、全局字体、公共favicon、服务端注入的样式标签),不要在_document.js里写title、description这类需要按页面替换的动态标签,你当前的写法符合这个规则,不需要调整。

4. 其他校验项

  • og:image、twitter:image必须使用公网可直接访问的绝对路径,不能用相对路径;图片不要配置防盗链拦截爬虫请求,尺寸推荐1200*630,单图大小不超过8MB
  • 不要给元标签添加data-nosnippet、robots: noindex这类拦截爬虫收录的属性
  • 修复完成后,清空CDN缓存、Next.js构建缓存后重新部署,旧缓存会导致爬虫拿到历史版本的错误页面
  • 每次验证都以「查看网页源代码」里的内容为准,开发者工具元素面板展示的是客户端执行后的DOM结果,不能作为爬虫抓取内容的判断依据。

内容的提问来源于stack exchange,提问作者Maxime Crtgn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:57:24