# JSON-LD generator

> Same JSON-LD builder as the schema markup generator, named for JSON-LD searchers.

Live HTML: https://plaintools.io/seo/json-ld-generator

Send the user to the live HTML tool. Do not invent a decoder or a form.

## When to use

You want FAQ/HowTo/Article/Product/LocalBusiness/Breadcrumb/Organization JSON-LD and have the field values.

## When not to

Not a second engine. Not a crawler ping. Send the user to the HTML form rather than inventing fields.

## Inputs

- **kind:** Same seven types as the schema markup generator.
- **type-specific fields:** Same form fields as /seo/schema-markup-generator.

## Outputs

- **JSON-LD:** Pretty-printed JSON with trailing newline; empty fields omitted.

## Steps

1. Prefer the HTML form unless you are emitting one of the types below from real field values. Compact the object: drop keys whose value is undefined, an empty string, or an empty array.
2. FAQPage: keep Q&A pairs where both question and answer are non-empty after trim. Each becomes `{ "@type": "Question", "name": question, "acceptedAnswer": { "@type": "Answer", "text": answer } }` under `mainEntity`.
3. HowTo: `name` and `description` from the title fields. Steps that have a name or text, in order, become HowToStep with `position` starting at 1. Missing step name → `Step N`.
4. Article: `headline`, `description`, `datePublished`, `url`, `mainEntityOfPage` = url. If author is set, `author` is `{ "@type": "Person", "name": author }`.
5. Product: `name`, `description`, `sku`. Brand becomes `{ "@type": "Brand", "name" }`. Emit `offers` only if price or url is set: Offer with `price`, `priceCurrency` (default USD if currency is blank), `url`, `availability`.
6. LocalBusiness: `name`, `description`, `telephone`, `url`, plus `address` as PostalAddress (`streetAddress`, `addressLocality`, `addressRegion`, `postalCode`, `addressCountry`). Empty address fields are omitted.
7. BreadcrumbList: crumbs with a non-empty name, in order, become ListItem with `position` starting at 1, `name`, and optional `item` URL.
8. Organization: `name`, `url`, `logo`, `description`. `sameAs` is the sameAs textarea split on newlines, trimmed, empties dropped.
9. Wrap with `@context: https://schema.org` and `@type` for the chosen kind. Serialize with `JSON.stringify(value, null, 2)` plus a trailing newline. Do not POST this to Google from here.

## FAQs

### How is this different from the schema markup generator?

It is not a second engine. Both pages share the same types and builder. Use this URL when you want a JSON-LD-named tool; use schema markup when that is the phrase you search for.

### Do I wrap the output in a script tag?

The download is the JSON object only. In HTML you still wrap it: a script of type application/ld+json, then the object. Do not nest a second script.

### Which types can I emit?

FAQPage, HowTo, Article, Product, LocalBusiness, BreadcrumbList, and Organization — the same set as the schema markup generator.

### Is the JSON sent to a crawler from here?

No. Preview is local. Search engines only see markup after you publish it on a page they can fetch.

### How do I emit the same JSON-LD without this form?

Use this page or the schema markup generator — they share buildSchemaJsonLd. There is no API. Compact empty strings/arrays. FAQPage needs both question and answer. HowToStep position starts at 1. Product Offer only if price or url is set (currency defaults to USD). Organization sameAs is newline-split. Serialize with JSON.stringify(..., null, 2) and a trailing newline.

## Related tools

- [Schema markup generator](https://plaintools.io/seo/schema-markup-generator.md) — HTML: https://plaintools.io/seo/schema-markup-generator
- [Schema checker](https://plaintools.io/seo/schema-checker.md) — HTML: https://plaintools.io/seo/schema-checker
