agentleFS
ZmokiZmoki/zmoki-astro-starter/.claude/skills/structured-data/SKILL.md

structured-data

Skill4 starsChanged 17 days agoMITView on GitHub

Add or edit structured data (schema.org / JSON-LD) so pages qualify for Google rich results. Use when the user wants rich results, rich snippets, a knowledge-panel, breadcrumbs, article/blog markup, an Organization or Profile card, FAQ/Q&A, or any schema.org markup for SEO.

8 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use core-web-vitals.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • vijpatel7Skill

    core-web-vitals

    Optimize Core Web Vitals (LCP, INP, CLS) for better page experience and search ranking. Use when asked to "improve Core Web Vitals", "fix LCP", "reduce CLS", "optimize INP", "page experience optimization", or "fix layout shifts".

    Also in 3 projects that use this

The file

We split this skill into the rules it gives an agent

6 rules. 0 are common, 6 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 7 edited versions we read keep these.

  • 6

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Add and maintain schema.org JSON-LD so pages are eligible for Google rich results.

    line 7
  2. Distinctive:

    Before implementing a type, fetch its gallery page and read two things.

    line 12
  3. Distinctive:

    Nothing misleading: No fabricated reviews or ratings, no impersonation, nothing off-topic.

    line 23
  4. Distinctive:

    Complete: Every required property, plus each recommended one you can honestly fill.

    line 24
  5. Distinctive:

    If the user asks for a type not in the gallery, tell them it won't produce a Search feature, even if schema.org defines it.

    line 33
  6. Distinctive:

    Check that every marked-up fact is visible on the page.

    line 53

“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Structured data

Add and maintain schema.org JSON-LD so pages are eligible for Google rich results. Follow Google's documentation only:

Before implementing a type, fetch its gallery page and read two things. Don't work from memory; both change.

  1. Eligibility. Confirm this site and page qualify before writing markup. Many features are limited by region, language or device. FAQPage and QAPage rich results are limited to authoritative government and health sites, so this site won't get them.
  2. Required and recommended properties, with their exact names and shapes.

Google's rules

Break these and Google can ignore the markup or issue a manual action:

  • JSON-LD only. The whole site uses <script type="application/ld+json">; there's no Microdata or RDFa.
  • Match visible content. Mark up only what a visitor can see on the page.
  • Nothing misleading. No fabricated reviews or ratings, no impersonation, nothing off-topic.
  • Complete. Every required property, plus each recommended one you can honestly fill.
  • On the page it describes. Site-wide entities like Organization are the exception. Duplicate pages carry identical markup.
  • Most specific type (BlogPosting over Article).
  • Crawlable. Pages and images in the markup must not be blocked. /-/astro/* and /thank-you/* are noindex (src/headers/headers.config.ts), so don't add rich-result markup there.

What the site emits

src/STRUCTURED-DATA.md lists every type, the pages that carry it, and what is left out on purpose. Read it first; update it in the same commit as any change. Still to add: VideoObject for embedded videos.

If the user asks for a type not in the gallery, tell them it won't produce a Search feature, even if schema.org defines it.

How to add it

Builder. Add one function per type to src/lib/structured-data.ts, next to blogPosting, imageObject, breadcrumbList and siteIdentity. It takes only facts the page shows and returns the schema object; the page passes it to src/components/JsonLd.astro, which takes one object or an array, escapes <, and works anywhere in the document. JSON-LD is data, so the CSP doesn't affect it.

Values. Take text from src/site.config.ts (site.name, site.organization.*, …); never hard-code it. Pass titles and descriptions through htmlToText (src/lib/html-text.ts): pages render them as HTML. Reference the site owner through the builders' owner(), which carries its @id. People come from src/content/people.yaml through personToProps(); a Person's url is their profile page when they have one, else their own site.

URLs. The caller builds absolute URLs with absoluteUrl(path) from siteUrls(Astro) (src/lib/urls.ts), the same helper behind the canonical link and og:image, and passes them in. For a page's OG card, use getOgImage(pathname) (src/og/manifest.ts). For a content image, use publishedImageUrl(src) (src/lib/images.ts), never the origin URL. Dates are ISO 8601 (.toISOString()).

Breadcrumbs. Don't build BreadcrumbList by hand: <Breadcrumbs crumbs={[{ name: "Home", href: "/" }, …, { name: title }]} /> renders the visible trail and its markup from one array. Every crumb but the last needs an href (the build fails otherwise); the last is the current page. Shared crumbs (homeCrumb, blogCrumb) live in src/lib/crumbs.ts. On a noindex page, pass schema={false}.

PostLayout.astro is the worked example: blogPosting({...}) plus <Breadcrumbs>.

Verify (required)

  1. Build, then serve or deploy.
  2. npm run check:sd (scripts/check-structured-data.ts, also in CI) parses every JSON-LD block in dist/ and fails on invalid JSON, missing @context/@type, or leftover ${…}/undefined. It doesn't judge eligibility.
  3. Rich Results Test: https://search.google.com/test/rich-results. Enter the URL or paste the rendered HTML. The intended type must be detected with no errors; fix every warning you can. It's manual; there's no CI API.
  4. On the live site, URL Inspection in Google Search Console confirms Google can crawl and parse it.
  5. Check that every marked-up fact is visible on the page.

Report the types and pages you changed and the Rich Results Test outcome. Don't claim eligibility the test didn't confirm.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.