Inspect recorded application snapshots, play through ordered events, pin a comparison baseline, and jump to any checkpoint.
Activity replay
Inspect the state behind each recorded event.
Created
0.0s · Maya opened a project
Untitled project
Draft0tasks
Paused at event 1 of 4.
pnpm dlx shadcn@latest add @latheui/activity-replayPart of Lathe Pro. Set up your project once with your license key: npx latheui init --key <key>. See Lathe Pro.
Activity Replay is part of Lathe Pro
The preview is live and free to try. The source, the install and every assembly come with Pro: $79 once, with lifetime updates.
Depends on
| Prop | Type | Default | Description |
|---|---|---|---|
| events* (required) | readonly ReplayEvent<T>[] | — | Ordered events with unique id, label, optional detail, nonnegative at timestamp in milliseconds and an application-owned snapshot. |
| renderSnapshot* (required) | (snapshot: T, baseline: T | undefined) => ReactNode | — | Render state and its optional baseline. Snapshots are supplied by the application; Lathe does not record sessions. |
| value / defaultValue | string | first event (defaultValue) | Controlled or initially selected event id. |
| onValueChange | (id: string) => void | — | Receives automatic and manual event changes. |
| interval | number | 1200 | Fixed playback interval between events in milliseconds; event timestamps remain metadata. |
| disabled | boolean | false | Disable navigation, speed changes and playback. |
| className | string | — | Classes for the section. |
Replace the demo data and callbacks with your application. Honor AbortSignal in asynchronous callbacks so cancellation also stops transport work.
"use client"
import { ActivityReplay } from "@/components/activity-replay"
const events = [
{ id: "created", label: "Created", at: 0, detail: "Maya opened a project", snapshot: { name: "Untitled project", tasks: 0, status: "Draft" } },
{ id: "named", label: "Named", at: 2400, detail: "Project renamed", snapshot: { name: "Field notes", tasks: 0, status: "Draft" } },
{ id: "planned", label: "Planned", at: 6100, detail: "Three tasks added", snapshot: { name: "Field notes", tasks: 3, status: "Draft" } },
{ id: "shared", label: "Shared", at: 9400, detail: "Project shared with the team", snapshot: { name: "Field notes", tasks: 3, status: "In review" } },
]
export default function ReplayDemo() {
return <div className="w-full max-w-xl"><ActivityReplay events={events} renderSnapshot={(snapshot, baseline) => <div className="space-y-4"><div className="flex flex-wrap items-center justify-between gap-3"><p className="text-lg font-medium tracking-tight">{snapshot.name}</p><span className="rounded-full border border-border px-2 py-1 text-xs">{snapshot.status}</span></div><p className="font-mono text-3xl tabular-nums">{snapshot.tasks}<span className="ml-2 font-sans text-xs text-muted-foreground">tasks</span></p>{baseline && <p className="border-t border-border pt-3 text-xs text-muted-foreground">Baseline: {baseline.name}, {baseline.tasks} tasks, {baseline.status}.</p>}</div>} /></div>
}