vibecheck0.3.0
AI readinessaeostructured-data-invalidwarning

Invalid structured data (JSON-LD) in React

You added JSON-LD, but it’s malformed or missing its schema.org @context, so crawlers parse it, fail, and skip it — you get zero credit for the effort. This is worse than a silent miss because it looks done. Hand-authored or string-concatenated JSON-LD (common in AI output) is exactly where trailing commas and unescaped quotes creep in.

Symptoms

  • Rich Results Test reports a parsing error or missing required field
  • No rich results despite having a JSON-LD block on the page
  • The script contains a trailing comma, unescaped quote, or wrong @context
  • VibeCheck flags the JSON-LD as present but invalid

How VibeCheck catches it

In your widget · Problems

warningaeoStructured data is invalid

To your coding agent · MCP

agent › get_detected_issues
{ detector: "aeo", issue: "Structured data is invalid", threshold: "A JSON-LD script exists but fails JSON.parse or doesn’t reference schema.org" }

The same string in your widget and in your agent’s context — no screenshot, no copy-paste.

Root causes

  • Invalid JSON — trailing commas, unescaped quotes, or comments
  • Missing or wrong "@context": "https://schema.org"
  • String-concatenated JSON-LD instead of JSON.stringify of a real object
  • Interpolated values that weren’t escaped for JSON

The fix for React

Render with JSON.stringify and dangerouslySetInnerHTML so the value is properly escaped exactly once — don’t build the JSON as a template string.

tsx
<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>

Steps

  1. Replace hand-written JSON strings with JSON.stringify of a typed object
  2. Confirm @context is "https://schema.org" and @type is a valid type
  3. Run it through Google’s Rich Results Test until it passes clean

See the general, framework-agnostic fix →

FAQ

How do I know what’s wrong with my JSON-LD?
Paste it into Google’s Rich Results Test or the schema.org validator — both point to the exact line and field. Most failures are a JSON syntax error or a missing @context.
Why does string interpolation cause invalid JSON-LD?
A title with a quote, apostrophe, or newline breaks the surrounding JSON when interpolated raw. JSON.stringify escapes those characters correctly, which is why building an object and stringifying it is the safe pattern.
Can I put several types in one JSON-LD block?
Yes — use an @graph array to declare multiple entities (for example an Organization and a WebSite) in a single script. Keep each node’s @type and required fields valid: one malformed node invalidates the whole block.