Writing guide

The framework deliberately narrows the writing surface: one markdown file plus at most six frontmatter keys, everything else derived from the directory structure at build time. This page is the daily-writing cheat sheet; syntax details live in Markdown extensions.

A file is a page

Every **/*.md under contentDir is a page, routed as the extensionless <relative path>; index.md is the index page of its directory:

text
content/
├── index.md              # home page /
├── notes/foo.md          # /notes/foo
└── notes/index.md        # /notes/; the directory row links here

The emitted file names never change: /notes/foo is written as notes/foo.html, so any static host serves it directly. Directory index routes end with / by default; switch the form with urls.directoryIndex (see the configuration reference and Deployment).

Directories are categories: the sidebar is generated from directories, a folder row links directly to that directory's index.md, and the row label takes the first h1 of index.md (falling back to the directory name when no index page exists); the index page does not repeat among its own children. So "moving a file" is "moving a page" — navigation, archives, and the related graph all follow automatically. The generated order is alphabetical; adjust it with sidebar.order / sidebar.tweaks (see the configuration reference).

Titles and page names

The page title is the first h1 in the content; sidebar, TOC, archives, the home article feed, and RSS all consume it. A page without an h1 has an empty title and falls back to its file path in navigation. Heading anchors are generated by the same slugify as VuePress 2 (ported from @mdit-vue/shared), character-for-character identical to VuePress (non-ASCII kept as-is, English lowercased, spaces become hyphens). Internal references look like [Configuration reference](./configuration.md#basic-fields).

The six frontmatter keys

Only date / category / tag / icon / feed / overview are recognized; other keys are ignored:

md
---
date: 2026-10-03 # ISO string or yyyy-MM-dd; article feed ordering and RSS pubDate
category:
  - guide # category archive pages (multi-value)
tag:
  - writing
  - markdown # tag archive pages (multi-value)
icon: solid/rocket # a registered icon key (iconProvider or icons)
feed: true # default true; false opts out of RSS (the article feed still includes it)
overview: true # default true; only meaningful on a directory's index.md
---

Dates: write one by hand, git handles the rest

So daily writing only needs one date written at creation; "last edited" is maintained by git with no manual syncing.

Relative links starting with ./ ../ are resolved at build time; a failure is a build error, so broken links cannot be published. Always cross-link articles with relative paths carrying the .md suffix (./related.md, cross-page anchors like ./related.md#section): they are protected by dead link checking and friendly to editors when files move. Resolve order, asset passthrough, and bare-link policy are covered in Markdown extensions.

Images

Relative-path images are copied at build time under content-hash names, with src rewritten per page depth, so deploying under any sub-path keeps them working. An image alone in a paragraph is upgraded to <figure> (alt becomes figcaption), and the ![alt](src =WxH) size syntax is supported; all forms and rules are in Markdown extensions. For screenshots that need click-to-zoom, use the ZoomedImg island — see Islands.

  1. Create xxx.md in the right directory, write the h1 and frontmatter (at least date)
  2. Organize content with the syntax from Markdown extensions; code blocks have line numbers by default and auto-collapse past 15 lines, no need for screenshot-as-code
  3. Cross-link related articles — the build aggregates mutual references into the related-article graph
  4. Verify with pnpm build or the dev server: dead links and icon errors surface at build time