Skip to content
Notes

Closing a script tag by accident

JSON.stringify does not escape angle brackets, and JSON-LD lives inside a script tag.

Rough noteWritten

Written once, in the moment. I have not gone back over it.

The site embeds structured data the usual way: a <script type="application/ld+json"> filled by dangerouslySetInnerHTML with JSON.stringify(jsonLd).

JSON.stringify escapes quotes and backslashes. It does not escape <. So a value containing the literal string </script> closes the tag early, and whatever follows it in that JSON gets parsed by the browser as HTML.

The inputs were deployer-set environment variables, not anything a visitor types, so this was never live. I fixed it anyway. The same change started feeding guide titles into JSON-LD, so the values are content now, not just deploy config.

The fix is a serializeJsonLd() helper that escapes <, >, and & into their unicode forms before the string reaches the DOM. Three characters, six lines, plus tests for the </script> case and for <!--.

Written . Something wrong or out of date? Tell me.