Why malformed JSON-LD can look like missing JSON-LD
A page can contain a JSON-LD script and still be reported as having “no JSON-LD.” The usual cause is not detection—it is a parser that silently discards the block after JSON.parse fails.
The parse-and-discard trap
A common implementation finds every <script type="application/ld+json">, parses each text value, and retains only successful results. This looks compact:
const schemas = scripts
.map(script => {
try {
return JSON.parse(script.textContent || "");
} catch {
return null;
}
})
.filter(Boolean);
The final array is empty when every block is malformed. If the interface uses that array to decide whether structured data exists, a syntax problem becomes a false “not found” result.
Detection, parsing, and validation are separate states
A reliable inspector treats these as three different questions:
- Detection: Is a JSON-LD script present in the document?
- Parsing: Is its text valid JSON, and where does parsing fail?
- Validation: Does the parsed value follow the expected Schema.org or platform structure?
Skipping directly from detection to validated entities removes the evidence needed to answer the second question.
A source-preserving data model
Keep one record for every script before parsing it. Attach either a parsed value or a parse error, never replace the source:
{
blockIndex: 1,
raw: "{ \"@type\": \"Product\", ... }",
parsed: undefined,
parseError: {
line: 7,
column: 5,
excerpt: " \"priceCurrency\": \"USD\"",
pointer: " ^"
}
}
Once parsing succeeds, normalize top-level arrays and @graph entries into inspection items while retaining their block index and JSONPath. The same mapping should also apply to nested typed entities such as an Offer inside a Product.
A five-minute debugging workflow
- Confirm the script exists in the rendered DOM, not only in the original HTML response.
- Copy the exact raw text and inspect the reported line and column.
- Fix JSON syntax first: commas, quotes, escaping, and truncated output.
- After parsing succeeds, inspect Schema.org structure and platform-specific requirements.
- Run the live URL through an official validator before shipping.
为什么错误的 JSON-LD 会被普通检查器显示为“不存在”
常见实现会先寻找所有 JSON-LD 脚本,再对每个代码块调用 JSON.parse,最后过滤解析失败的结果。如果所有代码块都包含语法错误,过滤后的数组就是空数组,界面便会错误地显示“未检测到 JSON-LD”。
正确做法是把三个状态分开:页面是否存在代码块、代码块能否解析、解析后的实体是否符合 Schema.org 或平台要求。每个原始代码块都应在解析前被保存;解析失败时记录准确行号、列号、上下文和源码,而不是丢弃它。
解析成功后,还要识别顶层数组、@graph 与嵌套的带类型实体,并保留它们和原始代码块的对应关系。对于 React、Vue、Tag Manager 等动态注入的场景,还需要监听 JSON-LD 脚本变化,并提供明确的手动重新扫描。