structured-data-generators

Typed factories for schema.org nodes, and a serializer whose output can't break out of its <script> tag.

$ npm install structured-data-generators

view-source: what your page ships application/ld+json
<script type="application/ld+json">
{"@context":"https://schema.org/",
 "@type":"Person",
 "name":"Ada Lovelace",
 "jobTitle":"Analyst \u0026 Metaphysician",
 "description":"\u003c/script\u003e stays inside its tag"}
</script>
toJsonLd escapes <, >, &, U+2028, and U+2029 — untrusted strings can't close the tag.

One minute to first schema

// 1. create — factories stamp the literal @type
import { createPersonSchema, toJsonLd } from "structured-data-generators";

const person = createPersonSchema({
  "@id": "https://example.com/#person",
  name: "Ada Lovelace",
  url: "https://example.com",
});

// 2. serialize — safe to interpolate into HTML
const tag = `<script type="application/ld+json">${toJsonLd(person)}</script>`;

Why this one

Literal-typed @type
createPersonSchema(...)["@type"] is the literal "Person", not string. Graphs that reference each other stay correct at compile time.
Script-safe serializer
Raw JSON.stringify in a script tag is an injection bug waiting for one user-supplied string. The escaping here is tested character by character.
No hidden defaults
Factories stamp @type and pass options through verbatim. JSON key order follows your option order, so snapshot tests of emitted markup stay stable.
Zero dependencies
Plain ESM TypeScript. No framework coupling — this site renders its own head tags with it, and so does viktor.andersson.tech.