# Article

> The reading layout of one blog post: a back link, tag, title, lead, author, date, and cover, then the post as plain HTML, with a list of its sections on wide screens.

- Name: `article`
- Status: beta
- Categories: blog, post, reading, marketing
- Files: the install writes `article.tsx`, and any part files named `article-*.tsx`, to your `components` alias, `@/components` by default. Edit them freely. They are yours.
- Other registry items: `@arbokui/avatar`, `@arbokui/badge`, `@arbokui/button`, `@arbokui/glide-highlight`. The install adds them.
- Gallery: https://arbokui.com/website/article
- Registry item: https://arbokui.com/r/article.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the website component. It also adds every component it uses:

   ```bash
   npx shadcn@latest add @arbokui/article
   ```

## Use it for

- The page for one blog post, guide, or announcement, under the site's Navbar.
- Pass the post as children, as plain HTML or the output of your Markdown: h2, h3, p, a, ul, ol, blockquote, code, pre, figure, img, and hr. The Article styles them.
- Give each section an h2. With two or more, a list of them sits beside the body on wide screens, and marks the one being read.
- Pass \`back\` to link to the list of posts, and your router's link through \`renderLink\`, like next/link.
- Pass \`date\` as a plain date, like "2026-10-12". It prints the same on the server and in the browser.
- Pass \`cover\` as your own image or a drawing. It fills a 16:9 frame at every width, and an image is cropped to fit.
- The title and section headings are set in the theme's \`font-headline\`. Load Geist Serif as \`--font-geist-serif\`, or it falls back to the system serif.
- A pinned navbar covers the top of the page. Set \`--article-offset\` on the Article to its height plus a gap, like className="\[--article-offset:5rem\]". It sets where the list sticks and where a jump to a section lands. The default is 6rem.

## Avoid it for

- A list of posts. Use a grid of cards that link here.
- Docs with a sidebar of pages. The sections list covers one page only.
- A Hero above it. The title is the page's h1.
- Headings in the body other than h2 and h3. Use h2 for each section and h3 inside one.

## Props

- `title`: `ReactNode`. The post's title. It is the page's h1, in the serif.
- `lead`: `ReactNode`. One or two sentences under the title that say what the post covers.
- `tag`: `ReactNode`. A short tag over the title, like "Guides".
- `back`: `{ href: string; label: string }`. The link back to the list of posts, like { href: "/blog", label: "All posts" }.
- `author`: `{ name: string; role?: ReactNode; avatar?: string }`. Who wrote it. The name gives the avatar its initials and tint, and avatar is a photo URL.
- `date`: `string`. When it was published, as a date like "2026-10-12". A string that is not a date shows as it is.
- `readingTime`: `ReactNode`. How long it takes to read, like "6 min read".
- `cover`: `ReactNode`. A picture under the header, like an \<img> or a drawing, in a 16:9 frame. It spans the body and the sections list.
- `children`: `ReactNode`. The post itself, as plain HTML.
- `renderLink`: `(props: ArticleLinkProps) => ReactNode`. Default `a plain <a>`. Draws the back link. Spread the props onto your router's link: (props) => \<Link {...props} />. The renderLink a site passes its Navbar fits too.
- `locale`: `string`. Default `"en-US"`. Formats the date. Fixed, so the server and the browser print the same words.
- `contentsLabel`: `string`. Default `"On this page"`. The heading over the list of sections, on wide screens.
- `className`: `string`. Extra classes on the article, which holds the container query.

## Accessibility

- The root is an article. The title is its h1, so the page should have no other.
- The date is a time element with the date you passed as its datetime.
- The author's name is written out, so screen readers skip the avatar.
- The sections list is a nav named by its heading. The link for the section being read has aria-current="location".
- A press on a section scrolls to it, smoothly unless reduced motion is on, updates the address, and moves focus to its heading, so Tab carries on from there.
- Copy link keeps its name. Screen readers hear "Link copied", or that it could not copy, from a polite live region.
- A code block that is wider than the column scrolls inside itself, and takes focus so keys can scroll it.
- Links in the body are underlined, so they never rely on color alone.

## Examples

### A blog post

```tsx
<Article
  back={{ href: "/blog", label: "All posts" }}
  tag="Guides"
  date="2026-10-12"
  readingTime="6 min read"
  title="How to plan a release"
  lead="The steps a team can follow from the first list of changes to the day it ships."
  author={{ name: "Priya Raman", role: "Product lead" }}
>
  <h2>Write down the scope</h2>
  <p>Start with a short list of what the release changes.</p>
  <h2>Set the dates</h2>
  <p>Pick the day it ships first, then work back from it.</p>
</Article>
```

### With next/link, a cover, and another locale

```tsx
<Article
  title="Planifier une version"
  date="2026-10-12"
  locale="fr-FR"
  contentsLabel="Sur cette page"
  back={{ href: "/blog", label: "Tous les articles" }}
  cover={<img src="/blog/release.png" alt="" width={1600} height={800} />}
  renderLink={(props) => <Link {...props} />}
>
  <p>Commencez par une courte liste.</p>
</Article>
```
