astro-structured-datav2.0.1

CASOON Open Source

JSON-LD for Astro, typed and validated.

astro-structured-data renders schema.org JSON-LD from Astro components. Props are checked against Zod schemas at build time: invalid data stops the build instead of reaching Google.

npm install @casoon/astro-structured-data
pnpm add @casoon/astro-structured-data
yarn add @casoon/astro-structured-data
MITnpm 2.0.1Astro 5 · 6 · 7Node ≥ 18
examples/blog-post.astro → JSON-LD
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Structured data for Astro sites",
  "description": "How JSON-LD is generated from typed, validated component props.",
  "datePublished": "2026-09-10",
  "dateModified": "2026-09-12",
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://example.com/"
  },
  "author": {
    "@type": "Person",
    "name": "Jane Doe"
  },
  "isAccessibleForFree": true,
  "publisher": {
    "@type": "Organization",
    "name": "Example Blog",
    "logo": {
      "@type": "ImageObject",
      "url": "/logo.png"
    }
  },
  "image": {
    "@type": "ImageObject",
    "url": "/images/structured-data.jpg"
  },
  "inLanguage": "en",
  "keywords": "astro, json-ld, seo",
  "timeRequired": "PT4M"
}
Astro components, one per schema type plus generic and graph
18
Zod schemas exported for content collections and forms
16
tests, including real static, dev and SSR builds
232
client JavaScript added to your pages
0 kB

What it does

  1. Validated at build time

    Every component parses its props with its Zod schema: ISO 8601 dates, ISO 4217 currencies, absolute or root-relative URLs, cross-field rules. Unknown props are errors, so typos cannot drop data silently.

  2. No invented values

    Components never fill in placeholders. A name, a hiring organisation or a salary unit comes from a prop or a configured default, otherwise the build fails.

  3. Meta tags from the same data

    With generateMeta, a middleware derives canonical, Open Graph and Twitter tags from the primary schema of the page. Tags your layout already sets are kept.

  4. One @graph per page

    With useGraph, all schemas of a page are merged into a single @graph block, wherever the components sit and even when they await data.

Rejected at build time

All examples →
[astro-structured-data] <EventSchema> on /events/meetup/ received invalid props:
✖ Invalid input
  → at startDate
✖ Must be an ISO 4217 currency code like "EUR"
  → at priceCurrency

Real output: the error the component throws for examples/invalid-event.astro while this site was built.

examples/invalid-event.astro

Quickstart

Register the integration, then place components on your pages. The full walkthrough and every component are in the documentation.

  1. Install the package and add the integration to astro.config.mjs.
  2. Set site in the Astro config, or pass siteUrl to the integration.
  3. Import components from @casoon/astro-structured-data/components and pass your data as props.
astro.config.mjsConfig
import { defineConfig } from 'astro/config';
import structuredData from '@casoon/astro-structured-data';

export default defineConfig({
  site: 'https://example.com',
  integrations: [structuredData({ generateMeta: true })],
});