# Blog 01

> A blog section with a grid layout.

A shadcn/ui block from the [@ncdai](https://chanhdai.com/components) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/ncdai/blog-01).

- Page, with a live preview: https://shadcn.exchange/r/ncdai/blog-01
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/ncdai/blog-01-light-1a828be3b0dc1a49.png
- Registry item: https://chanhdai.com/r/blog-01.json
- Categories: marketing
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://chanhdai.com/r/blog-01.json
```

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

## Dependencies

- npm packages: `date-fns`, `lucide-react`
- Registry items: `button`

## Files

### `src/registry/blocks/blog-01/blog-01.tsx`

```tsx
import { ArrowRightIcon } from "lucide-react"

import { Button } from "@/components/ui/button"
import { ArticleItem } from "@/registry/blocks/blog-01/components/article-item"

export default function Blog01() {
  return (
    <div className="container mx-auto flex flex-col gap-8 px-4 py-8">
      <h2 className="ml-4 font-heading text-4xl font-medium tracking-tight md:text-5xl">
        Blog
      </h2>

      <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
        {articles.map((article) => (
          <a key={article.id} className="block h-full" href="#">
            <ArticleItem
              title={article.title}
              coverUrl={article.coverUrl}
              createdAt={article.createdAt}
            />
          </a>
        ))}
      </div>

      <div className="flex justify-center">
        <Button
          className="gap-2 pr-2.5 pl-3"
          nativeButton={false}
          render={<a href="#" />}
        >
          View All
          <ArrowRightIcon />
        </Button>
      </div>
    </div>
  )
}

type Article = {
  id: string
  title: string
  coverUrl: string
  createdAt: string
}

const articles: Article[] = [
  {
    id: "1",
    title:
      "Apple unveils iPhone 17 Pro: Aluminum frame returns, new colors, upgraded camera",
    coverUrl:
      "https://assets.chanhdai.com/registry/images/blocks/blog-01/1.webp",
    createdAt: "2025-09-13",
  },
  {
    id: "2",
    title:
      'While the world is expecting AGI, François Chollet is showing just how "naive" AI can be',
    coverUrl:
      "https://assets.chanhdai.com/registry/images/blocks/blog-01/2.webp",
    createdAt: "2025-04-21",
  },
  {
    id: "3",
    title:
      "Apple introduces iPhone 16e: A powerful new model for the iPhone 16 lineup",
    coverUrl:
      "https://assets.chanhdai.com/registry/images/blocks/blog-01/3.webp",
    createdAt: "2025-02-20",
  },
  {
    id: "4",
    title:
      "Apple unveils MacBook Pro M4: Same design, base model now with 16GB RAM, priced from $1,599",
    coverUrl:
      "https://assets.chanhdai.com/registry/images/blocks/blog-01/4.webp",
    createdAt: "2024-10-31",
  },
  {
    id: "5",
    title:
      "Apple unveils new Mac mini M4: Smaller, 16GB RAM on the base model, priced from $599",
    coverUrl:
      "https://assets.chanhdai.com/registry/images/blocks/blog-01/5.webp",
    createdAt: "2024-10-31",
  },
  {
    id: "6",
    title:
      "Apple unveils iMac M4: Unchanged design, more powerful M4 chip, RAM starts at 16GB, priced from $1,299",
    coverUrl:
      "https://assets.chanhdai.com/registry/images/blocks/blog-01/6.webp",
    createdAt: "2024-10-29",
  },
]
```

### `src/registry/blocks/blog-01/components/article-item.tsx`

```tsx
import { format } from "date-fns"

export type ArticleItemProps = {
  title: string
  coverUrl: string
  createdAt: string
}

export function ArticleItem({ title, coverUrl, createdAt }: ArticleItemProps) {
  return (
    <article className="h-full rounded-2xl bg-card text-card-foreground shadow-xs ring-1 ring-foreground/10 dark:ring-border">
      <div className="p-1 pb-0">
        <div className="relative aspect-video">
          <img
            className="size-full rounded-xl object-cover"
            src={coverUrl}
            alt={title}
          />
          <div className="pointer-events-none absolute inset-0 rounded-xl inset-ring-1 inset-ring-black/10 dark:inset-ring-white/15" />
        </div>
      </div>

      <div className="flex flex-col gap-2 px-4 pt-4 pb-6">
        <time
          className="block text-sm text-muted-foreground"
          dateTime={new Date(createdAt).toISOString()}
        >
          {format(new Date(createdAt), "MMMM d, yyyy")}
        </time>

        <h3 className="text-lg/tight font-medium text-balance">{title}</h3>
      </div>
    </article>
  )
}
```
