A release history is a [generated section](/concepts/generated-sections): a
source names the file and the type that reads it, and the pages follow.

```ts
export default defineAppConfig({
  duxt: {
    sources: [
      {
        path: 'docs',
        generated: [
          {
            type: 'changelog',
            path: 'CHANGELOG.md',
            label: 'Releases'
          }
        ]
      }
    ]
  }
})
```

The fields a declaration takes are the same for every type and are in
[Sources](/reference/sources). `changelog` names one option of
its own — [`granularity`](/reference/changelog/granularity) — and answers the two
policies below.

## Versioning

**Per version.** Every published documentation version gets a changelog of its
own, read from the `CHANGELOG.md` of that version and served inside it —
`/releases` for the default version, `/v2.x/releases` beside `/v2.x/guides`. It
works exactly like the documentation and the API reference next to it.

Each copy renders the whole file that version shipped, earlier releases
included, so an older version's changelog ends where that version did. The
version switcher keeps the reader in the changelog: on a release page it opens
the same release in the other version, and where that version never had the
release it opens that version's changelog overview instead of a missing page.

**The file is required in every version.** A published version without a
`CHANGELOG.md` fails the build, for a downloaded source as much as for the
repository being built — leaving the version out, or showing another version's
history there, would both publish something that version never shipped.

## Localisation

**The original, in every language.** One collection, built from the default
locale.

A release log is written once, by the release tool, in whatever language the
project commits in. There is nothing per-locale about it, so a localised site
serves the original and says so with the
[translation banner](/concepts/localisation) it already draws for an untranslated
page — which is the honest answer and needs no new component. The declaration's
`locales` map is read by `per-locale` types only and does nothing here.

## Where the entry goes

`navigation: 'sections'` is the default and puts the entry in the section row —
the top-level parts of the documentation.

A release log is often not one of those: it is a thing the project has **beside**
its documentation rather than a part of it. `navigation: 'navigation'` moves the
entry to the narrow first row, and `false` puts it nowhere and leaves the site to
link it.

```ts
{
  type: 'changelog',
  path: 'CHANGELOG.md',
  label: 'Releases',
  navigation: 'navigation'
}
```

::callout{type="tip" title="Placing the entry by hand"}
Writing the entry into `navigation` yourself keeps it where you put it — the
build leaves a section it already finds in the row alone, rather than appending
it. Which matters, because appended is last, and after Credits is not where a
release log goes.
::

## The feed

`duxt.feed.path` names the section `/rss.xml` is built from, and a release
history is what it was written for: every release page carries the release's own
`date`, and a release is a thing that **happened** — which a reference page being
edited is not.

```ts
feed: { path: '/releases', title: 'my project — releases' }
```

Off unless the key is set. Only the default version of each source contributes,
so a versioned site does not repeat every entry once per version, even though
every version publishes a changelog of its own. See
[Configuration](/reference/configuration) and [`/rss.xml`](/reference/endpoints/rss-xml).

## When the file cannot be read

A **local** file that is not there fails the build while the config is loading,
as it does for every type. What the file does not quite say — a heading that
reads like a release but does not parse as one — is a warning in the build
report instead; see
[What is read](/reference/changelog/what-is-read) and
[What the build checks](/concepts/build-checks).