# Invalid structured data (JSON-LD) in Next.js

> How to fix invalid structured data (json-ld) in Next.js — with the exact fix and copy-paste code.

_Category: AI readiness · Detector `aeo` · Check `structured-data-invalid` · Severity: warning_

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.

## The fix for Next.js

Render the `JSON-LD` from a Server Component with `JSON.stringify`. It runs server-side, so the escaped block ships in the initial HTML where crawlers read it — no client hydration needed.

```tsx
export default function Page() {
  const jsonLd = { '@context': 'https://schema.org', '@type': 'Article', headline }
  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
    />
  )
}
```

[Next.js docs](https://nextjs.org/docs/app/guides/json-ld)

### 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

## How VibeCheck detects it

The `aeo` detector flags this live in the browser and reports it to the widget's Problems list — and to your coding agent over MCP.

- **Issue string:** `Structured data is invalid`
- **Threshold:** A JSON-LD script exists but fails JSON.parse or doesn’t reference schema.org

## 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.

See the general, framework-agnostic fix: https://vibecheck.wcgw.fun/fix/invalid-structured-data.md

---

Fix guide from VibeCheck — https://vibecheck.wcgw.fun/fix/invalid-structured-data. Full site index for LLMs: https://vibecheck.wcgw.fun/llms.txt
