Make a collection
Logs need structure. Type them up properly.
One log file works. Six log files? You'd hand-import each one. That's silly.
Content collections turn a folder into a queryable thing. You declare a schema with zod — and every .md in the folder is validated against it at build time.
Typos in your frontmatter? Build error. Missing a field? Build error. The schema is your safety net.
import { defineCollection, z } from "astro:content";
import { glob } from "astro/loaders";
const logs = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/logs" }),
schema: z.object({
title: z.string(),
date: z.date(),
author: z.string(),
hype: z.number().default(0),
}),
});
export const collections = { logs }; Now your page can pull all logs with one call:
---
import { getCollection } from "astro:content";
import Layout from "~/layouts/Layout.astro";
const logs = (await getCollection("logs"))
.sort((a, b) => +b.data.date - +a.data.date);
---
<Layout title="Mission Log">
<h1>Mission Log</h1>
<ul>
{logs.map((log) => (}
<li>
<ahref={log.id}>{log.data.title}</a>
</li>
{))}
</ul>
</Layout> log.data is your typed frontmatter — autocomplete works. log.id is the URL-friendly slug. Add a [...slug].astro dynamic route to render each one, and you have a real blog.