404 Not Found status code
Use Harp to show a custom 404 page.
Why
Whatever you’re making deserves a custom 404 page — somewhere you can give visitors useful information and keep the site’s design consistent.
Usage
Add a 404.html file in your served directory. (404.ejs, 404.md, or 404.jade work too — they’ll compile to HTML.) When a request doesn’t match any file, Harp serves the 404.* contents with a 404 Not Found status code.
Example
The simplest case: drop a 404.html next to your other pages.
mysite/
|- 404.html
|- index.html
`- main.less
If you’d like the 404 page to share your site’s layout, use a compilable extension (.md, .ejs, or .jade) so it’s wrapped by _layout.*:
mysite/
|- _layout.ejs
|- 404.md
|- index.ejs
`- main.scss
The _layout file wraps both index.ejs and 404.md.
Cascading 404 files
404.* files cascade up the directory tree. When a request misses, Harp walks up from the request path, and at each directory level checks for a 200.* first and then a 404.*. The first match wins.
This means each section of your site can have its own 404 page:
mysite/
|- 404.html <-- top-level 404
|- index.html
`- shop/
|- 404.ejs <-- shop-specific 404
|- index.ejs
`- products/
`- widget.md
A request like /shop/missing-product matches shop/404.ejs (deeper directory wins). A request like /about (not present) walks up and is served the top-level 404.html. If neither file existed, Harp would fall back to a generic 404 response.
A
200.*and a404.*in the same directory: the200.*wins. If you’re routing a client-side app under/shop/with a200.ejs, your404.ejsin the same directory is unreachable.
Compile output
When you run harp <source> <build>, 404.* files are emitted as 404.html in the corresponding output directory. Most static hosts (Netlify, Vercel, GitHub Pages, Cloudflare Pages) recognize a top-level 404.html and use it for unmatched URLs automatically.