DEV Community

Daniel Pertu
Daniel Pertu

Posted on

Why our 404 page exists: the default one painted the header the wrong colour

Munchable has a branded 404 page. That is not interesting on its own. What is interesting is that the reason to write it was a CSS bug, and the reason to think about it was a robots tag that contradicted itself. Both are in the file header, and both are the kind of thing you only learn by looking at the default page in a real browser.

The bug

Next.js serves a built-in not-found page when you do not provide one. It injects its own body styles: black text on a white background, plus a dark-scheme variant. Every other page on the site is cream.

/**
 * Without this file Next serves its built-in one, which injects
 * `body{color:#000;background:#fff}` plus a dark-scheme variant of its own. Our
 * sticky header is a translucent cream (rgba(255,248,236,.86)) that assumes the
 * cream page behind it, so on that white body it rendered as a visibly paler
 * strip, and on a device set to dark it sat on black. Owning the route is what
 * puts the page back on the site's own background.
 */
Enter fullscreen mode Exit fullscreen mode

The sticky header is translucent cream over cream. Over white it becomes a paler strip. Over the dark variant it becomes a cream bar on black. The root layout still wraps the default page, so the header, footer and consent banner all render, on the wrong background. A visitor who typed the address wrong got a page that looked broken in a way that had nothing to do with the typo.

Owning the route means the page renders inside the layout on the site's own body, and only the middle needs writing.

The robots tag

Next emits <meta name="robots" content="noindex"> for this route on its own. The root layout hands down index, follow. Leave the page's metadata unset and both appear in one head, contradicting each other.

The site has a NO_INDEX constant for admin and account pages. It would have settled the contradiction, but it also says nofollow, and that tells a crawler to ignore the links on the page. The links on the page are the point of the page.

export const metadata: Metadata = {
  title: 'Page not found',
  robots: { index: false, follow: true },
};
Enter fullscreen mode Exit fullscreen mode

So: noindex, and still follow. There is also no canonical and no path, because the shared metadata helper derives both from a URL and a 404 has no URL of its own. Every unmatched address renders this one.

What is on it

A numeral made of the brand mark, the heading "We can't find that page", one line of reassurance, one button and three cards:

/** Where someone who landed here most plausibly meant to go. */
const WAYS_BACK = [
  { href: '/conditions', title: 'The seven conditions', blurb: 'IBS, reflux, lactose, bile acid malabsorption, gastroparesis, SIBO and IBD.' },
  { href: '/answers', title: 'Ingredient answers', blurb: 'Is this ingredient OK for my gut? One straight answer per condition.' },
  { href: '/#how', title: 'How scanning works', blurb: 'Point at a barcode, get Good fit, Caution or Avoid, and the reasons why.' },
];
Enter fullscreen mode Exit fullscreen mode

No search box and no fuzzy matching against nearby URLs. The site has three kinds of page a lost visitor was probably looking for, and a hand-written list of three beats a guess. Two inline comments record the restraint:

  • The brand mark is the nought in "404" and is hidden from assistive tech, because the heading already says what happened and the mark's own label would announce the brand a third time after the header.
  • One action, then three routes. A second button could only repeat one of the cards, and two ways to reach the same page is a decision the visitor did not need to be handed.

The reassurance line reads: "The link may be out of date, or the address may have a typo in it. Nothing has gone wrong with your account or your scans." A health app's 404 is a place people arrive worried. It should say the one thing that matters first.

See it at munchable.app/this-page-does-not-exist. The header is the same cream as the home page, which was the whole job.

Top comments (0)