Publish your first post and light up the RSS feed
Replace the scaffold's placeholder post with a fully-populated BlogSiteFrontMatter block and watch it flow into the blog index, per-tag pages, and the built-in RSS feed.
By the end of this tutorial, a running BlogSite at http://localhost:5000 surfaces a single, fully-populated post on the home page, the archive, the per-tag index, and /rss.xml — the placeholder from the scaffold tutorial swapped for a post of your own. Each BlogSiteFrontMatter field maps to a specific surface; the steps walk through them in turn.
Prerequisites
- .NET 10 SDK installed
- Completed Scaffold a blog with BlogSite (or have that example's
Program.csand a single placeholder post ready to reuse)
The finished code for this tutorial lives in examples/BlogSiteFirstPostExample.
1. Start from a bare-minimum front-matter block
This section replaces the scaffold's placeholder post with a new file Content/Blog/my-first-post.md that carries only the three fields every post truly needs — title, description, and date — then confirms it renders on the home listing, the archive, and the RSS feed even in this minimal state.
Delete Content/Blog/hello-world.md and create my-first-post.md
The scaffold tutorial left a placeholder post named hello-world.md in Content/Blog/. Delete it, then create a new file my-first-post.md in the same folder. The filename (minus .md) becomes the URL slug, so the post serves at /blog/my-first-post/.
Paste in title, description, and date only
Paste the markdown body below into the new file. These three fields are the smallest front matter that lets a BlogSite post render cleanly: title is the post's heading and link label; description is what the home card, archive card, and RSS <description> element all pull from; and date drives both the archive sort order and the RSS <pubDate> element.
---
title: Shipping a tiny content engine for weekend projects
description: Notes from the first month of building Pennington.
date: 2026-04-10
---
Welcome to the first real post on this blog. The scaffold from the
previous tutorial gave us a running BlogSite with one placeholder
post; this post replaces it.
## What's here so far
Just title, description, and date. That is enough for the home
listing, the archive page, and the RSS feed to light up.
The two --- fences delimit the YAML front matter block. The date: value parses as an ISO-8601 date; any format that round-trips as a date string works. For the full list of recognized front-matter keys, see the Pennington.BlogSite.BlogSiteFrontMatter reference page.
Checkpoint
- Run
dotnet runfrom the example project - Visit
http://localhost:5000/— a single recent-posts card titled Shipping a tiny content engine for weekend projects appears with the description from the front matter - Visit
http://localhost:5000/archive— the same post appears as the only archive entry, dated 2026-04-10 - Visit
http://localhost:5000/blog/my-first-post/— the post body renders with its H1 and paragraph text
2. Add the author, tags, series, and repository fields
Next, the front-matter block expands with the four BlogSiteFrontMatter fields that each light up a distinct blog surface — author, tags, series, and repository.
Replace the front matter with the fully-populated block
Replace the existing YAML block with the fully-populated block below. Each new key drives a different surface:
author:— byline on the post page and the<author>element in the RSS feedtags:—/tags/<tag>/index pages plus chips on the post pageseries:— shared-banner threading on the post chromerepository:— "Source Code" link card on the post page
---
title: Shipping a tiny content engine for weekend projects
description: Notes from the first month of building Pennington — why Markdig plus Razor components plus a little YAML beats reaching for a heavier framework.
date: 2026-04-10
author: Author Name
tags:
- pennington
- dotnet
- blogging
series: Pennington Field Notes
repository: https://github.com/example/pennington-field-notes
---
Welcome to the first real post on this blog. The scaffold from the
previous tutorial gave us a running BlogSite with one placeholder
post; this post replaces it with something the BlogSite template
actually has opinions about.
## What the front matter is doing
Each field in the block above lights up a different surface — the
archive card, the post header, the /tags/<tag> listings, the RSS
channel, the JSON-LD metadata — and walking through them in order
is the point of this tutorial.
BlogSiteFrontMatter carries more keys than this — sectionLabel for navigation grouping and redirectUrl for migrated posts among them. For the full record definition, see Pennington.BlogSite.BlogSiteFrontMatter.
Reload and confirm every surface updated
With the file saved, reload the running site and verify each new field in turn. No code changes are needed — the host from the scaffold tutorial stays untouched.
The RSS feed is on because EnableRss defaults to true; to turn it off, set it on BlogSiteOptions (see Pennington.BlogSite.BlogSiteOptions).
Checkpoint
- Visit
http://localhost:5000/blog/my-first-post/— the post header shows the byline Author Name, the series banner Pennington Field Notes, three tag chips (pennington, dotnet, blogging), and a Source Code link card pointing at therepository:URL. - Visit
http://localhost:5000/tags/pennington/— the post appears on the per-tag index; repeat for/tags/dotnet/and/tags/blogging/. - Visit
http://localhost:5000/archive— the archive card carries the longer description from the expanded front matter. - Visit
http://localhost:5000/rss.xml— the feed<channel>carries the site title and one<item>whose<title>,<description>,<pubDate>,<author>, and<link>all map back to the front matter.
Summary
- A Pennington blog post backed by
BlogSiteFrontMattermaps predictably onto each blog surface — title/description/date for listings, author for byline and RSS, tags for/tags/<tag>/indexes, series for the shared banner, repository for the source-code link card. - Dropping a new
Content/Blog/*.mdfile brings it straight to the home page, the archive, every tag it claims, and/rss.xml— noProgram.cschanges needed.