Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

DavidSpooner's avatar

Incremental Implementation of Inertia/Vue

Vue brags that it is "incrementally adoptable". I also found this post from Adam Wathan which says:

"Just deployed our first Inertia page in the Tailwind UI codebase!

Really nice to be able to do this incrementally — converting the whole app and then trying to do a giant 
merge/deploy would be a nightmare, but with Inertia it's easy to convert one page at a time."

https://twitter.com/adamwathan/status/1521579621426282501?lang=en

Besides those, I can't seem to find a single other mention in any documentation or tutorial about what would be a good way to approach an incremental adoption of Inertia/Vue. Does anyone know of a tutorial or piece of documentation that addresses this?

Details of my situation:

My Laravel app has a Home Controller which returns a view at resources/views/home.blade.php and that just extends an app.blade.php layout file which is located at resources/views/layouts/app.blade.php. Walking through the inertia documentation, it seemed apparent that I needed to add the @inertia directive to resources/views/layouts/app.blade.php, but when I tried to do that, no $page variable (which is required by @intertia) was getting passed to that view. One question I am trying to answer is where that $page variable is supposed to get passed from. I have looked at the HandleInertiaRequests.php middleware and don't see any obvious indication that it is getting passed from there.

I am currently considering whether this issue is due to app.blade.php not being located in the root of the view directory, since that is the default set up for Inertia/Vue in Laravel. However, my home controller still expects a home.blade.php and, in some way, I need to continue loading my old layout but then somehow add inertia to it. I can add a new app.blade.php to the root of the view directory as sort of a second root layout file for the app, but then how would my app know when to load which root layout? And can that even work, considering (among other things)that I am using Vite and the @vite directive to load dependencies in both root layout files?

0 likes
6 replies
martinbean's avatar

@davidspooner Well I guess the case would be converting one page to Inertia, rather than trying to convert an entire app in one go.

Pick a page. Convert it to return an Inertia view instead of your original Blade view. Rinse and repeat.

1 like
DavidSpooner's avatar

@martinbean Thanks for the reply.

Don't I first need to add a "root DOM node" to the app before I can render any Vue page?

What I want to do is exactly what you said, which is build one page at a time. In order to do that, I think I would need to figure out some way to get the @inertia directive to live next to the @yield(content) directive in my root layout, wouldn't I?

As I understand it the @inertia directive renders something like:

<div id="app" data-page="{ json_encode($page) }}"></div>

and that root node is necessary to render any page via Inertia/Vue. Is that not correct?

martinbean's avatar

@DavidSpooner You would probably have two layouts: one for your Blade views, and then one for the Inertia views. You could extend a common layout to reduce repetition:

<!-- resources/views/layout.blade.php -->
<!DOCTYPE html>
<html>
    <head>
        <!-- meta, title, etc. -->
        @stack('head.end')
    </head>
    <body>
        @yield('content')
    </body>
</html>
<!-- resources/views/layout-inertia.blade.php -->
@extends('layout')

@push('head.end')
    @inertiaHead
@endpush

@section('content')
    @inertia
@endsection

Then set Inertia views to use your new Inertia layout using Inertia::setRootView() as per the docs (https://inertiajs.com/server-side-setup#root-template).

3 likes
DavidSpooner's avatar
DavidSpooner
OP
Best Answer
Level 6

I think I finally got this figured out.

1. The issue with the $page variable not getting passed in.

My initial attempt to incorporate Inertia/Vue into my root layout at resources/views/layouts/app.blade.php looked something like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Scripts -->
    @vite(['resources/assets/sass/app.scss', 'resources/assets/js/app.js'])

    @inertiaHead

</head>
<body>

    @include('layouts.header')

    <div class="container-fluid" id="app">
        <div class="row" id="body">
            <div class="content-wrapper main-content clear-fix container-fluid">

                @yield('content')
    
                @inertia

            </div>
        </div>
    </div>
</body>
</html>

I arrived at that setup after following along with the Inertia docs at https://inertiajs.com/server-side-setup. At that point, if I tried to load any of my existing routes, I got a "Undefined variable $page" error in the browser originating from the @inertia directive. My question then, was "Where is that $page variable supposed to get passed in from?"

A better question might have been, "When is that $page variable supposed to get passed in?" After doing the client side setup, creating the views/js/Pages/Welcome.vue, and creating a route to load the new component (with Inertia), I discovered that I do not get the "Undefined variable" error when loading that route. So the $page variable only gets passed in when we are loading an Inertia route. Otherwise, it is not passed in and we get the error. The simple solution is to wrap the directives in a check for the @page variable:

  @if(!empty($page))
        @inertiaHead
    @endif

 @if(!empty($page))
     @inertia
 @endif

2. Is it possible to use multiple root layouts (i.e. One app.blade.php for Inertia/Vue and perhaps an app2.blade.php for the older Blade-based content)

The short answer here seems to be Yes. I was concerned about how the app would know when to use which layout. The obvious answer here is "Routing". Smh... hahaha. Yes, I think I forgot that Routing in Laravel existed for like a whole day. When we create routes for our new Inertia/Vue pages, we simply load the correct base layout. So far, I haven't noted any issue with using the @vite directive in both layouts.

So there are at least two approaches here. I haven't yet decided which I will use, or if maybe some combination of them makes sense. I am still interested in what people think would be a "best practice" approach to this if anyone else wants to chime in.

Sinnbeck's avatar

@DavidSpooner I would go with two different layout files. Keep them completely separate. Martin already wrote how to do so.

1 like

Please or to participate in this conversation.