한국어
Youngkwang Yang

A personal tech blog

Contents

From Markdown to typed pages: the build pipeline

Astro

A content-driven site is really a small compiler. Text files go in, HTML comes out, and a schema in the middle keeps the two honest. Here is the shape of it.

noyesMarkdown / MDXschema valid?build failstyped entriesstatic HTML

The diagram above is written in Mermaid — just a fenced ```mermaid block — and rendered to a plain SVG at build time, so the page ships no diagramming JavaScript and still works offline.

The schema is the contract

Every post is validated against a schema before it becomes a page. Get a field wrong and the build stops — you never ship a half-broken post.

// src/content.config.ts
const posts = defineCollection({
  loader: glob({ pattern: '**/index.{md,mdx}', base: './src/content/posts' }),
  schema: z.object({
    title: z.string(),
    pubDate: z.coerce.date(),
    category: z.string(),
  }),
});

Rendering is boring, on purpose

Once entries are typed, turning them into pages is mechanical. No surprises at runtime because there is no runtime — it already ran, at build.

---
const posts = await getCollection('posts');
---
{posts.map((p) => <a href={`/posts/${p.id}`}>{p.data.title}</a>)}

The payoff: a broken link or a missing date is a build error on my machine, not a bug a reader finds later.