Content Model

In Dune, content is files. There is no database. Pages live on the filesystem — as named folders or as plain files in a directory.

content/
├── 01.home/
│   └── default.md          ← numeric page folder
├── 02.blog/
│   ├── blog.md             ← listing page for /blog
│   └── 01.hello-world/
│       ├── post.md         ← child page
│       └── cover.jpg       ← co-located media
├── 03.landing/
│   └── page.tsx            ← TSX content page
├── blog/
│   └── my-post/
│       ├── post.md         ← named page folder → /blog/my-post
│       └── cover.jpg       ← co-located media
└── articles/
    ├── default.md          ← /articles listing page
    ├── my-first-post.md    ← flat file → /articles/my-first-post
    └── deep-dive.md        ← flat file → /articles/deep-dive

Content layouts

Numeric page folders

A folder with a numeric prefix (01., 02., …) is always a page folder. The file inside selects the theme template — post.md renders with post.tsx, default.md uses default.tsx. Co-located media lives in the same folder as the content file.

02.blog/01.hello-world/post.md   →  /blog/hello-world
03.landing/page.tsx              →  /landing

Named page folders

A plain folder (no numeric prefix) whose content file stem matches a theme template name is also treated as a page folder. The folder's path becomes the route; the filename selects the template.

blog/my-post/post.md     →  /blog/my-post   ("post" matches templates/post.tsx)
news/launch/article.md   →  /news/launch    ("article" matches templates/article.tsx)

This mirrors the Grav convention: you can give any folder a human-readable name and put the template-named content file inside. Co-located media works the same way as with numeric folders.

Flat content files

When a file's stem does not match any theme template name — and is not a reserved stem (default, index) — it becomes its own page, routed by filename:

articles/my-first-post.md    →  /articles/my-first-post
articles/deep-dive.md        →  /articles/deep-dive
articles/default.md          →  /articles  (reserved stem — listing page)

Flat files work well for articles, changelog entries, or any content that doesn't need co-located media or nested sub-pages. Add a default.md alongside them to create a listing page at the directory's own route.

How Dune decides

File path Condition Route
01.blog/01.post/post.md numeric parent folder /blog/post
blog/my-post/post.md stem matches template /blog/my-post
articles/first.md stem has no matching template /articles/first
articles/default.md reserved stem /articles

Core ideas

Frontmatter = metadata. The YAML block at the top of each file controls title, date, taxonomies, collections, visibility, caching, and more.

Filename = template (page folders). post.md renders with the post.tsx theme template. default.md uses default.tsx. The filename both selects the template and — in plain folders — determines whether the folder is treated as a page folder or a flat archive.

Formats are interchangeable. Markdown for prose. TSX for interactive pages. They share the same folder conventions, frontmatter fields, collection system, and taxonomy system.

Content formats at a glance

Format Frontmatter Body Rendering Best for
.md YAML between --- Markdown → HTML Injected into theme template Blog posts, docs, articles
.tsx export const frontmatter = {} or sidecar YAML JSX component Self-rendering, optional layout Landing pages, interactive content
.mdx YAML between --- Markdown + JSX Compiled, injected into template Tutorials with live examples (v0.2)

Read on for details on each format, frontmatter fields, media handling, collections, and taxonomies.