Building This Blog with mdsvex
I wanted a blog that I could write in plain Markdown, keep under version control, and ship as static HTML — no database, no CMS, no runtime fetching. Here is how this very page is built.
Why mdsvex
mdsvex is a Markdown preprocessor for Svelte. Each .md file becomes a
Svelte component, and its YAML frontmatter is exported as a metadata object. That means I get:
- Posts authored in Markdown, living in
src/posts/ - Typed frontmatter (title, description, date, tags)
- Full prerendering — every post is a static file at build time
The frontmatter
Every post starts with a small block of metadata:
---
title: 'Building This Blog with mdsvex'
description: 'How this site turns Markdown into prerendered posts.'
date: '2026-06-10'
tags: ['SvelteKit', 'mdsvex']
published: true
--- A single helper globs every file and sorts them by date:
const files = import.meta.glob('/src/posts/*.md', { eager: true });
export const posts = Object.entries(files)
.map(([path, mod]) => ({
slug: path.split('/').pop().replace('.md', ''),
meta: mod.metadata,
Component: mod.default
}))
.sort((a, b) => +new Date(b.meta.date) - +new Date(a.meta.date)); The whole index is derived from the filesystem. To publish, I drop a new
.mdfile insrc/posts/— the listing, the route, and the sitemap all pick it up automatically.
What you get for free
Because each post is a real Svelte component, styling is just Tailwind’s prose class, and the
content is indexed by search engines as static HTML. No client-side hydration is needed to read it.
That is the entire setup. Simple, fast, and easy to maintain.