Skip to content

Custom 404 pages

To show your own page when a visitor asks for an address that doesn’t exist, put a file named 404.html in the root of your build output. It’s served, with a 404 status, for any path on your site that doesn’t match a file.

You don’t need any configuration. If your site has no 404.html, visitors see a plain default page instead.

Most generators build 404.html for you from a page or template:

Generator Create
Astro src/pages/404.astro (or 404.md)
Hugo layouts/404.html
Eleventy A page with permalink: /404.html
Jekyll 404.html or 404.md in the site root, with permalink: /404.html
VitePress Built in. Customise it through the theme’s NotFound layout slot
Docusaurus Built in. Customise it by swizzling the NotFound theme component
Plain HTML A 404.html file next to your index.html

After building, check that 404.html is in the root of the output folder, next to your home page.

To give one part of your site its own not-found page, add a rule to your _redirects file with the status 404:

/docs/* /docs/404.html 404

A missing page under /docs/ now gets /docs/404.html, with a 404 status. Everywhere else still gets the root 404.html.

Pages that exist aren’t affected: a real file always wins over a rule. This works on Level 0 (public) sites, like the rest of _redirects.

If your site is a single-page app that handles its own routes in the browser, you probably don’t want a 404 for unknown paths. Send them to your app instead, with a rewrite in _redirects:

/* /index.html 200

Your app then decides what to show, including its own not-found screen. The response status is 200, so search engines see those addresses as real pages.

  • Headers follow the address asked for. Rules in _headers match the address the visitor requested, not /404.html. To set a header on not-found responses for a section, write the rule for that section’s path.
  • A 404 isn’t cached for long. A Cache-Control rule of your own doesn’t apply to a not-found response.
  • Links without a trailing slash. If /about/ works but /about shows your 404 page, turn on the trailing-slash setting.

Ask for an address that doesn’t exist and check the status:

Terminal window
curl -sI https://www.example.com/this-page-does-not-exist/

The first line should say 404. Open the same address in a browser to see your page.

Next: Coverage & Performance >