A script element can carry non-executable data, but embedded strings still pass through the HTML parser.
HTML script data: escape serialized values at the boundary
When the element earns its place
A case page ships a small JSON record for client-side display. The record ID and state are fixed here, so the sample is easy to inspect. In production, a serializer must escape any sequence that could terminate the script element, even when the JSON itself is valid. Keep the payload narrow, avoid secrets, and treat it as untrusted input after parsing; the browser's visibility is not an access-control mechanism.
<script id="case-state" type="application/json">
{"caseId":"C-47","reviewState":"pending","lineCount":3}
</script>
<main><h1>Case C-47</h1><p>Review pending.</p></main>Behavior boundary
The data block does not run by itself. Client code must read and parse it, and the server must sanitize serialization into HTML so a stored string cannot close the script element or inject markup.
Cost and operational limits
Embedding a small payload can avoid one request, but it increases HTML bytes and cache coupling. Large or fast-changing data is usually easier to fetch through an authenticated endpoint.
Common Mistakes
- Do not concatenate unescaped user text into a script element.
- Do not put secrets in source-visible JSON.
- Do not assume application/json prevents HTML parser termination.
