Skip to content
← back to all posts
14 August 20266 min read

Why Nuxt Content for a personal site

Markdown in a Git repo, typed frontmatter, and a static build that deploys to Cloudflare Pages for free. Here is the setup I actually use.

#nuxt#content#cloudflare

When I rebuilt my personal site I had three requirements:

  1. Writing should feel like writing, not like configuring a CMS.
  2. The output should be static — fast, cheap, and boring to maintain.
  3. Types everywhere, because I am that kind of person.

Nuxt Content hit all three.

Markdown lives in the repo

Every post is just a file:

---
title: Why Nuxt Content for a personal site
description: Markdown in a Git repo, typed frontmatter...
date: 2026-08-14
tags: [nuxt, content, cloudflare]
---

Content goes here.

Commit a file, and it is content. No database, no admin panel, no login to forget.

Typed frontmatter with Zod

The part I love most is the schema. In content.config.ts I describe exactly what a post looks like:

import { defineContentConfig, defineCollection, z } from '@nuxt/content'

export default defineContentConfig({
  collections: {
    blog: defineCollection({
      type: 'page',
      source: 'blog/**/*.md',
      schema: z.object({
        title: z.string(),
        description: z.string(),
        date: z.date(),
        tags: z.array(z.string()).default([]),
        draft: z.boolean().default(false)
      })
    })
  }
})

Now a typo in a date fails the build instead of shipping silently. That is the deal I want.

Querying is a one-liner

Listing posts, newest first, draft-free:

const { data: posts } = await useAsyncData('blog-list', () =>
  queryCollection('blog')
    .where('draft', '=', false)
    .order('date', 'DESC')
    .all()
)

And rendering a post:

<ContentRenderer :value="post" class="prose" />

That is the whole blog.

Static on Cloudflare Pages

Because everything is generated at build time, I do not need a server. The build command is literally:

npm run generate

The output lands in .output/public, and Cloudflare Pages serves it from the edge. Free tier, instant cache invalidation on deploy, done.

A personal site should cost you a coffee, not a subscription.

If you are on the fence: pick the boring static option. Your future self, half-asleep at 2am debugging a cache, will thank you.


Enjoyed it? There is more where that came from.

Read more →