Changelog
Changelog timeline module with team member lookups and author resolution.
Overview
The changelog module provides a Changelog component and useChangelog composable for rendering a timeline of updates with author attribution. It queries from a Nuxt Content collection and resolves authors via the team collection.
Configuration
nuxt.config.ts
changelog: {
enabled: true, // default: true — set false to disable
}
Content Setup
Schema
Import the schema from the layer and define your changelog collection:
content.config.ts
import { defineContentConfig, defineCollection } from '@nuxt/content'
import { baseChangelogSchema } from '@incubrain/foundry/schemas'
export default defineContentConfig({
collections: {
changelog: defineCollection({
type: 'page',
source: { include: 'decisions/**/*.md', prefix: '/decisions' },
schema: baseChangelogSchema,
}),
},
})
Schema Fields
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Category label (e.g., strategy, feature, pivot) |
version | string | Yes | Version identifier |
date | string | No | Publication date |
title | string | Yes | Entry title |
description | string | No | Short description |
excerpt | string | No | Longer excerpt |
image | string | No | Cover image path |
author | string | No | Team member slug (resolves via team collection) |
Content File Example
content/decisions/my-update.md
---
label: feature
version: "1.2.0"
date: "2026-01-15"
title: My Important Decision
description: Why we made this choice
author: founder
image: /images/decisions/my-update.png
---
Full article content here...
Changelog Component
Renders a timeline of changelog entries with author avatars, dates, and labels.
| Prop | Type | Default | Description |
|---|---|---|---|
labelField | keyof ChangelogCollectionItem | 'label' | Grouping label field |
sortField | keyof ChangelogCollectionItem | 'date' | Sort field |
sortOrder | 'ASC' | 'DESC' | 'DESC' | Sort direction |
showAuthor | boolean | true | Show author info |
showImage | boolean | true | Show entry images |
showScrollTop | boolean | true | Show scroll-to-top button |
scrollTopThreshold | number | 500 | Scroll threshold for button |
emptyTitle | string | 'No items yet' | Empty state title |
emptyDescription | string | 'Check back soon for updates.' | Empty state text |
emptyIcon | string | 'i-lucide-inbox' | Empty state icon |
Usage in a page:
content/pages/decisions.md
---
title: Decisions
description: Strategic decisions and learnings
---
::changelog
::
useChangelog Composable
For custom rendering, use the composable directly:
const { items, pending, getAuthorForItem } = useChangelog({
labelField: 'label',
sortField: 'date',
sortOrder: 'DESC',
showAuthor: true,
showImage: true,
})
Returns:
| Name | Type | Description |
|---|---|---|
items | Ref<ChangelogCollectionItem[]> | Changelog items (async) |
pending | boolean | Loading state |
getAuthorForItem | (item) => AuthorData | null | Resolve author from team collection |
Author resolution uses the author frontmatter field to look up a team member by slug. The team member's name, avatar, and GitHub link are returned.
App Config
Map the collection in your app.config.ts:
app/app.config.ts
content: {
collections: {
changelog: { name: 'changelog', type: 'page', prefix: '/decisions' },
},
}