Editorial 404 With Portrait Image

(Not Found)

Empty room, wrong door.

There is nothing behind this address. If a link of ours sent you here, tell us and it will be corrected the same day.

Report the broken link

[email protected]
Quiet studio interior with soft afternoon light

Studio floor, late afternoon

About this block

Editorial 404 With Portrait ImagePRO

Two-column 404 in a quiet monochrome language: a parenthetical eyebrow, a two-line display headline, a pill call to action and an oversized report-the-link email on the left, a tall captioned photograph on the right.

Error20: Editorial 404 With Portrait Image

A quiet two-column 404: a short display headline, a pill call to action and an oversized report-the-link email address on one side, a tall captioned photograph on the other.

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/error20?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

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

This installs the block to components/beste/block/error20.tsx, plus the two design-system primitives it renders through: badge7 for the parenthetical eyebrow and button12 for the pill call to action.

Quick start

The installed file exports error20Demo alongside the block: the exact props behind the preview above. Spread it to get a working error page in one line.

tsx
import { Error20, error20Demo } from "@/components/beste/block/error20";

export default function NotFound() {
  return <Error20 {...error20Demo} />;
}

Then replace the demo with your own props. The contact link is rendered at display size, so keep the label short:

tsx
import { Error20 } from "@/components/beste/block/error20";

export default function NotFound() {
  return (
    <Error20
      badge={{ label: "Not Found" }}
      heading="Empty room, <strong>wrong door</strong>."
      description="There is nothing behind this address. If a link of ours sent you here, tell us."
      button={{ label: "Take me back", href: "/" }}
      contactLink={{ label: "[email protected]", href: "mailto:[email protected]" }}
      labels={{ caption: "Studio floor, late afternoon", contactTitle: "Report the broken link" }}
      image={{
        src: "https://images.unsplash.com/photo-1569342195780-46e0e695da6e?w=1000&h=1250&fit=crop",
        alt: "Quiet studio interior with soft afternoon light",
      }}
    />
  );
}

Props

PropTypeDefaultDescription
badge{ label: string }–Parenthetical eyebrow above the headline
headingstring–Headline HTML, rendered as an h1; <strong> marks the muted clause
descriptionstring–Explanatory paragraph under the headline
buttonActionLink–Pill call to action
contactLinkActionLink–Oversized contact link under the hairline rule
labelsError20Labels{}Image caption and the lead-in above the contact link
image{ src: string; alt: string }–Tall photograph in the second column
classNamestring–Extra classes for the outer <section>
ts
type ActionLink = {
  label: string;
  href: string;
};

type Error20Labels = {
  caption?: string;
  contactTitle?: string;
};

Behavior notes

  • The photograph fills a 4:5 aspect box with object-cover, so any source ratio crops to the same tall tile. There is no hover treatment on the image: it neither zooms nor changes contrast.
  • The caption sits outside the image tile, under it, so it reads as an editorial credit rather than an overlay.
  • The contact block is separated by a top rule and only renders when contactLink is set; labels.contactTitle on its own renders nothing.
  • The columns stack on mobile with the text first, and split into two equal columns from the lg breakpoint up.
  • heading is injected with dangerouslySetInnerHTML and accepts inline HTML; text inside <strong> drops to muted grey. Keep the value under your own control, never user input.

More Error blocks

View all Error
PRO

error19

Typographic 404 Index

PRO

error32

404 With Recent Writing

PRO

error21

Server Error Record

Get Pro access