Part three. Let’s talk about how this post got to your screen, because it’s the most database-shaped thing in frontend land.
Each post on this blog is a markdown file with a frontmatter header — title, description, publish date. Classic static-site stuff, Jekyll did it in 2010. What Astro adds is the part that made me grin: a schema.
const blog = defineCollection({
loader: glob({ pattern: '**/*.md', base: './src/content/blog' }),
schema: z.object({
title: z.string(),
description: z.string().optional(),
pubDate: z.coerce.date(),
heroImage: image().optional(),
}),
});
That’s Zod, a validation library — think of it as constraints on a table, or the DTO validation you’d write for an API. If I typo a field or forget a date, the build fails. My blog has referential integrity. I’m not being ironic, this genuinely makes me happy.
Querying it looks like this:
const posts = (await getCollection('blog')).sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
);
Which is just SELECT * FROM blog ORDER BY pub_date DESC wearing a TypeScript costume. The results come out fully typed — post.data.title autocompletes, and if I ever rename a schema field, every page that uses it breaks loudly at build time.
Then one file, src/pages/blog/[slug].astro, tells Astro “generate one HTML page per post”. At build time it materializes the whole blog. There is no blog server. You’re reading a file.
Now, the bug. You knew there’d be a bug.
I wrote pubDate: 2025-03-01 in a post and the page rendered February 28. If you’ve ever worked with timezones you already solved it: a date-only string parses as UTC midnight, and I live in Brazil, UTC-3. Formatting that instant in local time lands on the previous day, 21:00. The fix is telling the formatter to stay in UTC:
new Intl.DateTimeFormat('en-US', { dateStyle: 'long', timeZone: 'UTC' });
Fifteen years of backend work, and the timezone off-by-one still found me in a markdown blog. Some bugs are loyal like that.
Next up: the floating keywords on the homepage, and how CSS became a real animation engine while we backenders weren’t looking.
Happy coding!