Not Found

๐Ÿ‘จโ€๐Ÿ’ผ Right now if you go to a route that doesn't exist (like /does/not/exist), our root route's error boundary will handle that. Unfortunately, this error boundary is pretty limited because we can't rely on the root route's loader for any data. This makes our 404 page pretty useless.
To be clear, we do have a 404 page for notes and users that aren't found. So going to /users/does-not-exist works well. And also /users/kody/notes/does-not-exist works well too. We just want to do the same for routes that don't exist at all. Like /does-not-exist or /users/kody/does-not-exist.
So we're going to use a router feature called a "splat route" to handle this. A splat route effectively says "match any route that starts with this path". So we can create a splat route at the end of our router that matches any route that starts with / and because splat routes receive a lower priority than others, we'll know if the splat route gets rendered it's because no other route matched so we can show our 404 error.
It's important to note that splat routes aren't only useful for 404s, but they can be really handy for use with a CMS where the URL segments are dynamic.
As we're following the remix-flat-routes convention, to create a route that matches /*, ๐Ÿจ we'll create a file at .
With that file created, you need to ๐Ÿจ create a loader that throws a 404 response:
export async function loader() {
	throw new Response('Not found', { status: 404 })
}
Next, let's ๐Ÿจ export the ErrorBoundary:
import { Link, useLocation } from '@remix-run/react'
import { GeneralErrorBoundary } from '../components/error-boundary.tsx'

// ...

export function ErrorBoundary() {
	const location = useLocation()
	return (
		<GeneralErrorBoundary
			statusHandlers={{
				404: () => (
					<div className="flex flex-col gap-6">
						<div className="flex flex-col gap-3">
							<h1>We can't find this page:</h1>
							<pre className="text-body-lg whitespace-pre-wrap break-all">
								{location.pathname}
							</pre>
						</div>
						<Link to="/" className="text-body-md underline">
							Back to home
						</Link>
					</div>
				),
			}}
		/>
	)
}
Finally, we'll want to ๐Ÿจ export a default export just in case the loader is changed or fails in some way, we'll still be able to display some error to the user:
// ...

export default function NotFound() {
	// due to the loader, this component will never be rendered, but we'll return
	// the error boundary just in case.
	return <ErrorBoundary />
}

// ...
And with that, you should now be able to go to any route that doesn't exist and you should still see the header and footer. This will make it a much better user experience when folks hit a page that doesn't exist.

Access Denied

You must login or register for the workshop to view the diff.

Check out this video to see how the diff tab works.