Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/syhily/yufan.me/llms.txt

Use this file to discover all available pages before exploring further.

Static pages give you a way to publish standalone content — an About page, a Contact page, a colophon — outside the post stream. Pages render at /:slug and share the global slug namespace with posts: a slug used by a page cannot be reused by a post, and vice versa. Collisions are prevented at two levels — a database UNIQUE(slug) constraint on the page table and a cross-table fence (validateSlugFence) that checks the posts table before any slug is accepted.

Creating a page

1

Open the page list

Navigate to Admin → Pages in the sidebar. Click New Page in the top-right corner.
2

Enter a title

Type a title. The slug field is filled in automatically from the title using the deriveSlug pipeline (see slug rules below). You can override the slug at this step.
3

Optionally set a custom slug

Page slugs allow . and - and _ as separators, so you can enter legacy-style URLs like archives.html or about_us to preserve backward-compatible links. The auto-derived value is always plain kebab-case ASCII.
4

Write the body

Use the Tiptap editor to write the page body. The editor is identical to the one used for posts — see Using the Tiptap content editor for the full block reference.
5

Configure optional fields

Fill in the summary, cover image, and any display toggles (table of contents, updated date, show friends list, comments).
6

Publish or save as draft

Toggle Published on and click Save to publish the page. Leave the toggle off to save it as a draft.

Draft overlay

When you are logged in as an admin and visit a page that has published=false, the public-facing view shows an admin-only draft preview overlay. This lets you review the rendered layout before publishing without exposing the content to public visitors.

Slug rules

Page slugs follow a slightly more permissive pattern than post slugs:
RulePagesPosts
Allowed separators. _ -- only
CJK → pinyin auto-deriveYesYes
Max length80 characters80 characters
Must be lowercase ASCIIYesYes
Shared namespace with postsYesYes
The permissive separator set exists so that legacy URLs like archives.html survive a migration without needing a redirect rule. When the slug is auto-derived from the title, only - is emitted; the extra characters are available only when you supply a slug manually.

Page fields

FieldDescription
TitleDisplay title (max 200 characters). Required.
SlugURL identifier for the page. Auto-derived from the title; editable. Must be unique across all pages and posts.
SummaryShort excerpt (max 500 characters) for meta description and listings.
Cover imageImage from the library used as the page thumbnail and OG image.
BodyFull page content authored in the Tiptap editor and stored as PortableText JSON.
PublishedWhen true and a published revision exists, the page is visible to the public.
Publish dateOptional future date; the page stays hidden until the time arrives.
Show ToCRenders a table of contents sidebar from heading anchors.
Show updated dateDisplays the last-updated timestamp on the page.
Show friendsRenders the friends/links list at the bottom of the page.
Comments enabledAllows readers to post comments on this page.
OG imageCustom Open Graph image URL. Falls back to the cover image when empty.

Body format

Pages use exactly the same Tiptap editor and PortableText wire format as posts. All block types — headings, code blocks, math, Mermaid diagrams, images, music players, tables, solution blocks, and footnotes — are available. See Using the Tiptap content editor for the full reference.
Both the page table’s database UNIQUE(slug) constraint and the cross-table fence (validateSlugFence in src/server/domains/pages/fence.ts) prevent slug collisions between pages and posts. If you try to save a page with a slug already in use by a post, the API returns a validation error before any write is committed.

Build docs developers (and LLMs) love