How the changelog pages work

What the build generates, what stays yours, and how to set it up for a GitHub repository.

Short answer to the most common question: the pages are driven by your configuration, not by your content. Creating a folder and dropping a page with <fd-changelog> in it does not make the build produce years and months. The build reads changelog.monthlyPages and writes the tree itself.

The one thing to remember

<fd-changelog> displays history. changelog.monthlyPages generates pages. They are independent — you can use either alone.

What you create, and what the build creates

You create the section and, if you want one, a landing page:

docs/
└── changelog/
    ├── _section.json        ← yours: the section's label and position
    └── index.md             ← yours: whatever you want readers to land on

The build adds everything below that, and keeps it in step with the history:

docs/
└── changelog/
    ├── _section.json
    ├── index.md
    └── feastdocs/               ← generated: one folder per repository
        ├── _category.json       ← generated: the category label
        ├── index.md             ← generated: that repository's overview
        └── 2026/                ← generated: one folder per year
            ├── _category.json
            └── august.md        ← generated: one page per month

Each generated page holds a filter and nothing else:

---
title: 'FeastDocs — August 2026'
sidebar_label: 'August'
sidebar_position: -8
---

<!-- AUTO-GENERATED by `npm run docs:build` — edits are overwritten. -->

# FeastDocs — August 2026

<fd-changelog month="2026-08"></fd-changelog>

That is why the files are stable: the commits live in a generated data module, never in the page. A new commit changes no file. A new month adds one.

Each repository's index.md becomes its category's own link, and carries that repository's months plus its five most recent changes. That is deliberate: the listings live with the repository they belong to, so the section's landing page can be an introduction and a set of cards (<fd-changelog-repos>) instead of a third copy of the same commits.

You do not even have to create the section — point monthlyPagesDir at a folder that does not exist and the build creates it, which then becomes a top-level section with a label derived from the folder name.

Setting it up for a GitHub repository

// feastdocs.config.mjs
github: {
  repo: 'acme/docs',       // gives every entry a commit link
  branch: 'main',
},
changelog: {
  limit: 150,              // how many commits to read
  monthlyPages: true,      // generate the tree
  monthlyPagesDir: 'changelog',
  selfLabel: 'Acme Docs',  // category label for this repository
},
npm run docs:build

The log tells you what happened:

changelog: git history gave 146 commits
changelog pages: 3 written, 0 removed → docs/changelog

docs/changelog/index.md is yours. An index of the generated pages, without repeating their contents, is one component:

<fd-changelog-months></fd-changelog-months>

The generated files are ordinary Markdown and are meant to be committed. They change rarely — once a month — and committing them keeps the repository self-describing and the content manager's file tree honest.

Which branch the history comes from

By default the build reads the checked-out branch, which is what a normal deploy wants: the changelog matches the content being published.

Set a branch explicitly when that is not true — for example when previews build from feature branches but the changelog should always show the release line:

changelog: {
  branch: 'main',
},

A CI clone often holds only the branch it built, so main may exist solely as origin/main. Both are tried, and if neither exists the build warns and reads the checked-out branch rather than failing:

! changelog: branch 'release' is not in this checkout — reading the checked-out branch instead

Other repositories carry their own branch, set per entry in changelog.repos — see changelogs for several products.

Several repositories

Each source gets its own category, in the order you list them:

Changelog
├── Changelog            (your index.md)
├── Acme Docs            ← this repository, named by selfLabel
│   └── 2026 › August
└── Checkout API         ← from changelog.repos
    ├── 2026 › August, July
    └── 2025 › December
changelog: {
  monthlyPages: true,
  groupByRepo: true,      // 'auto' drops this level while there is one source
  selfLabel: 'Acme Docs',
  repos: [
    { repo: 'acme/checkout-api', title: 'Checkout API' },
  ],
},

title is the category label and the URL segment (/changelog/checkout-api/…). Without it the repository name is used.

What is yours and what is the build's

Owner Rule
_section.json, index.md, any page you wrote You Never touched
<repo>/_category.json, <year>/_category.json Build Carries "generated": true
<repo>/index.md, <year>/<month>.md Build Carries the AUTO-GENERATED marker

Two consequences:

  • Edits to generated pages are lost on the next build. Put anything hand-written on your own page in the section.
  • Pruning only removes what it generated. Months that fall out of changelog.limit, a renamed product, a repository dropped from the config — their pages go. A page you wrote inside a year folder stays, and so does a _category.json you wrote yourself.

Ordering

Generated categories use deliberately large positions so your own pages come first: repositories at 1000 + index (config order), years at 10000 - year (newest first). Months use a negative sidebar_position so December precedes January within a year.

Give your own pages ordinary positions (10, 20, …) and they stay at the top of the section.

Turning it off

Remove monthlyPages (or set it to false) and the build stops generating. The pages already written are not removed — pruning only runs when the feature is on. Delete the folders yourself, or turn it back on, build once to let it prune, then turn it off.

Troubleshooting

Symptom Cause
No pages appear monthlyPages is not true, or the history is empty
git history gave 1 commit Shallow checkout — the build falls back to the host API, and the log says so
A month is missing No commits landed in it; empty months are skipped
An old month page lingers It is outside changelog.limit; it is pruned on the next build with the feature on
The repository level is missing groupByRepo is 'auto' and there is only one source
Pages appear in an unexpected section monthlyPagesDir is a top-level folder, so it is a section