astrobench · play with code
Step
3/10

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.

src/content.config.ts — brand new file read-only
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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:

src/pages/logs/index.astro read-only
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
---
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.

— page 3 —
in the binder open binder →
saved a moment ago
progress 30%
earn +90 XP