Changelog
Author release notes as ordinary content files or source them from GitHub Releases, and Blume builds a timeline page and an RSS feed automatically.
Blume ships a changelog out of the box. Write each release as a normal content file, mark it type: changelog, and Blume collects every entry into a generated timeline page and an RSS feed — no layout to build, no list to maintain. Or skip the files entirely and source your changelog from GitHub Releases.
Write an entry
A changelog entry is a regular .md or .mdx page with type: changelog in its frontmatter. By convention they live under changelog/, but the type — not the folder — is what matters:
---
title: v1.2.0
type: changelog
date: 2026-06-20
changelog:
version: 1.2.0
category: Features
---
A big batch of components landed this release — columns, frames, trees, and tooltips, plus code groups that render as proper language tabs.
- New `Accordion`, `Expandable`, and `Tooltip` components
- `CodeGroup` tabs with flush code blocks
Give every entry a date so the timeline and feed sort newest-first. An unquoted YAML date is fine — Blume normalizes it.
The changelog object
The optional changelog object adds richer metadata for the timeline and feed:
changelog.version?string
Release version. Falls back to a v-prefixed label when there's no title.
stringchangelog.category?string
Shown as a tag beside the entry, e.g. Release, Features, Fixes.
stringchangelog.date?string
Publish date. May live here or at the top level — both feed the timeline and RSS feed.
stringThe timeline page
Once you have at least one type: changelog entry, Blume generates a /changelog page automatically. It renders as a focused, full-width timeline — no sidebar or table of contents — with each entry newest-first, showing its date, label, and category tag in a left rail beside its content:
- The entry title becomes its label — or
v{version}when there’s no title. It links to that entry’s own page, so a release is both a line in the timeline and a shareable permalink. - The
categoryrenders as a tag next to the date. - Drafts and
sidebar.hiddenentries are skipped.
The page appears only when nothing already occupies the /changelog route. To replace it with your own design, add a custom page at pages/changelog.astro — it takes over and Blume stops generating the default timeline.
Because this page is generated rather than authored, it isn’t part of the content tree — so a header tab pointing at /changelog resolves to the newest entry instead. Give the tab an href to land on the index itself:
navigation: {
tabs: [
{ label: "Changelog", path: "/changelog", href: "/changelog" },
],
}
Grouped by major version
When your versions follow semver and span more than one major, Blume paginates the timeline by major version. Only the newest major line is shown, with a Show N.x releases button at the bottom that reveals the next-oldest major one click at a time:
- Detection is automatic — no configuration. It kicks in only when every listed release parses as
major.minor.patchand there is more than one major; otherwise the timeline stays flat. - It tolerates the scoped tags monorepos publish, so
pkg@2.0.0groups under2.xandpkg@1.4.0under1.x. - It’s progressive enhancement: every release is still in the page’s HTML (and its RSS feed and search index), so readers without JavaScript — and crawlers — see the complete history. The button only collapses older majors once the page hydrates.
From GitHub Releases
Rather than authoring entries by hand, point the built-in github-releases source at a repo and every release becomes a type: changelog entry — the same timeline and feed, fed straight from the releases you already publish. Blume’s own changelog is built this way:
content: {
sources: [
{ type: "filesystem", root: "content" },
{
type: "github-releases",
prefix: "changelog",
owner: "acme",
repo: "sdk",
},
],
}
The release name becomes the title, its tag becomes changelog.version, and its published date sorts the timeline. Each release page also gets a unique meta description summarized from its notes — markdown stripped, section headings and changeset commit-hash prefixes dropped, trimmed to the search-snippet length blume audit checks for — instead of falling back to the site description. A private repo authenticates with the GITHUB_TOKEN environment variable. See Content sources for every option.
The RSS feed
Blume also builds a changelog feed at /changelog/rss.xml, sorted newest-first by date. Feeds need an absolute site URL, so set deployment.site; Blume then injects a <link rel="alternate"> tag on every page so readers discover it automatically.
The feed is on by default. Tune it under seo.rss:
seo: {
rss: {
enabled: true,
types: ["blog", "changelog"],
limit: 50,
},
}
Remove "changelog" from rss.types to skip the feed while keeping the timeline.
Structured data
When structured data is on, each changelog entry is emitted as a schema.org TechArticle with its description and publish date, so search engines can index releases as dated articles.