How to Build an Astro Blog by Hand
DIY Astro fun
03/31/2025
read timeļ¼2 mins
First the easy way
The easy way to build an Astro blog with markdown content is to use the Astro CLI. It will create a new Astro project for you with all the dependencies and everything you need.
yarn create astro
The hard way
The hard-ish way to build an Astro blog is to build it by hand. This is a good way to learn Astro and how it works.
Steps:
- put your .md files in
/src/content/posts
- create a
src/content/config.ts
like this:
import { defineCollection, z } from 'astro:content';
const posts = defineCollection({
schema: z.object({
title: z.string(),
pubDate: z.date(),
description: z.string(),
// add more fields if needed
}),
});
export const collections = {
posts,
};
- create your posts page at
src/pages/posts/[slug].astro
like this:
---
import { getCollection, getEntryBySlug } from 'astro:content';
import Layout from '../../layouts/Layout.astro'; // or whatever your layout file is
const { slug } = Astro.params;
const post = await getEntryBySlug('posts', slug);
if (!post) {
throw new Error(`Post not found for slug: ${slug}`);
}
---
<Layout title={post.data.title}>
<article>
<h1>{post.data.title}</h1>
<p><time datetime={post.data.pubDate.toISOString()}>{post.data.pubDate.toDateString()}</time></p>
<p>{post.data.description}</p>
<div class="content">
<post.Content />
</div>
</article>
</Layout>
- create your index page at
src/pages/blog.astro
like this:
---
import { getCollection } from 'astro:content';
const posts = await getCollection('posts');
---
<h1>Blog</h1>
<ul>
{posts.map(post => (
<li>
<a href={`/posts/${post.slug}`}>{post.data.title}</a>
</li>
))}
</ul>