Custom Nova 4 Error Pages
Have you been asked to make a custom error page for Laravel Nova 4 and had a hard time and want to cry?
Me too, but not anymore.
As of 2023, the way of doing this is creating custom assets and registering them. https://github.com/laravel/nova-issues/discussions/5809
Here are the steps:
- Make a custom asset.
- In the asset, register your custom component.
- Create the custom component.
- Build the asset.
First, make a custom asset. https://nova.laravel.com/docs/customization/assets.html
Make sure you use your company or organization name.
php artisan nova:asset your-company/nova-error-pages
This will ask you to update composer, install npm dependencies, and compile dependencies. You should say yes to everything.
When you are done this step, you should have a new asset in ./nova-components
and your composer.json
should be updated.
Okay. Now you have a custom asset. It’s its own little thing that lives in ./nova-components/NovaErrorPages/
. It has its own composer.json
and package.json
. You are doing great.
The asset should look like this.
composer.json
dist
node_modules
nova.mix.js
package-lock.json
package.json
postcss.config.js
resources
src
webpack.mix.js
Now, find ./nova-components/NovaErrorPages/resources/js/asset.js
. This is where you’ll register your new component.
You need to make asset.js
look exactly like this:
import NovaErrorPages from "./components/NovaErrorPages"
// We override the existing Nova Error Pages.
// https://github.com/laravel/nova-issues/discussions/5809
Nova.booting((app) => {
app.component("CustomError403", {
extends: NovaErrorPages,
props: {
status: {
type: String,
default: "403",
},
},
})
app.component("CustomError404", {
extends: NovaErrorPages,
props: {
status: {
type: String,
default: "404",
},
},
})
app.component("CustomAppError", {
extends: NovaErrorPages,
props: {
status: {
type: String,
default: "500",
},
},
})
})
What we did was register our new component (we haven’t made that yet) in Nova. It replaces the existing CustomError404
and friends. You can find them in ./vendor/laravel/nova/resources/js/views/CustomError404.vue
.
Ok, next we need to actually make the component, right?
Create a file at ./nova-components/NovaErrorPages/resources/js/components/NovaErrorPages.vue
.
Copy in this code.
<template>
<!-- We have copied this from the existing Nova Error Page Views, and modified it. -->
<div class="flex justify-center h-screen">
<div
class="z-50 flex items-center justify-center p-6"
:dusk="`${status}-error-page`"
>
<span class="shrink-0 md:w-[20rem]" v-html="logo"></span>
<div
class="flex flex-col md:flex-row justify-center items-center space-y-4 md:space-y-0 md:space-x-20"
role="alert"
>
<div class="md:w-[20rem] md:shrink-0 space-y-2 md:space-y-4">
<Head title="Page Not Found" />
<h1 class="text-[5rem] md:text-[4rem] font-normal leading-none">
{{ status }}
</h1>
<p class="text-lg leading-normal">
<span v-if="status === '403'">{{ __("Access denied") }}</span>
<span v-else-if="status === '404'">{{ __("Page not found") }}</span>
<span v-else="status === '500'">{{ __("Unexpected error") }}</span>
</p>
<Link
:href="$url('/')"
class="inline-flex items-center focus:outline-none focus:ring rounded border-2 border-primary-300 dark:border-gray-500 hover:border-primary-500 active:border-primary-400 dark:hover:border-gray-400 dark:active:border-gray-300 bg-white dark:bg-transparent text-primary-500 dark:text-gray-400 px-3 py-2 h-9 font-bold tracking-wide uppercase"
tabindex="0"
replace
>
{{ __("Go Home") }}
</Link>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
computed: {
logo() {
return window.Nova.config("logo")
},
},
}
</script>
That will give you a template that uses your company’s logo if defined. __("Page not found")
is a translation I added to Nova’s translations. Let’s do that now.
Add this to ./resources/lang/vendor/nova/en.json
"Page not found": "Page not found",
"Access denied": "Access denied",
"Unexpected error": "Unexpected error"
Okay. Great. Pretty much done.
Finally, build your component. From your project root, run npm run build-nova-error-pages-prod
.
That should be it. Cause a 404
and see if it worked.
If you are having trouble, reach out!