block · 81/108
Changelog Page
Releases grouped by date with version, category, and product area filters.
Install
Install manuallyView source on GitHub
Composes
- changelog-page.tsx12
- changelog-entry.tsx9
- empty-state.tsx7
- filter-bar.tsx2
Accessibility4 checks
- Filters are labelled selects inside a Filter Bar, and Reset filters is disabled until a filter is active.
- A polite status announces how many releases match after each filter change.
- Each month is a section named by its h2, and each release is an article named by its h3 title. Empty months are removed from the page and the accessibility tree.
- Categories pair a color dot with a written label, and an empty result explains how to recover.
Content and community
Changelog
Every Kiln release, grouped by month. Subscribe to the feed to hear about new versions.
0 releases
September 2026
v4.2.0Builds
Persistent build cache
- Added
- Improved
- Parsed templates are cached on disk, keyed by content hash.
- Images are resized only when the source or size changes.
v4.1.3Dev server
Safer dev server reloads
- Fixed
- Security
- Reloads no longer drop query strings.
- The dev server now binds to localhost unless --host is passed.
August 2026
v4.1.0Images
Image formats and the legacy router
- Added
- Removed
- AVIF output for every responsive image size.
- The legacy router, deprecated since 3.0, has been removed.
Code example
usage.tsx"use client";import { SearchX } from "lucide-react";import { useState } from "react";import { ChangelogPage, ChangelogPageCount, ChangelogPageDescription, ChangelogPageEmpty, ChangelogPageFilter, ChangelogPageFilterOption, ChangelogPageFilters, ChangelogPageGroup, ChangelogPageGroupTitle, ChangelogPageHeader, ChangelogPageRelease, ChangelogPageTitle, type ChangelogPageVariant,} from "@/components/uai/changelog-page";import { ChangelogEntryCategories, ChangelogEntryCategory, type ChangelogEntryCategoryTone, ChangelogEntryChange, ChangelogEntryChanges, ChangelogEntryContent, ChangelogEntryDate, ChangelogEntryHeader, ChangelogEntryTitle, ChangelogEntryVersion,} from "@/components/ui/uai/changelog-entry";import { EmptyStateAction, EmptyStateActions, EmptyStateContent, EmptyStateDescription, EmptyStateHeader, EmptyStateMedia, EmptyStateTitle,} from "@/components/ui/uai/empty-state";import { FilterBarControls, FilterBarReset } from "@/components/ui/uai/filter-bar";const categoryLabels: Record<ChangelogEntryCategoryTone, string> = { added: "Added", improved: "Improved", fixed: "Fixed", removed: "Removed", security: "Security",};const months = [ { month: "September 2026", releases: [ { version: "4.2.0", date: "2026-09-24", label: "Sep 24", title: "Persistent build cache", area: "Builds", categories: ["added", "improved"] as ChangelogEntryCategoryTone[], changes: [ "Parsed templates are cached on disk, keyed by content hash.", "Images are resized only when the source or size changes.", ], }, { version: "4.1.3", date: "2026-09-09", label: "Sep 9", title: "Safer dev server reloads", area: "Dev server", categories: ["fixed", "security"] as ChangelogEntryCategoryTone[], changes: [ "Reloads no longer drop query strings.", "The dev server now binds to localhost unless --host is passed.", ], }, ], }, { month: "August 2026", releases: [ { version: "4.1.0", date: "2026-08-19", label: "Aug 19", title: "Image formats and the legacy router", area: "Images", categories: ["added", "removed"] as ChangelogEntryCategoryTone[], changes: [ "AVIF output for every responsive image size.", "The legacy router, deprecated since 3.0, has been removed.", ], }, ], },];export function ChangelogPagePreview({ variant = "timeline" }: { variant?: ChangelogPageVariant }) { const [category, setCategory] = useState(""); const [area, setArea] = useState(""); return ( <ChangelogPage variant={variant} category={category} onCategoryChange={setCategory} area={area} onAreaChange={setArea} > <ChangelogPageHeader> <div style={{ display: "grid", gap: 6 }}> <ChangelogPageTitle>Changelog</ChangelogPageTitle> <ChangelogPageDescription> Every Kiln release, grouped by month. Subscribe to the feed to hear about new versions. </ChangelogPageDescription> </div> <ChangelogPageCount /> </ChangelogPageHeader> <ChangelogPageFilters> <FilterBarControls> <ChangelogPageFilter name="category" label="Category"> <ChangelogPageFilterOption value="">All categories</ChangelogPageFilterOption> {Object.entries(categoryLabels).map(([value, label]) => ( <ChangelogPageFilterOption key={value} value={value}> {label} </ChangelogPageFilterOption> ))} </ChangelogPageFilter> <ChangelogPageFilter name="area" label="Product area"> <ChangelogPageFilterOption value="">All areas</ChangelogPageFilterOption> <ChangelogPageFilterOption value="Builds">Builds</ChangelogPageFilterOption> <ChangelogPageFilterOption value="Dev server">Dev server</ChangelogPageFilterOption> <ChangelogPageFilterOption value="Images">Images</ChangelogPageFilterOption> </ChangelogPageFilter> </FilterBarControls> <FilterBarReset /> </ChangelogPageFilters> {months.map((group) => ( <ChangelogPageGroup key={group.month}> <ChangelogPageGroupTitle>{group.month}</ChangelogPageGroupTitle> {group.releases.map((release) => ( <ChangelogPageRelease key={release.version} categories={release.categories} area={release.area} > <ChangelogEntryHeader> <ChangelogEntryVersion>v{release.version}</ChangelogEntryVersion> <ChangelogEntryDate dateTime={release.date}>{release.label}</ChangelogEntryDate> <span style={{ color: "var(--uai-subtle)", fontSize: 12 }}>{release.area}</span> </ChangelogEntryHeader> <ChangelogEntryContent> <ChangelogEntryTitle>{release.title}</ChangelogEntryTitle> <ChangelogEntryCategories> {release.categories.map((tone) => ( <ChangelogEntryCategory key={tone} tone={tone}> {categoryLabels[tone]} </ChangelogEntryCategory> ))} </ChangelogEntryCategories> <ChangelogEntryChanges> {release.changes.map((change) => ( <ChangelogEntryChange key={change}>{change}</ChangelogEntryChange> ))} </ChangelogEntryChanges> </ChangelogEntryContent> </ChangelogPageRelease> ))} </ChangelogPageGroup> ))} <ChangelogPageEmpty> <EmptyStateMedia> <SearchX /> </EmptyStateMedia> <EmptyStateContent> <EmptyStateHeader> <EmptyStateTitle>No releases match these filters</EmptyStateTitle> <EmptyStateDescription> Try another category or product area, or clear the filters to see every release. </EmptyStateDescription> </EmptyStateHeader> <EmptyStateActions> <EmptyStateAction emphasis="secondary" onClick={() => { setCategory(""); setArea(""); }} > Clear filters </EmptyStateAction> </EmptyStateActions> </EmptyStateContent> </ChangelogPageEmpty> </ChangelogPage> );}Manual installation
changelog-page.tsxLoading component source…