Creating a project template using Laravel, Vue 3, and Tailwind - Part 1
Tags: laravel, vue, tailwindcss
Published: 2021-03-15 21:25:17

*This article was originally published at [projectrebel.io](https://projectrebel.io).*

## Creating a project template using Laravel, Vue 3, and Tailwind
  * Part 1 *<- you are here*
  * [Part 2](https://dev.to/heynolnor/creating-a-project-template-using-laravel-vue-3-and-tailwind-part-2-e1p)
  * [Part 3](https://dev.to/heynolnor/creating-a-project-template-using-laravel-vue-3-and-tailwind-part-3-1klj)
  * Part 4

Laravel has recently added a couple of cool new tech stacks to the ecosystem, [Livewire](https://laravel-livewire.com/) and [Inertia](https://inertiajs.com/). 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](https://laravel.com/) introduced the new stacks, I decided to take the plunge on [Vue](https://v3.vuejs.org/). 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
```
If you don't have the Laravel installer, check out the [docs](https://laravel.com/docs/8.x/installation#installation-via-composer) 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
```

Now that we have added Vue to our project, we'll create an instance and mount it to one of our blade templates.
```js
// resources/js/app.js
require("./bootstrap");

import { createApp } from "vue";

const app = createApp({});

app.mount("#app");
```
```html
// 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>
...
```

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.
```js
// 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', [
        //
    ]);
```

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
```

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`.
```html
// 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>
```
```js
// resources/js/app.js
require("./bootstrap");

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

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

app.mount("#app");
```
```html
// 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>
...
```

### Adding TailwindCSS for styling
For the fastest prototyping, [TailwindCSS](https://tailwindcss.com/) 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](https://projectrebel.io) as well as [several](https://vidhoarder.com) [others](https://rebelcinema.io). 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](https://tailwindcss.com/docs/configuration). We can install and get a basic setup with the following commands.
```
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npx tailwind init
```
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.
```js
// webpack.mix.js
...
mix.postCss('resources/css/app.css', 'public/css', [
        require('tailwindcss'),
    ]);
```
```css
// resources/css/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

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.
```html
// resources/views/welcome.blade.php
...
<head>
    ...
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    ...
</head>
...
```

Finally, let's make some updates to the styling of our `Home` component.
```html
// 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>
```

## 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](https://github.com/projectrebel/laravue3) for yourself. Next time, we'll add [Laravel Breeze](https://laravel.com/docs/8.x/starter-kits#laravel-breeze) for some simple authentication and set up our TDD workflow as well.