As I begin my journey into Vue3, I would like to share my journey, what I am learning, in the hope this is something that may help you too. I am also open to suggestions to make any of my practices better. Afterall, there is no “one” solution to everything! Lets Dig In!
Making different reusable templates
When I starting building this project as a SaaS I knew it was going to have a public side that is used for primarily showing who the company is and selling the SaaS to potential customers. To achieve this, I amended the app.js
file that loads my application. The examples I am going to show is a modified version of Laravel Breeze out of the box version. My amended version gist can be seen here
First, we import what we would like to use as out template files for the various sections of our website.
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout.vue"
import GuestLayout from "@/Layouts/GuestLayout.vue";
As you can see, I have 2 layouts.
- One for Authenticated Users
- One for Guest Users (Unauthenticated)
Now I needed a way to ensure the correct layout displayed. Using Laravels middleware, we automatically put any authenticated views behind authentication, so this makes it a little easier. The way I did this was to determine where the view was coming from like so;
page.then (( module ) => {
if ( name.startsWith ('Guest/') ) {
module.default.layout = GuestLayout;
} else if ( name.startsWith ('Auth/') ) {
module.default.layout = AuthenticatedLayout;
}
});
As you see, I am checking the name of the file. If a file falls under the “Guest” Directory, it’ll show the GuestLayout, whereas if a user is logged in, all views will be coming from the “Auth” Directory.
So what does the reusable template look like?
Reusable templates should do the heavy lifting of all common objects on the page, and leave a Slot (or more) for your page content. See my “GuestTemplate” below.
<script setup>
import GuestFooter from "@/Components/Shared/GuestFooter.vue";
import PageHeading from '@/Pages/Guest/PageHeading.vue'
</script>
<template>
<PageHeading/>
<section>
<!-- Start Main Content Slot -->
<slot/>
<!-- End Main Content Slot -->
</section>
<GuestFooter/>
</template>
First, I import both my Guest Footer & Page Heading. These are the two common pieces on the ‘Guest’ facing part of my SaaS. I inject the PageHeading at the top which acts as the logo and menu container and then the GuestFooter at the bottom which has all the Legal Links required and contect information.
The <slot/>
you see in the middle is where Vue injects the loaded page. For example if I wanted to load a pricing page, All content will be loaded inside that slot.
What does it look like overall?
The final product is something like this. The “PageHeading” above loads the top navbar
and the “GuestFooter” you see, is at the bottom of the template file. When I reach out to my Guest/Pricing.vue
file, the file will inherit the template, and place the content in the slot creating a beautiful page.
Final Thoughts
If you reached this far, Thank you. Really. Without you, this is not possible. Writing this was a chance to gain good experience in writing a technically based blog. I am very new to creating my own VueJS SaaS (with Laravel/Inertia) and im learning more along the way. Watching and following a course is great, but there is nothing better than practicing in the wild. Should you have any feedback you can reach me on Twitter DMs or leave a comment for me to read.
Thank you.