DEV Community

Cover image for Livewire: Custom error page done right
Robson Tenório
Robson Tenório

Posted on • Updated on

Livewire: Custom error page done right

When something goes wrong with Livewire you see a modal. As a developer you know you have to click outside to close it. Users don't!

In this example I have used components from MaryUI.

When you click a button that fires a 403 you see this modal.


public function delete()
{
   abort(403, 'You can`t do that ....');
}

Enter fullscreen mode Exit fullscreen mode

403

When you navigate to a page does not exist you see this full page.

http://localhost:8019/noooooooo
Enter fullscreen mode Exit fullscreen mode

404

1: Create an empty layout

File: views/components/layouts/empty.blade

<html>
<head>
    ...
</head>
<body class="[...] bg-base-200">
   {{ $slot }}
</body>
</html>

Enter fullscreen mode Exit fullscreen mode

2 : Create a error page

File: views/errors/error.blade.php

This will override default Laravel error page. Notice we rely on $isLivewire to decide what to do with buttons.

  • If it is a modal show close button.
  • If it is not a modal show reload button.

Same page works for a modal or full page errors.

<x-layouts.empty>
    <div class="flex">
        <div class="mx-auto text-center">
            <img src="/error.png" width="300" class="mx-auto" />

            <div class="text-xl font-bold">Oops!</div>
            <div class="text-lg mx-auto max-w-4xl">{{ $message }}</div>

            <div class="flex mt-10">
                <div class="mx-auto grid md:grid-cols-2 gap-3">

                    <x-button :label="$isLivewire ? 'Close' : 'Reload'"
                              :icon="$isLivewire ? 'o-x-mark' : 'o-arrow-path'"
                              :onclick="$isLivewire
                                        ? 'window.parent.document.getElementById(\'livewire-error\').remove()'
                                        : 'window.location.reload()'"
                              class="btn-primary" />

                    <x-button label="Home"
                              icon="o-home"
                              onclick="window.parent.location.href = '/'"
                              class="btn-outline" />
                </div>
            </div>
        </div>
    </div>
</x-layouts.empty>

Enter fullscreen mode Exit fullscreen mode

3: Exception Handler render()

File: app/Exceptions/Handler.php

This overrides Laravel error rendering. See more at https://laravel.com/docs/10.x/errors

When APP_ENV=local we display default Laravel error page. For any other value like production we display our custom error page describe above.

public function render($request, Throwable $e)
{
   // Uses native error page while developing
   if (app()->environment() == 'local') {
      return parent::render($request, $e);
   } 

   // Allow redirect if auth exception
   if ($e instanceof AuthenticationException) {
      return parent::render($request, $e);
   }


   $status = parent::render($request, $e)->getStatusCode();
   $isLivewire = $request->hasHeader('X-Livewire');

   // Call error page        
   return response()->view('errors.error', [
         'isLivewire' => $isLivewire,
         'message' => $e->getMessage()
      ], $status);
}

Enter fullscreen mode Exit fullscreen mode

Better!


public function delete()
{
   abort(403, 'You can`t do that ....');
}

Enter fullscreen mode Exit fullscreen mode

403

http://localhost:8019/noooooooo
Enter fullscreen mode Exit fullscreen mode

404

Can we do it better? Yes!

You probably want to have a default message error based on status here instead to use raw error message.

[...]
403 - Go away!
404 - I can't find this page.
500 - Something is wrong our side.
[...]

[
   ...
   'message' => $e->getMessage()
]
Enter fullscreen mode Exit fullscreen mode

Thank you!

Top comments (0)