---
name: schema-markup
description: Generate validated JSON-LD structured data for a finished blog post using the @graph pattern.
---

# Schema Markup Generation

## Use this when

schema, json-ld, structured data, schema markup, generate schema.

## Process

Read the post and extract title, author (name, title, social links), dates, description, FAQ pairs if any, images, organization info, approximate word count, and slug.

Build one `@graph` array combining, with stable `@id` references so entities can cross-reference each other:
- BlogPosting: headline, description, datePublished, dateModified, author (@id reference to Person), publisher (@id reference to Organization), image (@id reference), mainEntityOfPage, wordCount, and a short articleBody excerpt.
- Person: name, jobTitle, url, sameAs profiles (Twitter/LinkedIn/GitHub).
- Organization: name, url, logo (as an ImageObject), sameAs profiles.
- BreadcrumbList: Home -> Category (or "Blog" if none) -> Post Title, sequential positions starting at 1.
- ImageObject for the cover image: absolute crawlable URL, width/height reflecting the real asset, caption matching the alt text.
- VideoObject for each embedded YouTube video, if any: name, description excerpt, thumbnailUrl, uploadDate, contentUrl, embedUrl, duration.
- FAQPage only when the post has a real, visible FAQ with at least one genuine Question/Answer pair. It earns no Google rich-result or ranking credit as of 2026-05-07 and should never be added purely for schema completeness or as a substitute for QAPage.

Do not recommend HowTo, ClaimReview, SpecialAnnouncement, Course Info, Estimated Salary, Learning Video, Vehicle Listing, or PracticeProblem as Google-eligibility tactics; their Search Console rich-result support has been retired or never existed, even though some remain schema.org-valid in principle.

Validate before output: every `@id` reference resolves inside the graph; `dateModified` is on or after `datePublished`; headline is concise; all URLs are absolute; image dimensions are positive integers; breadcrumb positions are sequential. Never invent a field value (author name, dates, dimensions) — mark it N/A when the source content doesn't supply it.

Security requirement: build the JSON with a real encoder, never string interpolation, and before embedding in an HTML `<script>` tag, escape `</` to `<\/` and literal `<` to `\u003c` so user-controlled fields (headline, description, author name, image URL, breadcrumb labels) can never break out of the script block.

Output as a single `<script type="application/ld+json">` block, or as standalone JSON for a CMS field, matching what the project already uses.

