Step-by-Step Guide to Use Global Vue Components with Laravel Blade templates and Vite
In this article, you will find a detailed guide on how to perform a clean installation of Vue 3 and Bootstrap 5 in a new Laravel 10 project. Additionally, you will utilize Vite to build the frontend assets.
This setup enables you to use Vue components registered globally in Blade templates as standalone components across the application.

Laravel provide all of the features you need to build modern web applications using Inertia.js or Livewire by leveraging Vue JavaScript framework.
They can be a better choices if you are working on a small to medium-sized project, since Inertia.js and Livewire provide a seamless experience between your Vue.js frontend and Laravel backend but they are designed to be used with Laravel specifically.
If you are working on a large and complex project, you will prefer avoiding the use of that kind of bridges to have more control over the frontend, and isolate it from the backend.
Create a fresh Laravel project:
composer create-project laravel/laravel laravel-vue-app
Change the working directory:
cd laravel-vue-app
Install node development dependencies:
npm install --save-dev \
vue \
bootstrap \
bootstrap-icons \
@popperjs/core
@vitejs/plugin-vue
The package.json will be updated as follow:
package.json (before)
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.7.2",
"vite": "^4.0.0"
}
}
package.json (after)
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"@popperjs/core": "^2.11.6",
"@vitejs/plugin-vue": "^4.0.0",
"axios": "^1.1.2",
"bootstrap": "^5.2.3",
"bootstrap-icons": "^1.10.3",
"laravel-vite-plugin": "^0.7.2",
"vite": "^4.0.0",
"vue": "^3.2.47"
}
}
Update vite.config.js as follow:
vite.config.js (before)
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
],
});
vite.config.js (after)
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import vue from "@vitejs/plugin-vue";
const path = require('path')
export default defineConfig({
plugins: [
laravel({
input: ["resources/css/app.css", "resources/js/app.js"],
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
// The Vue plugin will re-write asset URLs, when referenced
// in Single File Components, to point to the Laravel web
// server. Setting this to `null` allows the Laravel plugin
// to instead re-write asset URLs to point to the Vite
// server instead.
base: null,
// The Vue plugin will parse absolute URLs and treat them
// as absolute paths to files on disk. Setting this to
// `false` will leave absolute URLs un-touched so they can
// reference assets in the public directory as expected.
includeAbsolute: false,
},
},
}),
]
});
Update resources/css/app.css as follow:
resources/css/app.css (before)
//
resources/css/app.css (after)
@import "bootstrap/dist/css/bootstrap.min.css";
@import "bootstrap-icons/font/bootstrap-icons.css";
Create a new vue components resources/js/components/ExampleCounter.vue:
resources/js/components/ExampleCounter.vue
<script>
export default {
data() {
return {
count: 0,
};
},
};
</script>
<template>
<div class="row">
<div class="offset-sm-4 col-sm-4">
<button class="btn btn-primary btn-lg col-12 mt-5"
@click="count++"
>
<i class="bi bi-plus-circle"></i>
You clicked me {{ count }} times.
</button>
</div>
</div>
</template>
Update resources/js/app.js as follow:
resources/js/app.js (before)
import './bootstrap';
resources/js/app.js (after)
import "./bootstrap";
import "bootstrap";
import { createApp } from "vue";
import ExampleCounter from "./components/ExampleCounter.vue";
const app = createApp({});
app.component("example-counter", ExampleCounter);
const mountedApp = app.mount("#app");
Update resources/views/welcome.blade.php as follow:
resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Laravel</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<div id="app">
<example-counter></example-counter>
</div>
</body>
</html>
In the first Terminal start the Laravel’s local development server:
php artisan serve
In the second Terminal run the Vite development server:
npm run dev
Now access to the website over http://127.0.0.1:8000/

That’s all, we have everything set up and running :)
Feel free to Follow for more content 🔔, clap 👏🏻 and share the article With anyone you’d like.
As always, I appreciate your support.