
Next.js 的 组件会自动转义脚本内容,导致 " 等 HTML 实体替代双引号,破坏 JSON-LD 结构;需使用 dangerouslySetInnerHTML 安全注入预序列化的 JSON 字符串。
next.js 的 `
` 组件会自动转义脚本内容,导致 `"` 等 html 实体替代双引号,破坏 json-ld 结构;需使用 `dangerouslysetinnerhtml` 安全注入预序列化的 json 字符串。在 Next.js 应用中为页面添加结构化数据(如 NewsArticle Schema)是提升 SEO 和富媒体展示的关键步骤。但直接将 JSON.stringify() 的结果作为子元素插入 <script type="application/ld+json"></script> 会导致内容被 HTML 转义——例如 "@context" 变为 "@context",使搜索引擎无法解析,Schema 验证失败。
根本原因在于:Next.js 的 Head 组件(尤其在服务端渲染时)将 JSX 子节点视为文本内容并进行 HTML 转义,而非原始 HTML 片段。这不是安全漏洞,而是框架默认的防 XSS 行为;但对 JSON-LD 这类必须保持原始 JSON 格式的内联脚本而言,需显式绕过该机制。
✅ 正确做法是:不将 JSON 对象作为子元素传入,而是通过 dangerouslySetInnerHTML 将已序列化的 JSON 字符串作为 HTML 内容注入。注意:此处“dangerous”仅指需确保数据来源可信(如服务端生成、严格校验的变量),而 JSON-LD 本身不含可执行代码,风险极低。
以下是优化后的 Schema 组件实现:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
// components/Schema.tsx
import { useEffect } from 'react';
const Schema = ({ url, image, datePublished, dateModified }: {
url: string;
image: string;
datePublished: string;
dateModified: string;
}) => {
// 构建 Schema 对象(确保所有变量已定义,避免 undefined 导致 JSON 错误)
const schemaData = {
'@context': 'https://schema.org',
'@type': 'NewsArticle',
mainEntityOfPage: {
'@type': 'WebPage',
'@id': url,
},
headline: 'Article headline',
image,
datePublished,
dateModified,
author: {
'@type': 'Person',
name: '****',
},
publisher: {
'@type': 'Organization',
name: 'macandental',
logo: {
'@type': 'ImageObject',
url: '/logo.png', // 建议使用绝对路径或 public 目录下的静态资源
},
},
};
// 序列化为紧凑 JSON(生产环境推荐),开发时可用 JSON.stringify(..., null, 2) 便于调试
const schemaJSON = JSON.stringify(schemaData);
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: schemaJSON }}
/>
);
};
export default Schema;在页面组件中使用(注意传入必要参数):
// pages/faq.tsx
import Head from 'next/head';
import Schema from '@/components/Schema';
export default function FaqPage() {
const url = 'https://example.com/faq';
const image = 'https://example.com/faq-cover.jpg';
const datePublished = new Date().toISOString();
const dateModified = datePublished;
return (
<>
<Head>
<title>常见问题 | macandental</title>
<meta name="description" content="了解关于牙科护理的常见问题解答" />
<meta property="og:type" content="article" />
<Schema
url={url}
image={image}
datePublished={datePublished}
dateModified={dateModified}
/>
</Head>
<main>
{/* 页面内容 */}
</main>
</>
);
}⚠️ 注意事项:
-
务必校验输入值:
url、image、日期等字段不能为空或undefined,否则JSON.stringify()会输出null或引发运行时错误; -
避免客户端动态拼接敏感数据:如用户输入未过滤的内容,应先清洗或改用服务端
getServerSideProps注入; - 验证输出:部署后使用 Google Rich Results Test 或 Schema Markup Validator 检查是否成功解析;
-
Next.js App Router 用户:若使用
app/目录,请改用metadata中的other字段或自定义Script组件(原理相同,仍需dangerouslySetInnerHTML)。
通过此方案,JSON-LD 将以标准、未转义的格式渲染到 中,确保结构化数据被搜索引擎准确识别,真正发挥 Schema 的语义化价值。

















