Animated ASCII art for 404 and error pages

Make a 404 or 500 page people remember with animated ASCII art. Ready-made error pieces plus any scene or creature, embedded with one tag.

Loading the builder…

/WHY

Everyone hits a broken link sometimes. A plain "Not found" loses them; a page with something to look at and one clear way back keeps them on your site.

The builder makes a complete 404, 500 or maintenance page with an animated ASCII piece, your words and your colours, plus the files for Next.js and Astro and the exact config for GitHub Pages, Netlify, Vercel, nginx, Apache, Express and Caddy.

/EXAMPLES

Ready-made examples to copy

Each one is complete. Copy it as it is, or change the piece name to any piece in the library.

404.html for any static host

GitHub Pages, Netlify, Vercel, Cloudflare Pages and Surge all serve a 404.html from the site root automatically.

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>404 · Page not found</title><meta name="robots" content="noindex"></head>
<body style="margin:0;min-height:100vh;display:grid;place-items:center;background:#05060a;color:#f4f4f5;font-family:system-ui;text-align:center">
  <main>
    <ascii-art piece="page-404" size="7"></ascii-art>
    <h1>This page drifted off into space.</h1>
    <p><a href="/" style="color:inherit">Take me home</a></p>
  </main>
  <script type="module" src="https://www.ascii-magic.com/ascii/ascii.js"></script>
</body>
</html>

Add a search box

Send people to your site search with what they were looking for, taken from the broken URL.

<form action="/search" style="margin-top:16px">
  <input name="q" id="q" placeholder="Search the site" style="padding:10px;width:240px">
  <button>Search</button>
</form>
<script>
  // turn /blog/old-post-name into "old post name"
  q.value = location.pathname.split("/").pop().replace(/[-_]/g, " ");
</script>

Maintenance page (503)

Serve it with a 503 status and a Retry-After header so search engines come back later instead of dropping your pages.

# nginx: switch on by creating /var/www/maintenance.on
if (-f /var/www/maintenance.on) { return 503; }
error_page 503 @maintenance;
location @maintenance {
  root /var/www/errors;
  add_header Retry-After 3600 always;
  rewrite ^ /503.html break;
}

Next.js App Router

app/not-found.tsx is shown for every missing route.

import Link from "next/link";
import Script from "next/script";

export default function NotFound() {
  return (
    <main style={{ minHeight: "100vh", display: "grid", placeItems: "center", textAlign: "center" }}>
      <div>
        {/* @ts-expect-error custom element */}
        <ascii-art piece="black-hole" size="6"></ascii-art>
        <h1>Lost in space</h1>
        <Link href="/">Back home</Link>
      </div>
      <Script type="module" src="https://www.ascii-magic.com/ascii/ascii.js" />
    </main>
  );
}

How to do it

  1. Pick an error piece, or any piece that fits your brand.
  2. Add the script tag and the element to your 404.html.
  3. Keep a plain text link back home under the art.

/GUIDE

What a good error page has

One sentence that says what happened in plain words, one obvious way back (usually a button to the home page), and ideally a search box or links to your most visited pages. The art is there to soften the moment, not to replace those.

Status codes matter for search

A missing page must return the 404 status, not 200, or search engines will index your error page as real content. Static hosts do this for you when you name the file 404.html. For servers, the config tab shows how.

During maintenance, return 503 with a Retry-After header. Search engines then wait and come back instead of treating your pages as gone.

Add <meta name="robots" content="noindex"> to the error page itself, as the generated page does.

Keep it light

Error pages are often served when something is already wrong, such as an overloaded server. Keep them to one HTML file with inline styles. The ASCII piece adds a few kilobytes and loads after the text.

Pieces that work well for this

Open any of them to copy the code or export.

/FAQS

Animated ASCII art for 404 and error pages: frequently asked questions

Q. What makes a good 404 page design?
A good 404 page design says what happened in one plain sentence, offers one obvious way back, and gives people a reason to stay. That usually means a button home, a search box or links to popular pages, plus something friendly to look at. An animated ASCII piece softens the moment without replacing those.
Q. What are some creative 404 page ideas with ASCII art?
Try a lost in space theme with Lost In Space 404, Black Hole or Asteroid Belt, a broken television with TV Static or CRT Test Card, or a message that unscrambles itself with Decode Reveal. Pair the art with a short line that matches it, like This page drifted off into space, and a clear link home.
Q. How do I add a custom 404 page to a static site?
Save the builder's page as 404.html at the root of your published folder. Most static hosts, including GitHub Pages, serve a file with that name automatically for missing pages and return the 404 status. The page is one file with inline styles, so there is nothing else to upload.
Q. How do I make a custom 404 page in Next.js or Astro?
Use the builder's Next.js tab for app/not-found.tsx in the App Router, which loads the script with next/script. For Astro, save the Astro tab as src/pages/404.astro. Both keep the heading, message and link as real text and place the animated piece above them.
Q. How do I serve a custom 404 page on nginx, Apache, Express or Caddy?
Open the Server config tab: it has the error_page line for nginx, the ErrorDocument line for an Apache .htaccess file, an Express handler that sends the file with the right status, and a handle_errors block for Caddy. Each one serves your page while keeping the real error status code.
Q. Does an animated 404 page hurt SEO?
No, as long as the page returns a real 404 status rather than 200. The generated page also includes a robots noindex tag, so search engines never index it as content. The text loads first and the animation after it, so the art does not delay what crawlers and visitors read.
Q. Can I make a 500 error or maintenance page the same way?
Yes. Switch the Error choice to 500 or 503 and the builder changes the code, title and files. Server Error 500 and Maintenance Mode are made for those pages. For Next.js, the 500 version becomes an error.tsx file with a Try again button that calls reset.
Q. What status code should a maintenance page return?
A maintenance page should return 503 Service Unavailable, ideally with a Retry-After header. That tells search engines the outage is temporary, so they come back later instead of dropping your pages. The nginx example on this page shows a switch that serves your 503 page whenever a maintenance file exists.
Q. Why does my host show its own 404 instead of mine?
The file is usually in the wrong place or has the wrong name. Name it exactly 404.html and put it at the root of the folder your host publishes, such as public or dist after a build, then deploy again. On your own server, check that the config line points at the right path.
Q. Does the 404 page work if JavaScript is blocked?
Yes. The heading, message and link home are plain HTML, so they show without JavaScript. Only the animated piece needs the script; without it, that space simply stays empty. Keep the link home as real text so nobody is ever stuck on the page.
Q. How big should a 404 page be?
As small as possible, because error pages are often served when something is already wrong. The builder's page is one HTML file with inline styles and no images. The ascii-art piece adds a few kilobytes and loads after the text, so the message appears first.
Q. Is an animated 404 page accessible?
Yes. The piece is labeled for screen readers with its name, it holds a still frame for anyone who prefers reduced motion, and the heading, message and button stay as real text. The page title also says Page not found, so screen reader users hear what happened straight away.

Other ways to use it

Each one has its own builder.