Next.js13(SSR)+Strapi添加FAQ结构化数据失败求助
你的问题根源有两个:结构化数据生成逻辑错误和Script组件使用方式不符合搜索引擎要求,下面是具体修复方案:
1. 修复语法错误的核心原因
你用place.faq && place.faq.length > 0 && place.faq.map(...)生成mainEntity的写法有问题——当没有FAQ数据时,这个表达式会返回false,而JSON不允许布尔值作为mainEntity的合法值,直接触发Unexpected token ':'的语法错误。
必须确保mainEntity始终是数组类型,修改成条件判断后返回数组或空数组:
const faqSchema = place.faq?.length ? { "@context": "http://schema.org", "@type": "FAQPage", "mainEntity": place.faq.map((item) => ({ "@type": "Question", "name": item.title, "acceptedAnswer": { "@type": "Answer", "text": item.content, }, })) } : null;
2. 正确使用Next.js Script组件让谷歌识别
谷歌检测不到结构化数据,是因为你没给Script标签指定type="application/ld+json"——这是搜索引擎识别JSON-LD格式的必要属性。同时要确保只有存在FAQ数据时才渲染这个组件:
return ( <> {/* 仅当有FAQ数据时渲染结构化数据脚本 */} {faqSchema && ( <Script id="faq-schema" type="application/ld+json" strategy="afterInteractive" dangerouslySetInnerHTML={{ __html: JSON.stringify(faqSchema) }} /> )} {/* 原有页面组件保持不变 */} <Carousel place={place} /> <Layout> <div className="lg:pt-40 lg:pb-24 md:py-32 sm:py-24 py-8 lg:px-28 md:px-20"> <Header place={place} /> <Content place={place} /> {place.faq?.length && <FAQSection faq={place.faq} />} </div> <CardsSection places={morePlaces} params={params} /> </Layout> <StickyDiv /> </> );
这里用dangerouslySetInnerHTML插入JSON字符串,比直接在Script标签内写表达式更稳妥,避免Next.js模板解析引发的语法问题。
3. 更推荐:用Next.js 13 App Router的Metadata API
在App Router中,官方推荐用generateMetadata函数生成结构化数据,这种方式在服务器端直接注入到HTML的<head>里,更符合SSR最佳实践,也能确保爬虫正确抓取:
在[slug]/page.tsx顶部添加:
export async function generateMetadata({ params }: { params: { slug: string; city: string; lang: string } }) { const id = params.slug.split('-').slice(-1)[0]; if (!Number.isFinite(parseInt(id))) { return {}; } const place = await fetchPlace(id); if (!place.faq?.length) { return {}; } return { other: { "application/ld+json": { "@context": "http://schema.org", "@type": "FAQPage", "mainEntity": place.faq.map((item) => ({ "@type": "Question", "name": item.title, "acceptedAnswer": { "@type": "Answer", "text": item.content, }, })) } } }; }
用这种方式的话,你可以删掉原来的<Script>组件,结构化数据会自动注入到页面<head>中,无需手动处理脚本渲染。
验证方式
修复后可以用谷歌结构化数据测试工具验证,或者在浏览器开发者工具的Elements面板里,查看是否存在正确的application/ld+json类型脚本标签。
内容的提问来源于stack exchange,提问作者Ahmed Zrouqui

