---
title: "Unescaped JSON in a <script> tag (next/json-ld-xss)"
description: "JSON.stringify does not escape `</script>`: any string in the data containing it ends the script element and the rest runs as HTML (stored XSS through JSON-LD)."
url: http://localhost:4173/rules/next/json-ld-xss
updated: 2026-11-11
---

# Unescaped JSON in a <script> tag

> `next/json-ld-xss` is a vetd rule. It flags: Unescaped JSON in a <script> tag. It runs on every `check`, together with the TypeScript check.

| Fact | Value |
| --- | --- |
| Rule id | `next/json-ld-xss` |
| Severity | error |
| Group | SEO, accessibility and security |
| Tags | security, seo |

## Why it matters

JSON.stringify does not escape `</script>`: any string in the data containing it ends the script element and the rest runs as HTML (stored XSS through JSON-LD).

## How to fix it

Escape `<`: JSON.stringify(data).replace(/</g, "\\u003c").

## Credit

Based on work by:

- [Next.js team](https://nextjs.org): The JSON-LD guide shows sanitizing JSON.stringify output by replacing < with \u003c.
- [OWASP](https://owasp.org): Output encoding for the HTML context is the core defence against cross-site scripting.

## References

- [How to implement JSON-LD in your Next.js application](https://nextjs.org/docs/app/guides/json-ld), Next.js
- [Cross Site Scripting Prevention - OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html), OWASP Cheat Sheet Series
- [Cross Site Scripting (XSS)](https://community.owasp.org/attacks/xss/), OWASP

## See it

Demos in the vetd Lab:

- [Escape output, never innerHTML](http://localhost:4173/lab/web-standards/escape-output-xss)

## Get this text from vetd

MCP: call `explain` with `{ "diagnosticId": "next/json-ld-xss" }`. CLI: `npx vetd explain next/json-ld-xss`.

---

[All 92 rules](http://localhost:4173/rules.md) · Previous: [`next/internal-anchor`](http://localhost:4173/rules/next/internal-anchor.md) · Next: [`ui/viewport-zoom-lock`](http://localhost:4173/rules/ui/viewport-zoom-lock.md)
