> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getsabo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> Manage release notes stored as MDX and rendered on /changelog.

Sabo ships with a simple MDX-powered changelog.

* **Content Location**: `sabo/src/content/changelog/`
* **List Page**: `sabo/src/app/changelog/page.tsx`
* **Entry Page**: `sabo/src/app/changelog/[slug]/page.tsx`
* **Helper**: `sabo/src/lib/changelog.ts`

## Add a New Entry

<Steps>
  <Step title="Create a file">
    In `sabo/src/content/changelog/`, create a new `.mdx` file. The filename becomes the slug (e.g., `0-4-0.mdx` → `/changelog/0-4-0`).
  </Step>

  <Step title="Add frontmatter">
    Include metadata at the top. `releaseDate` is used for sorting (newest first).

    ```yaml theme={null}
    ---
    version: "v0.4.0"
    title: "Your Release Title"
    releaseDate: "2025-01-20T00:00:00.000Z"
    author:
      name: "Sabo Team"
      picture: "/blog/authors/sabo.png" # optional
    image: "/og/changelog.png" # optional Open Graph
    ---
    ```
  </Step>

  <Step title="Write content">
    Write your notes using Markdown/MDX. Headings like `## New Features`, `## Improvements`, and `## Bug Fixes` are commonly used.
  </Step>
</Steps>

## Fields Reference

<ParamField path="version" type="string">
  Displayed version label for the release.
</ParamField>

<ParamField path="title" type="string">
  Release title shown on the list and detail pages.
</ParamField>

<ParamField path="releaseDate" type="string">
  ISO date string used to sort entries (newest first).
</ParamField>

<ParamField path="author.name" type="string">
  Optional author display name.
</ParamField>

<ParamField path="author.picture" type="string">
  Optional author avatar path (relative to `public/`).
</ParamField>

<ParamField path="image" type="string">
  Optional Open Graph image used for social previews on the detail page.
</ParamField>

<Note>
  `image` is used in the entry page’s metadata for Open Graph previews. `author.picture` is parsed but not rendered by the current UI.
</Note>

## How It Works

Changelog files are read and parsed from `src/content/changelog`, then sorted by `releaseDate`.

```ts sabo/src/lib/changelog.ts theme={null}
export interface Author {
  name: string;
  picture?: string;
}

export interface ChangelogMetadata {
  slug: string;
  version: string;
  title: string;
  releaseDate: string;
  author?: Author;
  image?: string;
}

export interface ChangelogEntry extends ChangelogMetadata {
  content: string;
}
```

```ts sabo/src/lib/changelog.ts theme={null}
// Sort entries by releaseDate (newest first)
return entries.sort((a, b) => {
  return new Date(b.releaseDate).getTime() - new Date(a.releaseDate).getTime();
});
```

<Info>
  Slugs are derived from filenames (e.g., `0-4-0.mdx` → `/changelog/0-4-0`). No extra configuration is required.
</Info>
