Next.js中Head组件内JSON-LD脚本条件渲染的测试问题
问题描述
我们在Next.js项目中,通过Head组件内的Script标签添加JSON-LD格式的结构化数据,且该Script标签为条件渲染(仅当structuredData存在时才渲染)。
OurPage.tsx代码如下:
<Head> <title>{"meta title"}</title> <meta name="description" content="meta desc" /> { structuredData && <Script nonce={nonce} type="application/ld+json" // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{ __html: structuredData }} />} </Head>
我们尝试用React Testing Library和Jest测试该行为,通过mock next/head来实现,但渲染后的页面仅显示title和meta描述标签,预期的script标签缺失。测试代码如下:
jest.mock('next/head', () => { return { __esModule: true, default: ({ children }: { children: Array<React.ReactElement> }) => { return <>{children}</>; }, }; }); const { debug } = render(<OurPage />); debug();
解决方案
要解决这个问题,需要从三个关键点入手:
1. 传入必要的触发条件props
测试时未给OurPage传入structuredData和nonce,导致条件渲染判断structuredData && ...不成立,Script标签不会渲染。
修改测试代码,传入有效的结构化数据和nonce值:
// 构造符合JSON-LD格式的测试数据 const mockStructuredData = JSON.stringify({ "@context": "https://schema.org", "@type": "WebPage", name: "Test Page" }); // 渲染组件时传入props const { debug } = render( <OurPage structuredData={mockStructuredData} nonce="test-nonce" /> ); debug();
2. Mock Next.js的Script组件
Next.js的Script组件(来自next/script)是框架封装的特殊组件,在测试环境中可能不会直接渲染为标准的<script>标签。需要额外mock这个组件,让它输出普通的script元素:
jest.mock('next/script', () => { return { __esModule: true, default: (props: any) => { return <script {...props} />; }, }; });
3. 修正Head组件的Mock类型
原Head mock中定义children为Array<React.ReactElement>,但React的children实际类型是ReactNode(支持单个元素、多个元素或其他类型),修正类型避免渲染异常:
jest.mock('next/head', () => { return { __esModule: true, default: ({ children }: { children: React.ReactNode }) => { return <>{children}</>; }, }; });
完成以上修改后,重新运行测试,就能在debug输出中看到预期的JSON-LD script标签了。
内容的提问来源于stack exchange,提问作者Ayyappa Gollu
相关产品推荐
相关产品推荐

