inertia-laravel: Custom `rootView` and shared data set in middleware not taken into account for errors (eg. 404)

The new HandleInertiaRequests middleware exposes a rootView property, allowing to set a custom root view.

It works fine for regular Inertia::render in controllers, but doesn’t seem to be taken into account when returning custom error views, as the doc suggests.

In my case, this happens for a 404 error. I imagine Laravel handles such errors differently: the request might not go through the middleware stack.

I just realized that it wouldn’t send the shared data to the error page either, nor would it version.

Here’s a stack trace:

[2020-10-29 15:26:42] local.ERROR: View [app] not found. {"exception":"[object] (InvalidArgumentException(code: 0): View [app] not found. at /<project>/vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php:137)
[stacktrace]
#0 /<project>/vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php(79): Illuminate\\View\\FileViewFinder->findInPaths('app', Array)
#1 /<project>/vendor/laravel/framework/src/Illuminate/View/Factory.php(138): Illuminate\\View\\FileViewFinder->find('app')
#2 /<project>/vendor/laravel/framework/src/Illuminate/Routing/ResponseFactory.php(85): Illuminate\\View\\Factory->make('app', Array)
#3 /<project>/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): Illuminate\\Routing\\ResponseFactory->view('app', Array)
#4 /<project>/vendor/inertiajs/inertia-laravel/src/Response.php(93): Illuminate\\Support\\Facades\\Facade::__callStatic('view', Array)
#5 /<project>/app/Exceptions/Handler.php(51): Inertia\\Response->toResponse(Object(Illuminate\\Http\\Request))
#6 /<project>/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(416): App\\Exceptions\\Handler->render(Object(Illuminate\\Http\\Request), Object(InvalidArgumentException))
#7 /<project>/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(114): Illuminate\\Foundation\\Http\\Kernel->renderException(Object(Illuminate\\Http\\Request), Object(InvalidArgumentException))
#8 /<project>/public/index.php(70): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#9 /Users/<user>/.composer/vendor/laravel/valet/server.php(191): require('/Users/<user>/d...')
#10 {main}
"}

// app/Http/Middleware/HandleInertiaRequests.php

class HandleInertiaRequests extends Middleware
{
    protected $rootView = 'layouts.dashboard';

    // ...
}
// app/Exceptions/Handler.php

class Handler extends ExceptionHandler
{
    // ...

    public function render($request, Throwable $e)
    {
        $response = parent::render($request, $e);

        if (in_array($response->status(), [403, 404, 500, 503])) {
            return Inertia::render('public/Error', ['status' => $response->status()])
                ->toResponse($request)
                ->setStatusCode($response->status());
        }

        return $response;
    }
}

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 7
  • Comments: 29 (9 by maintainers)

Most upvoted comments

Welcome to 2022, Like to confirm that, i too face the same problem.

You’ve perfectly described my use case:

  • I have a custom layout, which isn’t app, hence the setRootView
  • That layout relies on some globals that are available everywhere else (the user being one of them)
  • The error page uses that layout, and still needs the user prop

That definitely needs to be supported, especially since it used to work perfectly fine.

I also ran into this problem recently. The only working solution i was able to find add is to add next two lines in custom Exception Handler before calling render:

Inertia::setRootView('my.custom.layout'); Inertia::share((new HandleInertiaRequests)->share($request));

I hope the issue will be solved soon…

Naive question, but can’t we just use app()->runningInConsole() to shunt the provider when necessary?

Probably!

Definitely, if we’re extending the ‘base’ service provider (like we’re doing with the ‘base’ middleware now), we can hide all of that logic within the Inertia package 👍

I do like @claudiodekker proposal. For that one error page be able to override the root element … done. I wouldnt know why anyone would like to share props to an error page

Because error pages might extend layouts, which might use certain shared props (e.g. the user) 😉

Welcome to 2022, Like to confirm that, i too face the same problem.

The following workaround also works for sharing data but it seems not very nice to “misuse” a middleware this way.

Code in Exception Handler:

Inertia::share((new HandleInertiaRequests)->share($request));

Currently facing the same issue, and would like to see this addressed as it has been discussed 3 years now and hasn’t been solved yet.

I have the same issue and am quite surprised this hasn’t been addressed yet.

Ran into the same issue, I think I also prefer moving the logic back to a service provider and bailing early in the console.