Anatomy of a Content Collection
A walkthrough of how Astro content collections, MDX components, and JSON-LD builders compose into the cycle-3 SEO/AEO content system at amysoft.tech.
Astro content collections combine Zod-validated frontmatter, MDX component injection, and JSON-LD builder functions into a single authoring pipeline — structured enough for search engines, flexible enough for real prose.
What is a content collection and why does it matter for SEO?
What is an Astro content collection and why does it matter for SEO?
A content collection is a folder of Markdown or MDX files governed by a Zod schema. Every field in the frontmatter is validated at build time, so malformed dates, missing headlines, and broken image URLs become build errors rather than silent runtime gaps. For SEO this means the structured data fed to schemas.article() — headline, author, datePublished — is guaranteed to be present and correctly typed before a single JSON-LD block is emitted to the page.
How do MDX components inject JSON-LD without prop drilling?
Step 1: Initialize accumulators in the route before Content renders
The [...slug].astro route reads entry.data.contentType from frontmatter and creates a matching accumulator (createQAAccumulator, createHowToAccumulator, or createDefinedTermSetAccumulator) stored on Astro.locals. Because locals are set before <Content components={editorialMdxComponents} /> is evaluated, every MDX component that runs during render can push entries into the accumulator via optional chaining — no prop threading required.
Step 2: Emit accumulated JSON-LD nodes after Content finishes
After <Content /> completes, the route evaluates Astro.locals.qaAccumulator?.toQAPage(), .howToAccumulator?.toHowTo(), and .definedTermSetAccumulator?.toDefinedTermSet(). Each returns null when no entries were pushed — a truthy gate prevents emitting empty schema blocks. When entries exist, a <JsonLd> component serializes the node into a <script type="application/ld+json"> tag inside <main>.
The pattern used for these components is an example of
- Accumulator pattern (also: collector pattern, builder accumulation)
- A design where child components push structured data into a shared, per-render store rather than returning values up the tree. The parent collects all entries after rendering completes and emits a single aggregate node — keeping children stateless and avoiding prop drilling.