src/data/collections/posts/posts.json. The file is a keyed object where each top-level key is the post’s slug, and each value is a fully typed post record validated by a Zod schema at build time. Adding a new post is as simple as appending a new key-value pair to that object and running a rebuild.
File Location
Data Structure
The top-level object is a map ofslug → post. This makes look-ups O(1) and keeps the dynamic route /blog/[slug] simple — the renderer reads the key that matches the URL parameter.
Required Fields
Every post record must include all of the following fields. The Zod schema will reject the build if any required field is missing or has the wrong type.Optional Fields
The body Field
The body field accepts GitHub-flavored Markdown rendered via remark-gfm. You can use all standard GFM features inside it:
- Headings (
##,###) - Fenced code blocks with language tags
- Tables
- Task lists
- Bold, italic, inline code, and blockquotes
\n for newlines and \n\n for paragraph breaks.
The image Object
When provided, the cover image object requires two sub-fields:
How Posts Are Displayed
Posts surface in two places in the default layout:Blog list page — /blog
The
posts-list section on src/data/pages/blog.json renders every post in reverse-chronological order. Tags are shown as clickable filter chips.Home page — recent posts
The
recent-posts section on src/data/pages/home.json shows the most recent N posts. Control the count with the limit field in that section’s data object.src/data/pages/home.json and update the limit value in the recent-posts section:
Dynamic Route
Every post is accessible at/blog/[slug], where [slug] is the top-level key in posts.json. The template file at src/data/pages/blog/[slug].json configures the post-detail section that renders the full article body.
The slug key and the
id field must always match. Mismatched values will cause the detail page to fail its schema validation at build time.Adding a New Post
1
Open posts.json
Open
src/data/collections/posts/posts.json in your editor.2
Append a new entry
Copy an existing post object, paste it as a new key-value pair at the end of the top-level object, and update every field. Choose a slug that is URL-safe: lowercase letters, numbers, and hyphens only.
3
Rebuild the site
Removing a Post
Delete the entire key-value pair fromposts.json, then rebuild. The post will no longer appear in listings or be accessible at its /blog/[slug] URL.