Building a Personal Blog with Astro: A Complete Guide
Learn how to create a modern, fast, and SEO-friendly personal blog using Astro, featuring Markdown support, dark mode, and internationalization.
Why Astro?
Astro is a modern static site generator that offers the best of both worlds: the developer experience of component-based frameworks and the performance of static HTML.
TIP
Astro ships zero JavaScript by default, making your site blazing fast!
Key Features
- Zero JS by default - Only ship JavaScript when you need it
- Component Islands - Use React, Vue, Svelte, or any framework
- Content Collections - Type-safe content management
- Built-in optimizations - Images, CSS, and more
Getting Started
Prerequisites
- Node.js 18+ or Bun
- A code editor (VS Code recommended)
Create a New Project
# Using npm
npm create astro@latest my-blog
# Using bun (recommended)
bun create astro my-blog
Project Structure
my-blog/
├── src/
│ ├── content/
│ │ └── blog/ # Your blog posts
│ ├── components/ # UI components
│ ├── layouts/ # Page layouts
│ └── pages/ # Routes
├── public/ # Static assets
└── astro.config.mjs # Configuration
Content Collections
Astro 5 introduced a powerful content layer API for managing your blog posts.
Define Your Schema
// src/content.config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
image: z.string().optional(),
tags: z.array(z.string()).default([]),
featured: z.boolean().default(false),
}),
});
export const collections = { blog };
Query Your Content
import { getCollection } from 'astro:content';
const posts = await getCollection('blog');
const featuredPosts = posts.filter(post => post.data.featured);
Adding Markdown Support
Astro has built-in Markdown support with powerful remark/rehype plugin ecosystem.
Key Plugins
remark-math+rehype-katex- Math equationsrehype-slug- Heading anchorsrehype-autolink-headings- Clickable headings
Dark Mode with Tailwind
Implementing dark mode is straightforward with Tailwind CSS.
Setup
// tailwind.config.mjs
export default {
darkMode: 'class',
// ...
};
Theme Toggle Component
function ThemeToggle() {
const toggleTheme = () => {
document.documentElement.classList.toggle('dark');
};
return <button onClick={toggleTheme}>Toggle Theme</button>;
}
Internationalization (i18n)
Support multiple languages using Astro’s built-in i18n features.
Configuration
// astro.config.mjs
export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: ['en', 'zh'],
routing: {
prefixDefaultLocale: true,
},
},
});
Performance Optimization
WARNING
Always test your site’s performance before and after optimization!
Image Optimization
---
import { Image } from 'astro:assets';
import myImage from '../assets/hero.jpg';
---
<Image src={myImage} alt='Hero image' />
Code Splitting
Use dynamic imports for heavy components:
const HeavyComponent = await import('./HeavyComponent');
Deployment
Astro sites can be deployed anywhere that supports static hosting.
Popular Options
| Platform | Pros | Cons |
|---|---|---|
| Vercel | Easy setup, Edge functions | Vendor lock-in |
| Netlify | Great DX, Forms | Build time limits |
| Cloudflare Pages | Fast, Free | Limited build options |
| GitHub Pages | Free, Simple | Manual setup |
Conclusion
Astro is an excellent choice for building personal blogs. Its focus on performance, combined with flexibility in choosing your preferred UI framework, makes it a powerful tool for developers.
Next steps:
- Explore Astro’s official documentation
- Join the Astro Discord community
- Start building your own blog!
Happy coding! 🚀