Archive By Year Columns

The archive

Four years, read backwards

2026

18 pieces

The year we published our prices.

2025

41 pieces

Everything we learned running three projects at once.

2024

37 pieces

The year the studio went from two people to five.

2023

22 pieces

Written in the evenings, before any of this was a plan.

About this block

Archive By Year ColumnsPRO

One column per year on a hairline, each stating the year as a figure with its published count beside it, a sentence on what that year was about, and the pieces that defined it.

Feature274: Archive By Year Columns

One column per year on a hairline, each stating the year as a figure with its published count beside it, a sentence on what that year was about, and the pieces that defined it.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Upgrade Now

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://ui.beste.co/r/feature274?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://ui.beste.co/r-base/feature274?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/feature274.tsx and the badge6 component it uses for the eyebrow (installed to components/beste/component/badge6.tsx).

Quick start

The installed file exports feature274Demo alongside the block: the exact props behind the preview above. Spread it to get a working year index in one line.

tsx
import { Feature274, feature274Demo } from "@/components/beste/block/feature274";

export default function ArchivePage() {
  return <Feature274 {...feature274Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Feature274 } from "@/components/beste/block/feature274";

export default function ArchivePage() {
  return (
    <Feature274
      eyebrow="The archive"
      heading="Four years, read backwards"
      countLabel="pieces"
      years={[
        {
          year: "2026",
          count: "18",
          summary: "The year we published our prices.",
          posts: [
            { title: "The estimate is design work", href: "/essays/estimate" },
            { title: "The quote we lost on purpose", href: "/letters/042" },
          ],
        },
      ]}
    />
  );
}

Props

PropTypeDefaultDescription
eyebrowstring–Badge6 label above the hairline rule
headingstring–Section heading under the rule
countLabelstring–Noun after each year's count, e.g. "pieces"
yearsYearColumn[][]One column per year, newest first
classNamestring–Extra classes for the outer section
ts
type YearColumn = {
  year: string;
  count: string;
  summary: string;
  posts: YearPost[];
};

type YearPost = {
  title: string;
  href: string;
};

Behavior notes

  • year and count are strings, not numbers, so a column can read "2023" or "Before 2023" without the block trying to do arithmetic on it.
  • Both carry tabular-nums, which keeps the figures aligned across columns even in a proportional typeface.
  • Order comes from the array. The block does not sort, so a newest-first archive is a newest-first array.
  • Columns are two across at md and four at lg, each on its own hairline, so a year with one post does not stretch to match its neighbour.

More Feature blocks

View all Feature
PRO

feature254

Photographic Year Ledger

PRO

feature162

Numbered Steps Grid

FREE

feature34

Numbered Reasons List

Get Pro access