Custom Vue 3 boilerplate - Vite, Pinia, Vue Router & Tailwind CSS
Tags: vue, tailwindcss, beginners, vite
Published: 2022-08-03 13:32:00

> ⚡**Update**: I've recreated **TypeScript** ready version of this boilerplate **[here](https://github.com/richardevcom/vue-ts-boilerplate)**.

_A while back I realized I'm trashing my beautiful workspace with quite a few repetitive Vue web apps. Shortly before backing them up to never be seen again, it clicked - why not repurpose those reusable parts and simply stack them in a boilerplate?_ 🤔

![Everything is a copy of a copy of a copy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u21qcd3ncvzlfe1qe5ge.gif)

I doubt that many _devs_ like staging same project and repeat same initial commands again and again, therefore in this article "slash" tutorial I will swiftly go over how does one stack and configure a boilerplate.

---

## Boilerplate stack
The stack of this boilerplate is focused on web app front end, therefore I'll keep it simple and use following packages:

- **[Vite](https://vitejs.dev)** - dev tool for building and serving
- **[Pinia](https://pinia.vuejs.org)** - for storing
- **[Vue Router](https://router.vuejs.org)** - for dynamic routing
- **[Tailwind CSS](https://tailwindcss.com)** - for looks
- **[Vite SVG loader](https://github.com/jpkleemans/vite-svg-loader)** (_optional_) - to easily import SVGs


## Prerequisite
Before we start, I'm assuming you're somewhat acquainted with command line and have **Node.js** installed. If not - download it [here](https://nodejs.org/en/download). To check if it's installed, simply run `node -v command`.


## Quickstart - Vue, Router & Store
Let's begin by initializing our boilerplate project.

```
npm init vue@latest
```
Now enter the project name. I'll be using `vue3-boilerplate`. On feature prompt choose to install **Pinia** and **Vue Router**.

```
✔ Project name: vue3-boilerplate
...
✔ Add Vue Router for Single Page Application development? Yes
✔ Add Pinia for state management? Yes
```
It's time to move into our project folder, install packages and run our boilerplate in development environment.
```
cd vue3-boilerplate
npm install
npm run dev
```
You should be seeing on your local development environment [`http://127.0.0.1:5173`](http://127.0.0.1:5173) this example page:

![Vue.js Home Page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/615t0jnezzho66omlamx.png)

_You can learn more about building or serving your app in this guide. Oh, and read more about **Pinia** [here](https://pinia.vuejs.org/introduction.html#comparison-with-vuex). It is very similar to **Vuex**._


## Add Tailwind CSS
👏 Great, we got our base, now we need the looks. Following [this guide](https://tailwindcss.com/docs/guides/vite) we are installing Tailwind CSS, its dependencies and then initializing configuration file.

```
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```
In your project root you'll now find `tailwind.config.js` file - let's open it and add our template paths:

```
module.exports = {
   content: [
      "./index.html",
      "./src/**/*.{vue,js,ts,jsx,tsx}",
   ],
   ...
}
```
Next we will need to load `@tailwind` directives, so let's create `tailwind.css` in our `/src/assets` folder with following directives:

```
@tailwind base;
@tailwind components;
@tailwind utilities;
```
Now let's load this CSS file by importing it in the very top of `/src/assets/main.css` file:

```
@import "./tailwind.css";
...
```
_Since we already import `/src/assets/main.css` file in `/src/main.js`, we are good to use **Tailwind**'s utility classes in our project._
Let's test it out by adding some classes inside `/src/views/AboutView.vue` in `<h1>` tag:

```
<template>
   <div class="about">
      <h1 class="text-xl font-medium text-white">This is an about page</h1>
   </div>
</template>
```
_We can also define our CSS properties separately below. To do so, we will need to install **SASS** package and **PostCSS** plugin - `sass` & `postcss-import`:_

```
npm i -D sass postcss-import
```
Now let's use `@apply` with our utility classes:

```
<template>
   ...
   <h1>This is an about page</h1>
   ...
</template>
<style lang="scss">
   .about {
      @apply lg:min-h-screen lg:flex lg:items-center;

      h1 {
         @apply text-xl font-medium text-white;
      }
   }
</style>
```
🎉 Awesome! We have our core and we have our looks. What else could we add? 🤔


## Add SVG loader (optional)
_I like my SVG like I like my app - Component-Driven.🥁 It just so happens that our newly stacked boilerplate can easily import SVG imagery, but there is a catch - you'll have to use it as component, meaning you'll manually have to add SVG code within template tags and import it like that._

Luckily there is this **[`vite-svg-loader`](https://www.npmjs.com/package/vite-svg-loader)** package that basically allows you to simply import your `.svg` files within Vue template as components. Let's proceed by adding it to our boilerplate:

```
npm install vite-svg-loader --save-dev
```
Now add this plugin in our `vite.config.js` configuration file:

```
...
import svgLoader from 'vite-svg-loader'
export default defineConfig({
   plugins: [vue(), svgLoader()],
   ...
})
```
Lastly, to test it out I'm going to change that **Vue.js** logo code to **Vite.js** in `/src/assets/logo.svg` to this one and save it:

```
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2454.32 2457.41"><defs><linearGradient id="a" x1="285.11" y1="1790.44" x2="285.7" y2="1789.74" gradientTransform="matrix(2454.32, 0, 0, -2187.24, -699180.9, 3916163.49)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#41d1ff"/><stop offset="1" stop-color="#bd34fe"/></linearGradient><linearGradient id="b" x1="285.22" y1="1790.33" x2="285.29" y2="1789.46" gradientTransform="matrix(1125.42, 0, 0, -2051.66, -319596.68, 3673197.31)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ffea83"/><stop offset="0.08" stop-color="#ffdd35"/><stop offset="1" stop-color="#ffa800"/></linearGradient></defs><path d="M2464.14,381.6,1311.22,2443.21c-23.8,42.57-85,42.82-109.12.46L26.33,381.79C0,335.63,39.47,279.72,91.78,289.08L1245.93,495.37a62.88,62.88,0,0,0,22.27,0l1130-206C2450.35,279.87,2490,335.35,2464.14,381.6Z" transform="translate(-17.94 -17.87)" style="fill:url(#a)"/><path d="M1795.71,18.48,942.53,185.66a31.33,31.33,0,0,0-25.25,28.9L864.8,1101a31.33,31.33,0,0,0,29.41,33.14,31.77,31.77,0,0,0,8.91-.75l237.54-54.82a31.32,31.32,0,0,1,37.73,36.79l-70.57,345.59a31.33,31.33,0,0,0,39.8,36.24l146.72-44.57a31.34,31.34,0,0,1,39.79,36.32L1222,2031.73c-7,33.95,38.14,52.47,57,23.36l12.59-19.44L1986.77,648.19c11.65-23.23-8.44-49.72-33.94-44.79l-244.52,47.18a31.33,31.33,0,0,1-36-39.44L1831.86,57.91a31.34,31.34,0,0,0-36.14-39.43Z" transform="translate(-17.94 -17.87)" style="fill:url(#b)"/></svg>
```
Then in `/src/App.vue` file I'll import it as SVG component and replace it with `<img class="logo" />`.

```
<script setup>
   ...
   import LogoSVG from './assets/logo.svg?component'
</script>
<template>
   ...
   <LogoSVG alt="Vite logo" class="logo" />
   ...
</template>
```


## 🎉Congratulations!
You are a proud owner of your very own boilerplate. 👏

![Yes! Napoleon Dynamite](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nk0eswklfity1t5av9zz.gif)

---

## What's next?
You would now want to create an easily _pull-able_ starter kit - for example, in **Github **- so your boilerplate is always one command away. I actually did just that - you can pull my version of boilerplate [here](https://github.com/richardevcom/vue3-boilerplate) or simply pull it:

```
npm i @richardev/vue3-boilerplate
```
Finally, I want to share this list of some useful **Vue.js** related packages to add to your boilerplate:
**[NuxtJS](https://nuxtjs.org)** - Vue.js Framework
**[Vue Meta](https://vue-meta.nuxtjs.org)** - for Web App SEO
**[VeeValidate](https://vee-validate.logaretm.com/v4)** - form validation
**[Vue Toastification](https://vue-toastification.maronato.dev)** - alerts a.k. toasts

_If you have ideas on what to add or remove in this boilerplate, tips on configuring it or you simply have an issue setting it up - I'll appreciate if you reach out in the comments below. 👋_

> ⚡**Update**: I've recreated **TypeScript** ready version of this boilerplate **[here](https://github.com/richardevcom/vue-ts-boilerplate)**.