Changelog
Show the releases of your project.
Installation
Install the timeline component. It adds @fumadocs/changelog to your dependencies:
npx @fumadocs/cli@latest add changelogUsage
Create a page under your Home Layout. Fetch a page of entries, render them with ChangelogTimeline, and link to the other pages with ChangelogPagination:
import { createFileRoute, notFound } from '@tanstack/react-router';
import { createServerFn } from '@tanstack/react-start';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { githubReleases } from '@fumadocs/changelog/github';
import { baseOptions } from '@/lib/layout.shared';
import { ChangelogPagination, ChangelogTimeline } from '@/components/changelog';
const getReleases = createServerFn({ method: 'GET' })
.validator((page: number) => page)
.handler(async ({ data: page }) => {
const releases = await githubReleases({
owner: 'fuma-nama',
repo: 'fumadocs',
token: process.env.GITHUB_TOKEN,
page,
});
if (releases.entries.length === 0) throw notFound();
return releases;
});
export const Route = createFileRoute('/changelog/{-$page}')({
loader: async ({ params }) => {
const page = Number(params.page ?? 1);
return { page, ...(await getReleases({ data: page })) };
},
component: Page,
});
function Page() {
const { page, entries, nextPage } = Route.useLoaderData();
return (
<HomeLayout {...baseOptions()}>
<div className="mx-auto flex w-full max-w-[900px] flex-col gap-10 px-4 py-12">
<ChangelogTimeline entries={entries} />
<ChangelogPagination
newer={page > 1 ? `/changelog/${page - 1}` : undefined}
older={nextPage ? `/changelog/${nextPage}` : undefined}
/>
</div>
</HomeLayout>
);
}Sources
GitHub Releases
githubReleases() returns a page of the published releases of a repository, with nextPage when there are older releases.
- Versions are read from the release names like
fumadocs-ui@16.17.0, or their tags. - Entries have a
prereleaseproperty for pre-releases. - GitHub limits unauthenticated requests to 60 per hour. Pass a
tokenand cache the page. - GitHub lists the first 1000 releases, or 10000 with a token. Later pages have no entries.
Prop
Type
Custom Entries
Entries are plain objects. Create them from any source:
Prop
Type
Entries go from the loader to the page as data, so write their content as Markdown in content, rather than as React nodes in body.
How is this guide?
Last updated on
