DEV Community

Cover image for Creating a project template using Laravel, Vue 3, and Tailwind - Part 1
Nolan Nordlund
Nolan Nordlund

Posted on • Updated on

Creating a project template using Laravel, Vue 3, and Tailwind - Part 1

This article was originally published at projectrebel.io.

Creating a project template using Laravel, Vue 3, and Tailwind

Laravel has recently added a couple of cool new tech stacks to the ecosystem, Livewire and Inertia. Both have a lot of potential and can be great next steps for people looking to get some more interactivity in their Laravel projects but who may feel that a full-fledged JS framework is daunting. About a year before Laravel introduced the new stacks, I decided to take the plunge on Vue. Even with great options like Livewire and Inertia, I would highly recommend a Vue deep dive.

Since learning Vue, I have found myself doing lots of tinkering on fun weekend ideas. Often a new idea means a fresh install and rather than spending all of my tinkering time installing packages and setting up build processes, I decided my next tinkering project would be a series of Laravel + Vue 3 templates. For the most basic of ideas, all I really want is Laravel with Vue integrated. Often times I'm using a project like this to test a new technique or package rather than actually work on an app idea. If I want to rapidly prototype a simple app and I'm not too concerned about the UX of the project, I'll add a simple authentication system and testing tools. And finally, for the projects that I think might actually turn into something useful, I like to set up a SPA.

I'll show you how I put each of my project templates together and you'll find links to the Github repos if you would rather just download it and get started with one of your own creations.

Setting up a basic project template

The goal here is to have something that I can clone and immediately have access to some of the basic tools that I want in all of my projects. Again, the uses for this basic template are just experimenting with new techniques or packages so my needs are pretty low.

Installing Laravel

Let's start with a fresh install of Laravel. If you have the installer, it is incredibly simple.

laravel new template
Enter fullscreen mode Exit fullscreen mode

If you don't have the Laravel installer, check out the docs to get started.

Integrating Vue 3

While Vue 3 was officially released back in September of 2020, it still needs to be installed using the next tag.

npm install vue@next
Enter fullscreen mode Exit fullscreen mode

Now that we have added Vue to our project, we'll create an instance and mount it to one of our blade templates.

// resources/js/app.js
require("./bootstrap");

import { createApp } from "vue";

const app = createApp({});

app.mount("#app");
Enter fullscreen mode Exit fullscreen mode
// resources/views/welcome.blade.php
...
<body>
    <div id="app" class="flex items-center bg-gray-100 min-h-screen">

    </div>
    <script src="{{ asset('js/app.js') }}"></script>
</body>
...
Enter fullscreen mode Exit fullscreen mode

We'll need to also update our JS build process to correctly process our Vue 3 files. I prefer using BrowserSync when I'm developing and Laravel Mix makes it simple to add. We'll make use of the APP_URL setting in the .env file.

// webpack.mix.js
const mix = require('laravel-mix');

mix.browserSync({
    proxy: process.env.APP_URL,
    notify: false
});
mix.js('resources/js/app.js', 'public/js').vue();
mix.postCss('resources/css/app.css', 'public/css', [
        //
    ]);
Enter fullscreen mode Exit fullscreen mode

Run the build and we'll have a functioning Vue instance but we won't see anything just yet. Mix will likely also install some extra packages and need to run a second time.

npm install && npm run dev
Enter fullscreen mode Exit fullscreen mode

Next we'll add a simple component so we have something to display. Create a new folder for components in resources/js and then we'll create our simple component, Home.vue.

// resources/js/components/Home.vue
<template>
    <div>
        <h1>
            Basic template
        </h1>
        <p>
            Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ad, expedita? Officiis autem, omnis hic similique facere tempora culpa animi quisquam commodi illum sapiente error fugiat? Nobis, architecto? Sapiente, laborum sint!    
        </p>
    </div>
</template>

<script>
export default {};
</script>
Enter fullscreen mode Exit fullscreen mode
// resources/js/app.js
require("./bootstrap");

import { createApp } from "vue";
import Home from "./components/Home.vue";

const app = createApp({
  components: {
    Home
  }
});

app.mount("#app");
Enter fullscreen mode Exit fullscreen mode
// resources/views/welcome.blade.php
...
<body>
    <div id="app" class="flex items-center bg-gray-100 min-h-screen">
        <home />
    </div>
    <script src="{{ asset('js/app.js') }}"></script>
</body>
...
Enter fullscreen mode Exit fullscreen mode

Adding TailwindCSS for styling

For the fastest prototyping, TailwindCSS is an excellent choice to style our views. It is a utility framework that might feel wrong if you strive to minimize the number of classes you use in your HTML. If you try it, I'm sure you'll love it. It is what I used to build my site as well as several others. As a developer with mostly backend experience, Tailwind really helped to demystify all things CSS.

One of Tailwind's most powerful features is the advanced configuration and theme customization. We can install and get a basic setup with the following commands.

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npx tailwind init
Enter fullscreen mode Exit fullscreen mode

You'll have a tailwind.config.js file in the root of your project for you to customize tailwind to your heart's content. One more update for webpack and we'll add the Tailwind styling to our app.css file.

// webpack.mix.js
...
mix.postCss('resources/css/app.css', 'public/css', [
        require('tailwindcss'),
    ]);
Enter fullscreen mode Exit fullscreen mode
// resources/css/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

The welcome view comes with some styles defined directly inside of style tags within the head of the view. Remove the styles and replace them with a link to our app.css file.

// resources/views/welcome.blade.php
...
<head>
    ...
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    ...
</head>
...
Enter fullscreen mode Exit fullscreen mode

Finally, let's make some updates to the styling of our Home component.

// resources/js/components/Home.vue
<template>
    <div class="w-1/2 bg-white rounded-lg shadow-lg mx-auto p-4">
        <h1 class="text-2xl text-gray-700 text-center mb-4">
            Home component
        </h1>
        <p>
            Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ad, expedita? Officiis autem, omnis hic similique facere tempora culpa animi quisquam commodi illum sapiente error fugiat? Nobis, architecto? Sapiente, laborum sint!
        </p>
    </div>
</template>

<script>
export default {};
</script>
Enter fullscreen mode Exit fullscreen mode

Conclusion and next steps

Overall, pretty simple but it is nice to save the steps every time we want to do some experimenting. You can grab the source from Github for yourself. Next time, we'll add Laravel Breeze for some simple authentication and set up our TDD workflow as well.

Top comments (10)

Collapse
 
bignonotation profile image
Bastiaan • Edited

Hi! Great part 1!
Took me a while to figure out, but as the tailwindCSS docs state, you also have to update your tailwind.config.js after the init for v3.0, see: tailwindcss.com/docs/guides/laravel

Collapse
 
bjwlf profile image
Bunyamin Kurt

great post. thanks.

Collapse
 
heynolnor profile image
Nolan Nordlund

Glad you liked it

Collapse
 
szabeh profile image
Mohammad sadegh Zabeh Jamshidi

Please, Edit parts link.

Collapse
 
heynolnor profile image
Nolan Nordlund

Links are updated. I haven't released part 4 yet and I'm not sure when I'll get to it.

Collapse
 
beaumontyun profile image
beaumontyun

Amazing post. Had a bit trouble connecting to a local environment using browser-sync but I resolved it with Laravel valet and changed the env APP_URL to a valet URL, then it worked.

Collapse
 
harriskhalil profile image
risbot

Hi is there a way to use vuex in it ?

Collapse
 
yuber83 profile image
yuber83

muchas gracias, me sirvio de mucho

Collapse
 
szabeh profile image
Mohammad sadegh Zabeh Jamshidi

Thanks. Great.

Collapse
 
kaii profile image
Leo

Muchas gracias por publicar esto!!