Change InertiaJS-Laravel default RootView

Viewed 5730

I am using Laravel 8 and I have installed InertiaJS, but in my directory resources/views/ I have a single file called index.blade.php which I plan to use with InertiaJS.

By default, InertiaJS looks for a file inside that directory called app.blade.php. I know writing the following statement:

\Inertia\Inertia::setRootView('index');

Change the rootView and allow me to use the file I have created. It may seem like a stupid question, but as far as I see it, I can do 2 things ..

  • Rename file index.blade.php to app.blade.php
  • Write the previous sentence .. in one of the ServiceProviders that I have

I wonder the following:

  • InertiaJS-Laravel does not allow publishing a ServiceProvider with the command php artisan vendor:publish? (the output of this command does not show me anything to publish regarding this package)
  • To solve my problem I should create a ServiceProvider like: php artisan make:provider InertiaServiceProvider and then register it?
  • Or just add the previous statement to one of the ServiceProvider that already exist? Like in app/Http/Providers/RouteServiceProvider.php

What do you recommend that would be better?

I want to seek the largest possible organization in my project. Thank you very much in advance...

7 Answers

Update; after my initial answer (on 20-09-2020), Inertia introduced middleware to handle your Inertia requests.

As described in the answers below, you can use the command php artisan inertia:middleware to generate this middleware. You can set the root index with:

// Set root template via property
protected $rootView = 'app';

// OR
// Set root template via method
public function rootView(Request $request)
{
    return 'app';
}

You can find more info in the docs.

Even tighter, just override the rootView method in App\Http\Middleware\HandleInertiaRequests like this...

public function rootView(Request $request)
{
    if ($request->route()->getPrefix() == 'admin') {
       return 'layout.admin';
    }

    return parent::rootView($request);
}

You can do this inside your controller on the fly.

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Inertia\Inertia;

class NewsController extends Controller
{
    public function index()
    {
        Inertia::setRootView('layouts.news');
        $users = User::all();

        return Inertia::render('News/Index', compact('users'));
    }
}

Replace in the App\Http\Middleware\HandleInertiaRequests

protected $rootView = 'app';

with:

public function rootView(Request $request): string
{
    if ($request->route()->getPrefix() === '/admin') {
        return 'admin.app';
    }
    
    return 'app';
}

I think it would be easier to change it in App\Http\Middleware\HandleInertiaRequests.

Be sure to run php artisan inertia:middleware during inertia server-side installation. Also include it in your web middleware group.

Then go to App\Http\Middleware\HandleInertiaRequests and change the $rootView property to the name of the blade file you want to use. Example:

protected $rootView = 'index';

Extended @Olu Udeh answer

overwrite handle method of App\Http\Middleware\HandleInertiaRequests middleware

public function handle(Request $request, Closure $next)
{
    if($request->route()->getPrefix() == 'admin'){
        $this->rootView = 'layouts.admin';
    }

    return parent::handle($request, $next);
}

In laravel 8 this work for me

App\Http\Middleware\HandleInertiaRequests

Code

public function rootView(Request $request)
{
    if(request()->is('admin/*') or request()->is('admin'))
    {
        return 'admin';
    }

    return parent::rootView($request);
}
Related