Adding content
Write a blog post, a project case study, or a docs page — the per-locale folder layout, frontmatter schemas, and the parallel-route rule.
Content lives in typed content collections under src/content/. Each
collection has a Zod schema in src/content.config.ts, so a missing or malformed
field is a build error, not a broken page. Two rules hold everywhere:
- Per-locale folders. Every collection nests by locale:
src/content/<collection>/<locale>/<slug>. The default locale isen. - Add files, not routes. The catch-all routes enumerate the collection and emit one page per entry. You never register a route by hand.
Blog post
The blog collection loads */*.mdx — i.e. <locale>/<slug>.mdx.
- Create the file
src/content/blog/en/my-first-post.mdx - Fill the frontmatter
The schema requires
title(≤70),description(70–160),datePublished, and anauthorreference; the rest are optional:--- title: Shipping faster with astro-ignite description: How an opinionated, fully-owned starter cut our time-to-first-deploy from an afternoon to a coffee break. datePublished: 2026-06-09 author: jordi tags: [astro, dx] ogImage: ./_assets/og-shipping.png --- Your MDX body here. Plain Markdown is styled by the layout's prose utility; import any component (e.g. from src/components/ui/) to go beyond it.Note:
ogImageis the post’s social preview image — post cards and detail pages render a token-resolved gradient cover, not a hero image. Omit it and OG falls back to the site-wide default banner. - See it
pnpm dev→ the post is live at/blog/my-first-post, listed on/blog, and folded into pagination, tags, and related-posts automatically.
Project case study
The projects collection loads */*/index.mdx — each project is a folder
(<locale>/<slug>/index.mdx) so it can carry its own assets. It adds summary,
techStack, links (live / repo / demo / caseStudy), and a status
(shipped | in-progress | archived):
---
title: Acme redesign
description: A ground-up rebuild of Acme's marketing site on Astro, shipping Lighthouse 100s and a 60% faster LCP.
summary: Full redesign and rebuild, from Figma to production in six weeks.
datePublished: 2026-05-01
techStack: [Astro, TypeScript, Tailwind]
links:
live: https://acme.example.com
status: shipped
---
Lives at /projects/acme-redesign.
Docs page
In the docs template, the docs collection loads <locale>/<slug>.mdx.
Frontmatter is title + description (40–160), with optional tags,
lastUpdated, and draft:
---
title: Configuration
description: Every setting in site.ts and what it controls, with sensible defaults for a first deploy.
tags: [reference]
---
## Section
Sidebar, breadcrumbs, on-this-page, and prev/next all derive from the
collection — add this file and it slots into the nav.
Reshape the sidebar order/grouping in src/config/sidebar.ts.
The parallel-route rule
This is where content and custom pages differ:
- Collection content (blog, projects, docs) is served by catch-all routes
(
[...slug].astrofor the default locale,[lang]/[...slug].astrofor the rest). They already handle every locale — so a localized post is just a second file under the target locale folder. Nothing else to wire. - Hand-written
.astropages (e.g.src/pages/about.astro) must ship a parallel atsrc/pages/[lang]/about.astrowhosegetStaticPathsemits one entry per non-default locale. A page at/foowith no/[lang]/foois an i18n gap the invariant audit will flag.
Drafts
Every content schema ships a draft: boolean (default false). Set
draft: true to keep an entry out of listings, the sitemap, and the build’s
published set while you work on it.