# Changelog 02

> A simple changelog block

A shadcn/ui block from the [@shadcnui-blocks](https://shadcnui-blocks.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/shadcnui-blocks/changelog-02).

- Page, with a live preview: https://shadcn.exchange/r/shadcnui-blocks/changelog-02
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/shadcnui-blocks/changelog-02-light-ca066a7bf0124b11.png
- Registry item: https://shadcnui-blocks.com/r/changelog-02.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://shadcnui-blocks.com/r/changelog-02.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Files

### `src/registry/blocks/radix/changelog-02/components/changelog.tsx`

```tsx
import { Separator } from "@/registry/bases/radix/ui/separator";
import { cn } from "@/lib/utils";

const changelogs = [
  {
    version: "1.0.0",
    date: "2025-06-01",
    title: "Initial Launch",
    description:
      "We're live! The very first release of our Shadcn UI blocks is here. This version includes the core blocks, dark mode support, and a complete landing page setup to get you started. Thanks for being here from day one!",
    features: [
      "Released 10+ customized Shadcn UI blocks",
      "Dark mode support",
      "Landing page with hero, features, and footer sections",
    ],
    isMajor: true,
  },
  {
    version: "1.1.0",
    date: "2025-06-10",
    title: "Pricing Block + Accessibility Improvements",
    description:
      "We've added a sleek pricing block with a monthly/yearly toggle. Accessibility improvements make your UI more inclusive, and we fixed a few layout issues to ensure a smoother mobile experience.",
    features: ["Added pricing block with monthly/yearly toggle"],
    changes: ["Improved accessibility for buttons and links"],
    fixes: ["Fixed mobile layout issues on testimonials section"],
  },
  {
    version: "1.2.0",
    date: "2025-06-20",
    title: "Blog Layout + Search Enhancements",
    description:
      "Introducing a brand-new blog layout designed for content creators. Search now supports fuzzy matching to make discovery easier. We've also optimized assets for faster load times.",
    features: ["Introduced a clean blog layout for content creators"],
    changes: [
      "Search bar now uses fuzzy filtering",
      "Optimized all images for performance and SEO",
    ],
    isMajor: false,
  },
  {
    version: "1.3.0",
    date: "2025-07-01",
    title: "Premium Blocks & Theme Customization",
    description:
      "This is a big one! We're rolling out premium blocks for advanced use cases, along with filtering options and customizable color themes so you can match your brand identity effortlessly.",
    features: [
      "Launched premium blocks section",
      "Added category and search filters",
      "Introduced customizable color themes",
    ],
    isMajor: false,
  },
  {
    version: "1.3.1",
    date: "2025-07-05",
    title: "Minor Fixes",
    description:
      "A quick patch to clean up a few UI glitches. Fixed image paths and polished up the theme switcher to eliminate flicker issues. Nothing major, but definitely smoother!",
    fixes: [
      "Fixed broken image links in logo cloud",
      "Resolved theme switcher flicker issue on dark mode",
    ],
    isMajor: false,
  },
].reverse();

export default function Changelog() {
  return (
    <section className="mx-auto max-w-3xl px-6 py-16">
      <h2 className="text-balance font-medium text-4xl tracking-tight">
        Changelog
      </h2>
      <p className="mt-2 text-balance text-lg text-muted-foreground tracking-[-0.015em] sm:mt-3 sm:text-xl">
        We ship fast. Track all the new features, updates, and fixes in one
        place.
      </p>

      <Separator className="mt-9" />

      <div className="flex flex-col divide-y sm:mt-16 sm:divide-y-0">
        {changelogs.map((changelog) => (
          <div
            className="relative flex items-start gap-8 py-10 sm:border-l sm:first:pt-0 [&>div]:-mt-1"
            key={changelog.version}
          >
            <div className="sticky top-5 mt-1.5 hidden min-w-40 pl-8 text-lg text-muted-foreground tracking-tight sm:block">
              <p className="relative z-10 bg-background pl-3 text-base leading-none">
                {changelog.date}
              </p>
              {/* Dot */}
              <div
                className={cn(
                  "absolute inset-y-0 left-0 my-auto h-2 w-2 -translate-x-1/2 rounded-full bg-muted-foreground",
                  {
                    "bg-primary ring-[3px] ring-primary/30": changelog.isMajor,
                  }
                )}
              />
              {/* Line */}
              <div className="absolute inset-0 -z-10 my-auto h-px w-full bg-border" />
            </div>
            <div>
              <h3 className="-mt-[0.2lh] font-medium text-2xl tracking-[-0.02em]">
                {changelog.title}
              </h3>
              <span className="mt-2 block text-lg text-muted-foreground tracking-tight sm:hidden">
                {changelog.date}
              </span>

              <p className="mt-3 text-muted-foreground">
                {changelog.description}
              </p>

              <div className="mt-4 space-y-4">
                {changelog.features && (
                  <div>
                    <h4 className="mb-1 flex items-center gap-2 font-medium text-lg">
                      Features:
                    </h4>
                    <ul className="list-disc pl-5 text-muted-foreground">
                      {changelog.features?.map((feature) => (
                        <li key={feature}>{feature}</li>
                      ))}
                    </ul>
                  </div>
                )}

                {changelog.changes && (
                  <div>
                    <h4 className="mb-1 flex items-center gap-2 font-medium text-lg">
                      Changes:
                    </h4>
                    <ul className="list-disc pl-5 text-muted-foreground">
                      {changelog.changes?.map((change) => (
                        <li key={change}>{change}</li>
                      ))}
                    </ul>
                  </div>
                )}

                {changelog.fixes && (
                  <div>
                    <h4 className="mb-1 flex items-center gap-2 font-medium text-lg">
                      Fixes:
                    </h4>
                    <ul className="list-disc pl-5 text-muted-foreground">
                      {changelog.fixes?.map((fix) => (
                        <li key={fix}>{fix}</li>
                      ))}
                    </ul>
                  </div>
                )}
              </div>
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}
```
