Implementing initial laravel-9.3.8 setup with vue3 using vite3

Vite is relatively new addition from laravel 9 onwards which servers an asset bundling tool in blazing fast manner. In this post, initial setup of vue js with vite will be shown step by step for smooth beginning of the project.

Step 01: Installing fresh laravel

composer create-project laravel/laravel vue3


Step 02: Renaming welcome.blade.php to app.blade.php and putting following html

<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel Vue initial setup </title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
        <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />
    </head>
<body>
<div class="app-body"> <main class="main"> <div style="padding-top: 20px" class="container"> <h1>This is h1 header </h1> </div> </main> </div> </body> </html>


Step 03:
Renaming welcome to app in routes/web.php

Route::get('/', function () {
    return view('app');
});


Step 04: Setting up vue component using following static html in resources/js/components/Issues/Index.vue 

<template>    
    <h1>Simple static text from vue component </h1>
<table class="table">
    <thead class="thead-dark">
      <tr>
        <th>Firstname</th>
        <th>Lastname</th>
        <th>Email</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>John</td>
        <td>Doe</td>
        <td>john@example.com</td>
      </tr>
      <tr>
        <td>Mary</td>
        <td>Moe</td>
        <td>mary@example.com</td>
      </tr>
      <tr>
        <td>July</td>
        <td>Dooley</td>
        <td>july@example.com</td>
      </tr>
    </tbody>
  </table>
  <table class="table">
    <thead class="thead-light">
      <tr>
        <th>Firstname</th>
        <th>Lastname</th>
        <th>Email</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>John</td>
        <td>Doe</td>
        <td>john@example.com</td>
      </tr>
      <tr>
        <td>Mary</td>
        <td>Moe</td>
        <td>mary@example.com</td>
      </tr>
      <tr>
        <td>July</td>
        <td>Dooley</td>
        <td>july@example.com</td>
      </tr>
    </tbody>
  </table>    
</template>

Step 05: Back in app.blade.php changing div inside main tag like below by putting id element "app"

<div style="padding-top: 20px" class="container" id="app">
    <h1>This is h1 header </h1>
</div>

Step 06: Adding blade directive for vite inside header section in app.blade.php

@vite(['resources/js/app.js', 'resources/css/app.css'])

Step 07: Installing Vite And The Laravel Plugin with npm

npm install

Step 08: Installing Vue3 with npm

npm install vue@3

Step 09: Installing vite plugin again with npm

npm i --save-dev --force @vitejs/plugin-vue

Step 10: in vite.config.js - importing vue and adding vue() with parameters after laravel config attribute inside plugin element and export default defineConfig({ });

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
        vue({ 
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),        
    ],
    resolve: {
        alias: {
            vue: 'vue/dist/vue.esm-bundler.js',
        },
    },    
});

Step 11: Joining all together by creating a Vue application in the resources/js/app.js

import './bootstrap';

import { createApp } from 'vue' 
import IssuesIndex from './components/Issues/Index.vue' 
 
createApp({}) 
    .component('IssuesIndex', IssuesIndex)
    .mount('#app') 


Step 12: Lastly, adding created vue component IssuesIndex inside app.blade.php like below with hypheneted syntax

<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel Vue initial setup </title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
        <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />
    </head>
<body>
<div class="app-body"> <main class="main"> <div style="padding-top: 20px" class="container" id="app"> <issues-index></issues-index> </div> </main> </div> </body> </html>

Step 13: Now, Starting the vite server

npm run dev


Step 14: Then, Running the site with the following command in browser with url https://localhost:8000/

php artisan serve


This will show in browser - "Simple static text from vue component" and a static table

Lastly, cool thing is when you update something in asset related files ( js, css, components ) vite will load the updated content automatically in the browser without refreshing the browser manually. Awesome!