# How to make a custom 404 page

> Replace the server's default error page with something useful, and avoid the two ways it goes wrong.

Source: https://cwp.sg/tutorials/custom-404-page/  
Author: Ben Johnson  
Last verified: 2026-09-21

**In short:** - Add `ErrorDocument 404 /404.html` to your `.htaccess` file to point Apache at your custom page. - Create a file called `404.html` in your site root with your own content and absolute paths for all assets. - Force a 404 status code by adding a rewrite rule: `RewriteRule ^404\.html$ - [L,R=404]`. - Test by visiting a non-existent URL and checking the Network tab in developer tools for a 404 response.

When a visitor hits a missing page on your site, they see the plain [404 error page](/errors/404-not-found/) that CWP's server generates. You can replace that with a page of your own. It takes two steps: one line of config, and one HTML file.

## The one line you need

Create or edit a file named `.htaccess` in the root folder of your site. Add this line:

```
ErrorDocument 404 /404.html
```

The path after `ErrorDocument` starts from your site root, not the current folder. If you write `404.html` without the leading slash, Apache looks for the file in whatever folder the broken URL requested. A visitor to `yoursite.com/nonexistent/page/` would make Apache look for `yoursite.com/nonexistent/page/404.html` and fail again. Always use a leading slash.

You can generate this line and others using the [htaccess generator](/tools/htaccess-generator/) if you prefer a form.

## The page itself

Create a file called `404.html` in the root of your site. It is a normal HTML page. A minimal version:

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Page not found</title>
    <link rel="stylesheet" href="/style.css">
</head>
<body>
    <h1>Page not found</h1>
    <p>The page you were looking for does not exist.</p>
    <p><a href="/">Go to the homepage</a></p>
</body>
</html>
```

### The status code trap

If your custom page returns a 200 OK status instead of 404, search engines treat it as a real page. Every mistyped URL on your site becomes a valid page with the same content. That is a duplicate content problem, and it can hurt your search ranking.

The server sends a 200 status by default for any HTML file that loads without error. You need to override that in the same `.htaccess` file. Add this line above the `ErrorDocument` line, or right after it:

```
RewriteEngine On
RewriteRule ^404\.html$ - [L,R=404]
```

This forces Apache to send a 404 status when it serves `404.html`. The page content is your custom version, but the status code tells crawlers and browsers that the original URL did not exist.

The order does not matter much here, but if you ever add more rewrite rules, keep the `ErrorDocument` line and the `RewriteRule` together so you do not forget one when you copy the config to a new site.

If the path in your `ErrorDocument` line is wrong or points to a file that does not exist, you get a [500 internal server error](/errors/500-internal-server-error/) instead of your custom page. The server cannot find the document it was told to use, so it crashes. Check the filename and the leading slash.

## Relative paths and broken assets

If your 404 page loads a stylesheet, an image, or a JavaScript file, the browser resolves the path relative to the URL in the address bar. A visitor at `yoursite.com/blog/some-old-post/` will look for `yoursite.com/blog/some-old-post/style.css`, not `/style.css`.

Always use absolute paths for everything in your 404 page. That means a leading slash on every `src` and `href`:

- `/style.css` not `style.css` or `../style.css`
- `/images/logo.png` not `images/logo.png`
- `/js/main.js` not `js/main.js`

The same rule applies to links inside your 404 page. A link to `contact.html` goes to `yoursite.com/blog/some-old-post/contact.html` and breaks. Use `/contact.html` instead.

## Multiple error pages in one go

You can handle other status codes the same way. The default [500 error page](/errors/500-internal-server-error/) is also plain. A common pattern is:

```
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /404.html
ErrorDocument 500 /errors/500.html
```

Create the HTML files, use absolute paths, and add a rewrite rule for each one that forces the correct status code.

If you host a static site, the [guide on static websites](/guides/how-to-host-a-website/static-website/) covers how to structure the rest of your files.

## Testing your custom 404

Visit a URL on your site that does not exist, such as `yoursite.com/test-404-please-ignore/`. If you see your custom page, it works. Check the browser's developer tools (Network tab) to confirm the response status is 404. If it is 200, you missed the rewrite rule. If you get a 500 error, the path in `ErrorDocument` is wrong or the file does not exist.

One practical detail: CWP's free hosting does not include backups. If you delete `404.html` by accident, the server falls back to its default 404 page. Keep a copy of your config and your custom page somewhere outside the account.

---

Content Website Platform (cwp.sg) operates the free hosting it writes about; see https://cwp.sg/about/ for the methodology and the commercial disclosure.
