Step-by-Step Guide to Use Global Vue Components with Laravel Blade templates and Vite

Arpanext
3 min readFeb 16, 2023

--

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.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Arpanext
Arpanext

Written by Arpanext

[ 👨‍💻 Software Engineer ][ 🗺 Traveler ] [ 🚀 Passionate about technology, innovation, challenging tasks and ofcourse eating, sleeping and other things... ]

Responses (1)

Write a response