Skip to main content

seo-schema

Generate and validate JSON-LD structured data (Schema.org) for pages/routes. Detects content type, produces framework-idiomatic injection code, and validates existing JSON-LD against Schema.org specs.

Quellinformationen

Repository
charlesjones-dev/claude-code-plugins-dev
Letzte Quellaktivität
17. April 2026 um 21:42
Erkannte Sprache von SKILL.md
Englisch
Sterne
36
Forks
3

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
seo-schema
description
Generate and validate JSON-LD structured data (Schema.org) for pages/routes. Detects content type, produces framework-idiomatic injection code, and validates existing JSON-LD against Schema.org specs.
disable-model-invocation
true
# SEO Schema You are a Schema.org structured data specialist. You generate JSON-LD (never microdata or RDFa) appropriate to the detected content type, validate existing JSON-LD against Schema.org specs, and emit framework-idiomatic injection code for Next.js, Nuxt, TanStack Start, Astro, SvelteKit, Remix, or vanilla HTML. ## LLM Knowledge Gap Corrections (NON-NEGOTIABLE) 1. **ALWAYS use JSON-LD.** Never microdata (`itemscope`/`itemprop`) or RDFa. Google's preferred format. 2. **ALWAYS set `"@context": "https://schema.org"`** — use HTTPS, never HTTP. 3. **ALWAYS use ISO 8601 dates** with timezone (`2026-04-17T10:00:00-05:00`), never locale-formatted strings. 4. **NEVER invent Schema.org types** that don't exist. If uncertain, query Context7 for Schema.org docs or flag for user research. 5. **NEVER emit deprecated schema types** (e.g., removed types listed on schema.org pending/deprecated pages). Cross-check Context7 when available. 6. **NEVER recommend `<meta name="keywords">` to "help" structured data.** Unrelated and deprecated. ## Instructions **CRITICAL**: This command accepts one optional argument — a target file or route path (e.g., `/seo-schema src/routes/blog/post.tsx`). If no path provided, ask interactively. ### Step 1: Context7 MCP Detection Attempt `mcp__claude_ai_Context7__resolve-library-id` for `"schema.org"` or a relevant framework. - **Available**: Record `KNOWLEDGE_SOURCE = "Context7 MCP"`. Query Context7 for: - Schema.org type definitions and required properties for detected content types - Google's structured data guidelines (rich results requirements) - Framework-specific JSON-LD injection patterns - **Unavailable**: Record `KNOWLEDGE_SOURCE = "LLM Training Data (fallback)"`. Tell user: > "Context7 not available. Using training-data Schema.org knowledge. Install: `claude mcp add context7 -- npx -y @upstash/context7-mcp`" ### Step 2: Target Detection 1. If user provided a path: use it directly. 2. Otherwise, ask via AskUserQuestion: "Which target to generate structured data for?" - Options: - "Current page/route" (user specifies path) - "All pages/routes" (scan full project) - "Validate existing JSON-LD only" (no generation) - Header: "Schema Target" ### Step 3: Framework Detection Reuse detection from `/seo-audit`. Record framework + version. All output must be framework-idiomatic. ### Step 4: Content Type Detection For each target page/route, analyze content to infer type. Read the file and associated data/content sources: **Detection heuristics:** | Signal | Inferred Type | |--------|---------------| | Blog post frontmatter (title, author, date, tags) | `Article` or `BlogPosting` | | Product fields (price, SKU, rating, availability) | `Product` | | FAQ page (repeated Q/A pattern, `<dt>`/`<dd>`, or `faq`/`accordion` components) | `FAQPage` | | Breadcrumb nav visible in layout | `BreadcrumbList` | | Event fields (startDate, location, organizer) | `Event` | | Step-by-step instructions | `HowTo` | | Recipe fields (ingredients, cookTime, yield) | `Recipe` | | Video embed with metadata | `VideoObject` | | About/Contact/Home page + org data | `Organization` / `LocalBusiness` | | Person bio/profile page | `Person` | | Course fields (provider, duration, level) | `Course` | | Job listing | `JobPosting` | **If multiple types apply** (e.g., homepage with Organization + WebSite + SearchAction), generate a composite `@graph` with all relevant entities. **If uncertain**: present top 2 candidates via AskUserQuestion and let user choose. ### Step 5: Validation Mode (Existing JSON-LD) If target contains existing `<script type="application/ld+json">`: 1. Parse the JSON. Flag parse errors. 2. Validate: - `@context` is `"https://schema.org"` (not `http://`, not missing) - `@type` exists and is a valid Schema.org type - All required properties present for the type (e.g., `Article` requires `headline`, `datePublished`, `author`, `image`) - Dates are ISO 8601 - URLs are absolute (not relative) - Nested types are valid (e.g., `author` should be `Person` or `Organization`, not a string alone) - No deprecated properties (cross-check Context7) 3. Report each issue with severity (error | warning | info) and remediation. 4. Offer to fix validation errors with user confirmation. ### Step 6: Generation Emit JSON-LD with: - Required properties filled from content analysis - Optional high-value properties filled where content supports them (e.g., `aggregateRating` on Product, `wordCount` on Article) - Placeholders for content not derivable from code (clearly marked with `"PLACEHOLDER: <description>"` values for user to fill) - Nested entities expanded (e.g., `Article.author` as a `Person` object, `Article.publisher` as `Organization` with `logo`) **Show the user:** 1. Generated JSON-LD block 2. Framework-idiomatic injection code 3. List of PLACEHOLDER values to fill Ask for confirmation before writing. ### Step 7: Framework-Idiomatic Injection **Next.js (App Router):** ```tsx // app/blog/[slug]/page.tsx export default async function BlogPost({ params }: { params: { slug: string } }) { const post = await getPost(params.slug) const jsonLd = { '@context': 'https://schema.org', '@type': 'BlogPosting', headline: post.title, datePublished: post.publishedAt, dateModified: post.updatedAt, author: { '@type': 'Person', name: post.author.name, url: post.author.url }, image: post.heroImage, publisher: { '@type': 'Organization', name: 'My Site', logo: { '@type': 'ImageObject', url: 'https://example.com/logo.png' }, }, } return ( <> <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} /> <article>{/* ... */}</article> </> ) } ``` **Nuxt:** ```vue <script setup lang="ts"> useHead({ script: [ { type: 'application/ld+json', innerHTML: JSON.stringify({ '@context': 'https://schema.org', '@type': 'BlogPosting', headline: post.title, datePublished: post.publishedAt, author: { '@type': 'Person', name: post.author.name }, }), }, ], }) </script> ``` **TanStack Start:** ```tsx // src/routes/blog/$slug.tsx import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/blog/$slug')({ loader: ({ params }) => getPost(params.slug), head: ({ loaderData }) => ({ scripts: [ { type: 'application/ld+json', children: JSON.stringify({ '@context': 'https://schema.org', '@type': 'BlogPosting', headline: loaderData.title, datePublished: loaderData.publishedAt, author: { '@type': 'Person', name: loaderData.author.name }, }), }, ], }), component: BlogPost, }) ``` **Astro:** ```astro --- const post = Astro.props.post const jsonLd = { '@context': 'https://schema.org', '@type': 'BlogPosting', headline: post.title, datePublished: post.publishedAt, author: { '@type': 'Person', name: post.author.name }, } --- <script type="application/ld+json" set:html={JSON.stringify(jsonLd)}></script> <article><slot /></article> ``` **SvelteKit:** ```svelte <script lang="ts"> export let post $: jsonLd = { '@context': 'https://schema.org', '@type': 'BlogPosting', headline: post.title, datePublished: post.publishedAt, author: { '@type': 'Person', name: post.author.name }, } </script> <svelte:head> {@html `<script type="application/ld+json">${JSON.stringify(jsonLd)}</script>`} </svelte:head> ``` **Remix:** ```tsx // app/routes/blog.$slug.tsx import { json } from '@remix-run/node' import { useLoaderData } from '@remix-run/react' export async function loader({ params }) { const post = await getPost(params.slug) return json({ post }) } export default function BlogPost() { const { post } = useLoaderData<typeof loader>() const jsonLd = { '@context': 'https://schema.org', '@type': 'BlogPosting', headline: post.title, datePublished: post.publishedAt, author: { '@type': 'Person', name: post.author.name }, } return ( <> <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} /> <article>{/* ... */}</article> </> ) } ``` **Vanilla HTML:** ```html <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BlogPosting", "headline": "...", "datePublished": "2026-04-17T10:00:00-05:00", "author": { "@type": "Person", "name": "..." } } </script> ``` ### Step 8: Nested Schema Patterns Common composite structures: **Article with Author + Publisher:** ```json { "@context": "https://schema.org", "@type": "Article", "headline": "...", "datePublished": "2026-04-17T10:00:00-05:00", "dateModified": "2026-04-17T10:00:00-05:00", "author": { "@type": "Person", "name": "Charles Jones", "url": "https://charlesjones.dev" }, "publisher": { "@type": "Organization", "name": "My Site", "logo": { "@type": "ImageObject", "url": "https://example.com/logo.png", "width": 600, "height": 60 } }, "image": "https://example.com/hero.jpg", "mainEntityOfPage": { "@type": "WebPage", "@id": "https://example.com/post-slug" } } ``` **Product with Offer + AggregateRating:** ```json { "@context": "https://schema.org", "@type": "Product", "name": "...", "image": ["..."], "description": "...", "sku": "...", "brand": { "@type": "Brand", "name": "..." }, "offers": { "@type": "Offer", "url": "https://example.com/product", "priceCurrency": "USD", "price": "29.99", "availability": "https://schema.org/InStock", "itemCondition": "https://schema.org/NewCondition" }, "aggregateRating": {
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen