zudo-doc
GitHub repository

Type to search...

to open search from anywhere

Changelog

Created Mar 16, 2026Updated Aug 31, 2026Takeshi Takatsudo

How to maintain a changelog section in your documentation site.

zudo-doc includes a changelog section for tracking release notes and version history. The changelog uses descending sidebar sort so the newest entries always appear at the top.

Directory Structure

Changelog entries live in a dedicated content directory:

src/content/docs/
└── changelog/
    ├── index.mdx          # Category index page (sets desc sort order)
    ├── 0.2.0.mdx          # Newer entry (sidebar_position: 2)
    └── 0.1.0.mdx          # Older entry (sidebar_position: 1)

Category Configuration

The index.mdx file configures descending sort order so newer entries appear first in the sidebar:

changelog/index.mdx
---
title: Changelog
sidebar_position: 10
category_sort_order: "desc"
---

With category_sort_order: "desc", entries with higher sidebar_position values appear first. This means newer versions naturally sort to the top.

Adding a New Entry

To add a new changelog entry:

  1. Create a new MDX file in src/content/docs/changelog/ named after the version (e.g., 0.2.0.mdx)

  2. Set the sidebar_position to a value higher than the previous entry

  3. Mirror the file in every configured additional-locale directory (for example, src/content/docs-ja/changelog/ and src/content/docs-de/changelog/)

src/content/docs/changelog/0.2.0.mdx
---
title: "0.2.0"
description: Short summary of this release.
sidebar_position: 2
---

Summary of changes in this release.

### Features

- Feature A
- Feature B

### Bug Fixes

- Fix for issue X

Tip

Use incrementing sidebar_position values for each new version. Combined with category_sort_order: "desc" in the category's index.mdx, this ensures the newest entry always appears at the top of the sidebar.

Entry Format

Each changelog entry is a standard MDX file. zudo-doc recommends a Keep a Changelog-style structure because those entries can be converted into package-friendly CHANGELOG.md files:

  • Title: The version number (e.g., "0.2.0")

  • Description: A brief summary of the release

  • Release date: A Released: YYYY-MM-DD line near the top when the release date is known

  • Content sections: grouped human-written notes such as Added, Changed, Deprecated, Removed, Fixed, Security, Breaking Changes, Features, and Bug Fixes

Write entries for humans. Do not dump raw git logs into changelog pages; group notable user-facing changes into short bullets.

Generated Package Changelogs

Projects can configure generated changelog outputs with the changelogs field. Each item points at a source directory and an output file:

zfb.config.ts
export default defineConfig(
  zudoDoc({
    changelogs: [
      {
        sourceDir: "src/content/docs/changelog",
        outputFile: "packages/zudo-doc/CHANGELOG.md",
        packageName: "@takazudo/zudo-doc",
      },
    ],
  }),
);

The MDX files remain the source of truth. The generated CHANGELOG.md is overwritten from those pages and should not be edited by hand. zudo-doc strips frontmatter, imports, exports, JSX tags/components, and MDX comments so the output stays readable as CommonMark in node_modules.

Multiple outputs can be configured by adding more items to the array. This is useful when a monorepo wants separate package changelogs, each generated from its own changelog source directory.

Multiple Changelogs (Multi-Package Projects)

Use a nested changelog when a monorepo publishes several packages independently. The top-level page becomes a landing page, and each package gets its own nested category:

src/content/docs/changelog/
├── index.mdx
├── core/
│   └── index.mdx
└── cli/
    └── index.mdx

This produces /docs/changelog, /docs/changelog/core, and /docs/changelog/cli. The landing page lists the package categories and does not use category_sort_order: "desc":

changelog/index.mdx
---
title: Changelog
sidebar_position: 10
---

Release notes for every package in this repository.

<CategoryNav category="changelog" />

One Page per Package (Default)

By default, the generator creates one index.mdx per package. Keep the complete package history on that page, with ## Unreleased followed by version sections:

changelog/core/index.mdx
---
title: Core
sidebar_position: 1
---

## Unreleased

### Added

- Work in progress.

## 1.0.0

Released: 2026-08-22

### Added

- Initial release.

One File per Version

Use separate version files when you also emit a package CHANGELOG.md. In this variant, the package index sets descending order and renders its release files:

src/content/docs/changelog/core/
├── index.mdx
├── 1.1.0.mdx
└── 1.0.0.mdx
changelog/core/index.mdx
---
title: Core
sidebar_position: 1
category_sort_order: "desc"
---

Release notes for the core package.

<CategoryNav category="changelog/core" />

Each package directory configured in changelogs must contain non-index, per-release MDX files. Set sourceDir to that package directory, never to the top-level changelog/ landing directory:

zfb.config.ts
changelogs: [
  {
    sourceDir: "src/content/docs/changelog/core",
    outputFile: "packages/core/CHANGELOG.md",
    packageName: "@acme/core",
  },
  {
    sourceDir: "src/content/docs/changelog/cli",
    outputFile: "packages/cli/CHANGELOG.md",
    packageName: "@acme/cli",
  },
],

The build warns about the landing-directory pitfall when a configured sourceDir yields no release entries but contains subdirectories with MDX files.

Tip

Previous/next pagination runs across the entire changelog section, so it can cross from one package into another. On package boundary pages, set pagination_prev: null or pagination_next: null in frontmatter when that transition would be confusing.

Generate the Layout

Pass a comma-separated package list when scaffolding a project:

pnpm create zudo-doc my-docs --changelog-packages core,cli

--changelog-packages implies --changelog. The generator creates the landing page and one package index for each slug, but it does not add a changelogs output configuration. To emit package CHANGELOG.md files, switch those packages to the per-version-file layout and configure one changelogs entry per package.

The version-bump skill keeps one lockstep root version and updates all packages by default, or only the packages you select. It adds a new version section to each selected single-page changelog, or a new per-version file to each selected package using the per-version-file layout. Independent per-package versioning is not supported.

Version Bump Script

zudo-doc includes a scripts/version-bump.sh script that automates version management:

# Bump version and create changelog entry
./scripts/version-bump.sh 0.2.0

# Bump version, create changelog entry, and snapshot current docs
./scripts/version-bump.sh 1.0.0 --snapshot

The script performs the following steps:

  1. Updates the version field in package.json

  2. Creates a changelog entry MDX file in the primary and each configured additional-locale directory

  3. Sets the correct sidebar_position automatically (incremented from existing entries)

Doc Snapshots

When called with --snapshot, the script also archives the current documentation as a versioned snapshot before bumping. This integrates with zudo-doc's versioning system:

  1. Copies src/content/docs/ to src/content/docs-v{old}/

  2. Copies each configured additional-locale directory (for example, src/content/docs-ja/ to src/content/docs-v{old}-ja/ and src/content/docs-de/ to src/content/docs-v{old}-de/)

  3. Prints the version config entry to add to src/config/settings.ts

Note

The --snapshot flag archives the old version's docs, not the new version. After the script runs, src/content/docs/ represents the new version and the snapshot preserves the previous state.

Version Bump Skill

For Claude Code users, zudo-doc includes a /zudo-doc-version-bump skill that orchestrates the entire release workflow. Instead of running the script manually, the skill handles everything end-to-end:

  1. Analyzes commits since the last git tag and categorizes them (breaking, features, fixes, other)

  2. Proposes a version bump type (major/minor/patch) based on the changes

  3. Runs version-bump.sh to update package.json and create changelog entries

  4. Fills in the changelog templates with actual commit details for the primary and each configured locale

  5. Runs pnpm b4push to validate the build

  6. Commits, pushes, and waits for CI

  7. Creates a git tag and GitHub release

  8. Guides you through npm publishing (or skips it for private packages)

# Run the skill in Claude Code
/zudo-doc-version-bump

# Or skip the proposal step by specifying the bump type
/zudo-doc-version-bump patch

Note

The skill requires at least one v* tag to exist. If this is the first release, create the initial tag manually: git tag v0.1.0 && git push --tags.

Header Navigation

For one changelog, use a flat headerNav item:

headerNav: [
  // ...other items
  { label: "Changelog", labelKey: "nav.changelog", path: "/docs/changelog", categoryMatch: "changelog" },
],

For multiple package changelogs, make the parent a dropdown. Keep categoryMatch: "changelog" on the parent and omit categoryMatch from its children:

headerNav: [
  // ...other items
  {
    label: "Changelog",
    path: "/docs/changelog",
    categoryMatch: "changelog",
    children: [
      { label: "Core", path: "/docs/changelog/core" },
      { label: "CLI", path: "/docs/changelog/cli" },
    ],
  },
],

Nested child active state is path-based, while categoryMatch scopes the sidebar by a single top-level directory. Two or more children that share a categoryMatch can all appear active in server-rendered HTML. A multi-segment value such as "changelog/core" never matches the top-level category and can leave the sidebar empty. The build reports a warning for either mistake. See Header Navigation for the general rule.

i18n

Mirror changelog entries in every configured additional-locale directory (such as src/content/docs-ja/changelog/ and src/content/docs-de/changelog/) to provide translated release notes. The index.mdx and directory structure should match the primary version.

Revision History

Takeshi TakatsudoCreated: 2026-03-16T22:41:36+09:00Updated: 2026-08-31T16:30:01+09:00

AI Assistant

Ask a question about the documentation.

Preview theme

Loading theme previews…