Static pages give you a way to publish standalone content — an About page, a Contact page, a colophon — outside the post stream. Pages render atDocumentation 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.
/: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
Open the page list
Navigate to Admin → Pages in the sidebar. Click New Page in the top-right corner.
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.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.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.
Configure optional fields
Fill in the summary, cover image, and any display toggles (table of contents, updated date, show friends list, comments).
Draft overlay
When you are logged in as an admin and visit a page that haspublished=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:| Rule | Pages | Posts |
|---|---|---|
| Allowed separators | . _ - | - only |
| CJK → pinyin auto-derive | Yes | Yes |
| Max length | 80 characters | 80 characters |
| Must be lowercase ASCII | Yes | Yes |
| Shared namespace with posts | Yes | Yes |
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
| Field | Description |
|---|---|
| Title | Display title (max 200 characters). Required. |
| Slug | URL identifier for the page. Auto-derived from the title; editable. Must be unique across all pages and posts. |
| Summary | Short excerpt (max 500 characters) for meta description and listings. |
| Cover image | Image from the library used as the page thumbnail and OG image. |
| Body | Full page content authored in the Tiptap editor and stored as PortableText JSON. |
| Published | When true and a published revision exists, the page is visible to the public. |
| Publish date | Optional future date; the page stays hidden until the time arrives. |
| Show ToC | Renders a table of contents sidebar from heading anchors. |
| Show updated date | Displays the last-updated timestamp on the page. |
| Show friends | Renders the friends/links list at the bottom of the page. |
| Comments enabled | Allows readers to post comments on this page. |
| OG image | Custom 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.