For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. The asciicn agent skill, for building any ASCII effect on the engine, is at /.well-known/agent-skills/asciicn/SKILL.md.

Not found

A 404 page whose code is drawn in sand: gusts wear its edges and grains drift downwind and settle, over a terminal line that echoes the missing path.

Controls
Code
Charset
Colour mode
Accent
Wind1×
Cell10px
Animate

Installation

pnpm dlx shadcn@latest add https://asciicn.dev/r/not-found.json

Usage

In Next.js, render it from app/not-found.tsx. That file handles unknown URLs and every notFound() call, and Next.js answers with a 404 status.

import Link from "next/link";
 
import { NotFound } from "@/components/asciicn/not-found";
import { Button } from "@/components/ui/button";
 
export default function NotFoundPage() {
  return (
    <main className="flex min-h-svh flex-col items-center justify-center">
      <NotFound
        actions={
          <>
            <Button asChild>
              <Link href="/">Back home</Link>
            </Button>
            <Button asChild variant="outline">
              <Link href="/docs">Browse the docs</Link>
            </Button>
          </>
        }
      />
    </main>
  );
}

The code is set in the page's own typeface at a heavy weight, then sampled into glyphs. Each sample knows how far it sits from the edge of a digit. Two gusts per loop sweep across the code and wear its edges down a few samples deep, so it changes shape without ever breaking up. Grains lift off the tops and right-hand faces, arc downwind in accent and fade as they settle, and the hole each one leaves fills back in as it lands. Faint wind ripples run through the sand. The loop lasts 16 seconds.

The terminal line types $ cd <path>, answers cd: no such file or directory: <path> and waits at a blinking cursor. Without path it reads window.location.pathname after mount, so the server markup and the first client render match. command and message change the two lines, for a failed request rather than a missing page:

<NotFound
  code="500"
  title="Something broke"
  path="/api/orders"
  command="curl -f"
  message="(22) the server returned 500"
/>

Examples

Something broke

A 500 page with a curl line, a red accent and a stronger wind.

Inside a card

compact shrinks the art, the terminal line and the type, for a missing record inside an app.

Classic ramp

The standard charset at a 12px cell. The sand thins from @ to . toward its edges, and the grains in flight are . and :.

Props

PropTypeDefault
code

The code drawn in sand.

Type: stringDefault "404"
title

The heading under the art.

Type: ReactNodeDefault "Page not found"
description

One or two sentences under the heading.

Type: ReactNodeDefault A line about a moved or mistyped link
path

The path echoed in the terminal line. Read after mount when omitted.

Type: stringDefault window.location.pathname
command

The command typed before the path.

Type: stringDefault "cd"
message

The error the command prints.

Type: stringDefault "no such file or directory"
actions

Buttons or links, laid out in a centred row.

Type: ReactNodeDefault –
titleAs

Heading level of the title, to fit the page outline.

Type: "h1" | "h2" | "h3" | "p"Default "h1"
accent

Colour of the drifting grains, the prompt and the cursor: a palette name or any CSS colour.

Type: AsciiColorDefault "orange"
wind

How hard the wind blows, from 0 (still sand, no grains) to 2.

Type: numberDefault 1
compact

A smaller layout for cards and panels.

Type: booleanDefault false
charset

Glyphs the sand is drawn with. Braille draws one dot per grain.

Type: CharsetNameDefault "braille"
colorMode

`truecolor` draws the sand in ink and the grains in `accent`; `mono` draws both in ink.

Type: "mono" | "truecolor" | "ansi16" | "duotone" | "palette"Default "truecolor"
dither

Ordered dithering. Blue noise turns the thinning edges into a stipple of loose grains.

Type: "none" | DitherMatrixDefault "blue-noise" for Braille and quadrants, "none" for ramps
cell

Glyph cell height of the art in CSS pixels.

Type: numberDefault 10, or 8 when compact
speed

Time multiplier for the wind.

Type: numberDefault 1
animate

`false` holds a still frame, prints the terminal line at once and stops the cursor blinking.

Type: booleanDefault true
stillTime

The moment drawn when motion is off or reduced, in seconds.

Type: numberDefault 5.5
chars, phosphor, ramp, ansi, grade, invert, threshold, edgeThreshold, background, fx

The shared look props. See [the engine](/docs/engine/ascii-engine).

Type: AsciiLookDefault –
handle

Filled with a handle for export.

Type: RefObject<AsciiHandle | null>Default –

Notes

  • The art is a canvas of real glyphs and is labelled with the code (role="img"). The terminal line, the title and the description are DOM text, so they are readable, selectable and translatable. Screen readers get the error line once, not letter by letter.
  • The motion is a function of time on a 16 second loop, so a still frame needs no history. Under prefers-reduced-motion the art holds the stillTime frame, the terminal line prints at once and the cursor stays lit.
  • The art pauses offscreen and in hidden tabs, and follows the theme: ink glyphs on the page, the accent from the --ascii-color-* tokens.
  • The code fits its box, so a three-digit code and a word such as "gone" both work. Short codes read best.