404

Dead End Sign Not Found

Dark 404 on a night road: a DEAD END warning sign beside a highway guide sign, then a monospace code, large headline, body and home button. Pulls in Geist Mono and Hanken Grotesk.

Free, MIT licenseOpen in Browse
import { ArrowLeftIcon } from "@phosphor-icons/react/dist/ssr"
import { cn } from "cn"

import { Eyebrow } from "@/components/editorial/eyebrow"
import { Heading } from "@/components/editorial/heading"
import { SectionDescription } from "@/components/editorial/section"
import {
  HighwaySign,
  WarningSign,
} from "@/components/graphics/road-signs"
import { buttonVariants } from "@/components/ui/button"

const SIGNS = {
  warning: { text: "DEAD", subtext: "END" },
  route: "ONWARD",
} as const

// The copy: change text here, not in the markup.
const COPY = {
  eyebrow: "404",
  title: "This page does not exist.",
  body: "There is nothing at this address. Everything else is still where you left it.",
  cta: "Back to home",
  onward: "Somewhere real instead",
} as const

const DESTINATIONS = [
  { href: "#", name: "Home", description: "Start from the surface." },
  { href: "#", name: "Browse", description: "The whole catalog, filterable." },
  { href: "#", name: "Docs", description: "How the pieces are made." },
  { href: "#", name: "Changelog", description: "What shipped, newest first." },
] as const

// The way back.
function HomeLink({ className }: { className?: string }) {
  return (
    <a
      href="#"
      data-slot="button"
      className={cn(
        buttonVariants({ size: "lg" }),
        "h-auto min-h-10 max-w-full py-2 text-center whitespace-normal",
        className
      )}
    >
      <ArrowLeftIcon data-icon="inline-start" aria-hidden="true" />
      {COPY.cta}
    </a>
  )
}

// A dead end on the night road; the guide sign points back the way you came.
export default function NotFound09() {
  return (
    <section className="dark @container/section flex min-h-[40rem] w-full flex-col items-center justify-center gap-10 bg-background px-6 py-24 wrap-anywhere text-foreground">
      <div className="flex max-w-full flex-wrap items-end justify-center gap-6">
        <WarningSign
          className="aspect-square h-auto max-w-full"
          text={SIGNS.warning.text}
          subtext={SIGNS.warning.subtext}
        />
        <HighwaySign
          className="max-w-full [&_.justify-between]:gap-[min(2rem,10vw)]"
          route={SIGNS.route}
          destinations={DESTINATIONS.slice(0, 3).map((d, i) => ({
            name: d.name,
            distance: String(i),
          }))}
        />
      </div>
      <header className="flex max-w-xl flex-col items-center gap-6 text-center">
        <Eyebrow>{COPY.eyebrow}</Eyebrow>
        <Heading render={<h1 />} size="lg">
          {COPY.title}
        </Heading>
        <SectionDescription size="md" variant="muted" className="max-w-lg">
          {COPY.body}
        </SectionDescription>
        <HomeLink />
      </header>
    </section>
  )
}

Installation

pnpm dlx shadcn add @01orbital/404-09
npx shadcn add @01orbital/404-09
yarn shadcn add @01orbital/404-09
bunx --bun shadcn add @01orbital/404-09

Free under the MIT license. Add the @01orbital registry to components.json once (install guide), then run the command.

It lands at components/blocks/404/404-09/index.tsx, as source you own and edit.

Usage

import NotFound09 from "@/components/blocks/404/404-09"

export default function Example() {
  return <NotFound09 />
}

Dependencies

npm: @phosphor-icons/react, cn. The CLI installs them for you.

Registry pieces it installs with it: