❄️ The winter sale is here. 25% off for a limited time. Join us →

Inertia
Using different app layouts in one Inertia app
17
859
Solved

whoami (Daryl)

Started this discussion 2 months ago

Hey everyone,

Have you guys tried using different app layouts in one Inertia + Vue app?

Let's say, for the back office (admin) we'll use admin.blade.php instead of the default app.blade.php

And for the front side e.g. e-commerce, we'll use the default app.blade.php

I need to do this because I'm using a template, the front-side UI is different from the back office (admin).

Haz

Replied 2 months ago

Hello,

I would only have one app.blade.php file. Then with Vue, create multiple layouts.

AppLayout.vue:

<template>
	<h1>User area</h1>

    <slot />
</template>

Dashboard.vue:

<template>
	<AppLayout>
		<h1>Dashboard</h1>
	</AppLayout>
</template>

AdminLayout.vue:

<template>
	<div>Admin area</div>

    <slot />
</template>

Users.vue:

<template>
	<AdminLayout>
		<h1>Users</h1>
	</AdminLayout>
</template>

See also:

Creating layouts

Persistent layouts

Default layouts

alex

Replied 2 months ago

Yep, this is the best approach for multiple layouts.

Multiple base template files will cause a headache down the line unless you have incredibly separated applications :)

whoami (Daryl)

Replied 2 months ago

Hey @alex

Thanks for your response, my concern with it is that I'm not able to use different CSS files.

E.g. In my admin.blade.php, I will put the CSS files included with the back office template.

And in my app.blade.php, I will put the CSS files included in the e-commerce template.

whoami (Daryl)

Replied 2 months ago

Thanks @Haz

Haz

Replied 2 months ago

Put them in app.blade.php or AdminLayout.vue.

There's nothing stopping you from adding link and script tags.

You have a couple of choices here:

useScriptTag

AdminLayout.vue:

<script setup>
	useScript(...)
</script>

<template>
	<link rel="..." href="...">
	
	<slot />
</template>

I think you could also just do this:

<script setup>
	//
</script>

<template>
	<head>
		<link rel="..." href="...">

		<script src="..."></script>
	</head>

	<slot />
</template>

Remember, it's just a layout. I hope this helps.

whoami (Daryl)

Replied 2 months ago

Hey, I'll try this. But I think this will not behave like the way we load assets in our blade files through @vite?

Haz

Replied 2 months ago

Hello,

I'm not sure. Are these CDNs and precompiled assets? It's hard to comment without knowing more context.

whoami (Daryl)

Replied 2 months ago

Sorry, let's take this css file as an example for the admin design.

Ideally, we place this inside resources/css and then import it in our app.js.

// app.js
import "../css/styles.css";
// vite.config.js
...
    laravel({
      input: ["resources/js/app.js"],
      refresh: true,
    }),

Finally, in app.blade.php

@vite('resources/js/app.js')

While writing this, I realized I need multiple app.js too, separate for each UI (admin, e-commerce). I'm confused right now. 😅

Haz

Replied 2 months ago

Hello,

I think you are overcomplicating it.

Remove the following line (and any other lines that are specific to a layout) from your app.js file and app.css file. Shared assets can remain.

import "../css/styles.css";

AdminLayout.vue:

<template>
	<head>
		<!-- make sure the path is correct -->
		<link rel="stylesheet" href="../css/styles.css">
	</head>

	<slot />
</template>

Let's say you have a users page under your admin area for example...

Users.vue:

<template>
	<AdminLayout>
		<h1>Users</h1>
	</AdminLayout>
</template>

See my post above regarding script tags.

You are still going to use Vite to bundle assets, providing that you aren't using SB Admin Pro dist assets.

I was going to create an example repo for you, but SB Pro Admin is a paid product. If you share what assets you need to load, I can provide further assistance.

whoami (Daryl)

Replied 2 months ago

Hey, Haz,

You're right, I'm over complicating it, sorry about that, I'm new with this Inertia setup.

Let me try your approach, thank you.

If you still wanna create an example repo, you can use this free SB admin.

whoami (Daryl)

Replied 2 months ago

Just an update, I tried this one.

AdminLayout.vue:

<template>
	<head>
		<!-- make sure the path is correct -->
		<link rel="stylesheet" href="../css/styles.css">
	</head>

	<slot />
</template>

It is working but the styles.css is not included when I run npm run build, that's because I link it directly.

Also, I found this thread. I'm not sure if it's a good workaround.

public function rootView(Request $request): string
{
    if ($request->routeIs('admin.*')) {
        return 'layouts.admin';
    }

    return $this->rootView;
}

Haz

Replied 2 months ago

Hey,

Crazy weekend here. Will get back you sometime tomorrow. I’ll update this post.

whoami (Daryl)

Replied 2 months ago

Hey, Haz,

Thank you.

Best answer

Haz

Replied 2 months ago

Hello,

I have been playing around with this. I honestly don't think you need that workaround solution.

The following should be enough:

<Head>
<link>
<style>
<script>
useScriptTag

It is working but the styles.css is not included when I run npm run build, that's because I link it directly.

You need to instruct Vite to build it.

vite.config.js:

        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
                'resources/css/custom.css',
                'resources/js/custom.js',
                'resources/css/admin.css',
                'resources/js/admin.js',
            ],
            refresh: true,
        }),

I made a simple app to test it all out. You can find the repo here. Check the routes to follow along.

If you still wanna create an example repo, you can use this free SB admin.

I checked it.

It seems that you have all of the files locally, so the approach taken in the example app above is pretty much the same. One key difference is that SB Admin uses Sass, so you will need to install a Sass plugin if you want to heavily customise it. Luckily Vite has you covered:

CSS Pre-processors

I think I have given you all the information that you need to take over. Let me know if you need anything else.

I hope this helps.

Note: You will notice that there aren't any dedicated layouts here, but the logic in each page can be easily moved. I was just demonstrating how you can separate assets and build them.

whoami (Daryl)

Replied 2 months ago

Hey, Haz,

Sorry for the late reply, appreciate your effort in this.

Haz

Replied 2 months ago

Helllo @whoami,

I wanted to check if your issue was solved. I saw you marked the best answer, but want to make sure it's actually working.

whoami (Daryl)

Replied 2 months ago

Hey, Haz,

Thanks for checking out. Yeah, it works.

I also use the VueUse's useScriptTag for some scripts.

Thanks again!