So I am working on a Laravel 8 app, with Inertia and Vue.
The idea is that most of the pages are Laravel + Blade (good for SEO, fast loading etc…), but for selected pages that need a lot of user interactions, I insert a Vue component in the Blade Template where the interactions need to happen.
With Inertia, this is done by calling the Vue component with return Inertia::render('vueComponent')
in the Controller that is called by the Laravel Route. Data can be passed to the Vue instance, and even to the Blade template, so this is good (see below).
namespace AppHttpControllers;
use InertiaInertia;
class RangePageController extends Controller
{
public function show(string $lang='fr')
{
// Strip the trailing slash from $lang
$lang = Str::before($lang, '/');
return Inertia::render('ProductsGallery', ['bar' => "Hello World"])->withViewData(['lang' => $lang]);
}
}
And by default, the file "/resources/views/app.blade.php" is rendered with the Vue component replacing the @inertia directive (plus some Vue Data). Neat.
By default, the Blade layout file "app.blade.php" is used. The doc specifies that the default can be changed: InertiaInertia::setRootView('name');
.
The Question: rather than changing the default, is there a way to choose different Blade layout files when calling different pages from the Controller (and inject the Vue component as above)? For instance I would like to use one Blade layout for my e-commerce basket, and a different one for my admin pages. Like choosing "app1.blade.php" for a page, and "app2.blade.php" for another.
Many thanks!
E.
3
Answers
Found a solution, for what it is worth.
AppHttpMiddleware
, extending theHandleInertiaRequest.php
middleware.protected $rootView
to point to the custom Blade layout file in/resources/views
.For instance
protected $rootView = 'admin.app';
, to point to/resources/views/admin/app.blade.php
, and the same for the 'web'app.blade.php
.Kernel.php
replicating the list in the "web" group, and I replace the defaultAppHttpMiddlewareHandleInertiaWebRequests::class
lines with the extended classes (in the "web" and the "admin" groups).resources/views/web/
.Probably some better solutions, but this one seems to work.
Note: I have seen a discussion on GitHub to do the same, but in addition to have 2 different Vue instances: one for "web", and one for "admin". Not sure what this brings, but I am still looking for a way to do it! If anybody has an idea...
You can change the root template of interia in middleware(HandleInertiaRequest.php) using property and also with method
Now filter the request in rootView() method and change the root template according to your need just using a simple if-else conditions.
Just a little bit update your HandleInertiaRequests
Also remove HandleInertiaRequests from global middleware and add it as named middleware
and now you can populate routes, routes groups as you need