Not Found With Search

Error 404

This page moved, or it never existed

Search from here rather than going back and starting again. Members, appointments, documents, and invoices all answer the same query.

Soft blue gradient backdrop
rowan

Members

Rowan Blake

Active · Clinic 2

Member

Rowan Blake · Intake notes

Updated 3 days ago

Document

Invoice #4821

Rowan Blake · Paid

Billing

3 of 11 matches shown

About this block

Not Found With SearchPRO

A not-found page that offers a way forward rather than a way back, pairing an oversized light heading with an image tile floating a live search panel and a two-column hairline list of likely destinations.

A not-found page that offers a way forward rather than a way back, pairing an oversized light heading with an image tile floating a live search panel and a two-column hairline list of likely destinations.

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

Base UI flavor

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

This installs the block to components/beste/block/error36.tsx, the search24 results piece it floats on the tile (installed to components/beste/piece/search24.tsx), and the button21 component it uses for the action.

Quick start

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

tsx
import { Error36, error36Demo } from "@/components/beste/block/error36";

export default function NotFound() {
  return <Error36 {...error36Demo} />;
}

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

tsx
import { Error36 } from "@/components/beste/block/error36";
import { Search24 } from "@/components/beste/piece/search24";

export default function NotFound() {
  return (
    <Error36
      code="Error 404"
      heading="This page moved, or it never existed"
      description="Search from here rather than going back and starting again."
      button={{ label: "Back to the workspace", href: "/app" }}
      media={
        <Search24
          query="rowan"
          groupLabel="Members"
          results={[{ title: "Rowan Blake", meta: "Active · Clinic 2", kind: "Member" }]}
          footer="1 of 11 matches shown"
        />
      }
      image={{ src: "/backdrops/blue.jpg", alt: "Soft blue gradient backdrop" }}
      destinationsLabel="Where people usually meant to go"
      destinations={[
        {
          title: "Today's clinic list",
          description: "Everyone arriving today, sorted by time.",
          href: "/app/today",
        },
        { title: "Members", description: "The full directory across every site.", href: "/app/members" },
      ]}
    />
  );
}

Props

PropTypeDefaultDescription
codestring–Small status line above the heading
headingstring–Error heading, rendered as the page h1
descriptionstring–Centered supporting paragraph, capped at max-w-xl
button{ label: string; href: string }–Single outline action under the copy
mediaReactNode–Live asset on the tile, search24 in the demo
image{ src: string; alt: string }–Backdrop behind the media tile
destinationsLabelstring–Small label above the destination list
destinationsDestination[][]Linked hairline rows of likely pages
classNamestring–Extra classes for the outer section
ts
type ActionLink = {
  label: string;
  href: string;
};

type Destination = {
  title: string;
  description: string;
  href: string;
};

Behavior notes

  • The search panel inside the tile is a presentational piece, not a working search box. It illustrates the affordance, and the real search lives at whatever destination you point people to.
  • The action wrapper is flex items-start justify-center. The items-start is load-bearing: without it the button would stretch vertically inside the centered flex row.
  • Destinations are whole Link elements laid out as a two-column grid from sm, filling column by column, so an odd count leaves the gap at the end rather than mid-list.
  • The hover arrow uses a named group, group/error36, rather than the bare group class, so nesting this block inside another grouped component will not trigger both animations at once. The shift is wrapped in motion-safe:.
  • Each destination carries its own border-t with no closing rule, so the list stays open at the bottom.
  • Widths step outward down the page: max-w-2xl for the copy and the tile, max-w-4xl for the destinations, so the page reads as narrowing to a point and then opening out.
  • heading renders as an h1, since this block is designed to be the whole not-found page rather than a section of one.

More Error blocks

View all Error
PRO

error4

404 With Destination Cards

FREE

error2

404 With Site Search

PRO

error38

Missing Piece With Archive Search

Get Pro access