Generate complete JSON-LD schema markup for blog posts with Article/BlogPosting, Person, Organization, BreadcrumbList, ImageObject, and optional FAQPage. Validates against Google requirements and warns about deprecated types. Use when user says "schema", "blog schema", "json-ld", "structured data", "schema markup", "generate schema".
72
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Generates complete, validated JSON-LD schema markup for blog posts using the @graph pattern. Combines multiple schema types into a single script tag with stable @id references for entity linking.
Read the blog post and extract all schema-relevant data:
Complete BlogPosting with recommended properties when applicable:
{
"@type": "BlogPosting",
"@id": "{siteUrl}/blog/{slug}#article",
"headline": "Concise post title",
"description": "Concise page-specific meta description",
"datePublished": "YYYY-MM-DD",
"dateModified": "YYYY-MM-DD",
"author": { "@id": "{siteUrl}/author/{author-slug}#person" },
"publisher": { "@id": "{siteUrl}#organization" },
"image": { "@id": "{siteUrl}/blog/{slug}#primaryimage" },
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "{siteUrl}/blog/{slug}"
},
"wordCount": 2400,
"articleBody": "First 200 characters of content as excerpt..."
}Google's Article structured data docs do not define required Article
properties. Include headline, datePublished, author, publisher, and
image when applicable, validate with the Rich Results Test, and treat missing
fields as warnings unless the target surface requires them. Recommended
properties: description, dateModified, mainEntityOfPage, wordCount, articleBody
(excerpt).
Author schema with stable @id for cross-referencing:
{
"@type": "Person",
"@id": "{siteUrl}/author/{author-slug}#person",
"name": "Author Name",
"jobTitle": "Role or Title",
"url": "{siteUrl}/author/{author-slug}",
"sameAs": [
"https://twitter.com/handle",
"https://linkedin.com/in/handle",
"https://github.com/handle"
]
}Optional properties (include when available):
alumniOf - Educational institution (Organization type)worksFor - Employer (reference to Organization @id if same entity)Blog's parent organization entity:
{
"@type": "Organization",
"@id": "{siteUrl}#organization",
"name": "Organization Name",
"url": "{siteUrl}",
"logo": {
"@type": "ImageObject",
"url": "{siteUrl}/logo.png",
"width": 600,
"height": 60
},
"sameAs": [
"https://twitter.com/org",
"https://linkedin.com/company/org",
"https://github.com/org"
]
}Logo requirements: use a valid crawlable image URL and follow the active Organization and Article documentation for the target surface. Do not invent hard logo dimensions unless the project or current docs require them.
Navigation breadcrumb schema showing content hierarchy:
{
"@type": "BreadcrumbList",
"@id": "{siteUrl}/blog/{slug}#breadcrumb",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "{siteUrl}"
},
{
"@type": "ListItem",
"position": 2,
"name": "Category Name",
"item": "{siteUrl}/blog/category/{category-slug}"
},
{
"@type": "ListItem",
"position": 3,
"name": "Post Title",
"item": "{siteUrl}/blog/{slug}"
}
]
}If no category is available, use "Blog" as the second breadcrumb item with
{siteUrl}/blog as the URL.
Extract Q&A pairs from the blog post's FAQ section:
{
"@type": "FAQPage",
"@id": "{siteUrl}/blog/{slug}#faq",
"mainEntity": [
{
"@type": "Question",
"name": "What is the question?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The complete answer text (40-60 words with statistic)."
}
}
]
}Important note: Google retired FAQ rich results for all sites on 2026-05-07.
FAQPage is not a Google rich result path. Only emit FAQPage when visible FAQ
content exists, with at least one valid Question and matching visible answer.
Treat it as entity clarity markup, not a Google rich-result promise. The
Article/BlogPosting schema remains the priority for blog search eligibility.
For each YouTube video embedded in the post, generate a VideoObject schema:
{
"@type": "VideoObject",
"@id": "{siteUrl}/blog/{slug}#video-{index}",
"name": "Video title",
"description": "Video description excerpt (first 200 chars)",
"thumbnailUrl": "https://img.youtube.com/vi/{videoId}/hqdefault.jpg",
"uploadDate": "{ISO 8601 date}",
"contentUrl": "https://www.youtube.com/watch?v={videoId}",
"embedUrl": "https://www.youtube.com/embed/{videoId}",
"duration": "PT{M}M{S}S",
"interactionStatistic": {
"@type": "InteractionCounter",
"interactionType": { "@type": "WatchAction" },
"userInteractionCount": {viewCount}
}
}Add each VideoObject to the @graph array. Use #video-1, #video-2 etc. for
the @id fragment. Extract video metadata from the embed's noscript fallback or
from YouTube Data API if available via blog-google.
Cover image schema for the post's primary image:
{
"@type": "ImageObject",
"@id": "{siteUrl}/blog/{slug}#primaryimage",
"url": "https://cdn.pixabay.com/photo/.../image.jpg",
"width": 1200,
"height": 630,
"caption": "Descriptive caption matching alt text"
}Image requirements:
Check per-surface support before recommending schema types:
| Type | Google rich-result status | Valid entity/context use |
|---|---|---|
| HowTo | Not a current Google rich-result tactic | Valid schema.org type when the page genuinely contains how-to content |
| Dataset | Not for generic blog rich results | Valid for dataset pages and Dataset Search eligibility |
| QAPage | Not the same as FAQPage | Valid when the page contains one question with user-submitted answers |
| SpecialAnnouncement, PracticeProblem, Sitelinks Search Box | Do not recommend for general blog posts | Use only when current official docs and page content match |
Validation checks:
QuestionAI citation optimization note: Relevant schema helps entity clarity and rich-result eligibility where supported, but structured data is not required for Google generative AI search visibility. Prioritize Article/BlogPosting, Person, Organization, and BreadcrumbList. Add ImageObject or VideoObject when assets exist, and add FAQPage only when visible FAQ content exists.
Combine all schemas into a single <script> tag using the @graph pattern:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "BlogPosting", ... },
{ "@type": "Person", ... },
{ "@type": "Organization", ... },
{ "@type": "BreadcrumbList", ... },
{ "@type": "FAQPage", ... },
{ "@type": "VideoObject", ... },
{ "@type": "ImageObject", ... }
]
}
</script>@graph pattern benefits:
Output options:
<head> or before </body>Save the generated schema to the blog post file or to a separate schema file as the user prefers.
aec971a
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.