Twitter Bootstrap and jQuery are Html/CSS and JavaScript framework and library still in heavy use in the Laravel community to this day.

It’s ease add then with Laravel Mix, but since Laravel v9.2.0 Vite is now the default bundler and a lot of users have had trouble getting it to work.

In this post we will go over how to install, configure, import them and how to use with Laravel 9 and Vite.

Vite and Laravel

Laravel switched from Webpack to Vite since Laravel version 9.2.0. So, instead of webpack.mixin.js config file, now we have vite.config.js config file on project folder of Laravel.

<code>vite.config.js</code> on Laravel project
`vite.config.js` on Laravel project

Vite is a modern frontend build tool that provides an extremely fast development environment. Using Vite with Laravel, you will typically use bundle your application’s CSS and JavaScript files into production ready assets using Vite.

Laravel integrates seamlessly with Vite by providing an official plugin and Blade directive to load your assets for development and production.

Installing Twitter Bootstrap and jQuery in Laravel with Vite

Installing Twitter Bootstrap in Laravel with Vite

Execute the following commands to install Twitter Bootstrap on Linux Mint or Linux Ubuntu:

# We do this because it will take care of a lot of things for us
composer require laravel/ui
php artisan ui bootstrap

# install all node_modules
npm install

A webpack.mixin.js file exists in project folder, we can delete it.

Importing and configuring vite.config.js for Twitter Bootstrap

Open the vite.config.js file and configure it as the following example:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import path from 'path';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/sass/app.scss',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
    ],
    resolve:{
        alias:{
            '~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap')
        }
    }
});

We have imported path module to deal with the path of the Bootstrap files, and added a resolve section that creates an alias to bootstrap library.

Open the file resources/js/bootstrap.js to import, instead of require, bootstrap library:

import _ from 'lodash';
window._ = _;

// ENSURE BOOTSTRAP IS BEING IMPORTED NOT REQUIRED
import * as Popper from '@popperjs/core'
window.Popper = Popper

import 'bootstrap';

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

import axios from 'axios';
window.axios = axios;

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Echo exposes an expressive API for subscribing to channels and listening
 * for events that are broadcast by Laravel. Echo and event broadcasting
 * allows your team to easily build robust real-time web applications.
 */

// import Echo from 'laravel-echo';

// import Pusher from 'pusher-js';
// window.Pusher = Pusher;

// window.Echo = new Echo({
//     broadcaster: 'pusher',
//     key: import.meta.env.VITE_PUSHER_APP_KEY,
//     wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
//     wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
//     wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
//     forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
//     enabledTransports: ['ws', 'wss'],
// });

Now we need to import bootstrap 5 SCSS path in resources/js/app.js file:

import './bootstrap';

import '../sass/app.scss'

Setup Auth Scaffolding with Bootstrap

This is an optional step, use it if you want to have a frontend scaffolding with Blade and Bootstrap

php artisan ui bootstrap --auth

Installing jQuery in Laravel with Vite

jQuery is installed using a node package manager, with a single command from the terminal. I will use npm.

At the root folder of your Laravel application run the following command.

npm install jquery --save-dev

Importing and configuring jQuery

After install jQuery, we need to import it in resources/js/bootstrap.js file. That’s where Laravel imports its dependencies and we will add it below the lodash import.

import _ from 'lodash';
window._ = _;

// UPDATE THIS LINES OF bootstrap.js FILE
import $ from 'jquery';
window.$ = $;

import 'bootstrap';

...

You can see that we also added jQuery to the window object, using this line: window.$ = $.

This will be useful for when we need to access jQuery directly in a Blade file. But if you never intend on using jQuery directly in a Blade file and plan to use it in your app.js file only, then there is no need to add it to the window object.

Using jQUery in Laravel with Vite

If you have problems using jQuery with Vite, is most likely the issue is you are trying to access $ on the window object before it has been loaded in. Laravel loads its scripts as JavaScript modules which are deferred by default.

A commom error is issued like this:

       Uncaught TypeError: window.$ is not a function
    at dashboard:1823:12
(anonimo) @ dashboard:1823
[Violation]Forced reflow while executing JavaScript took 72ms
dashboard:101 
 
        
       Uncaught Error: Bootstrap's JavaScript requires jQuery
    at app.0bbf2228.js:50:31

So if you’re trying to access jQuery using a blocking inline <script> tag, jQuery won’t be available when the browser executes that JavaScript. This means jQuery wasn’t loaded yet.

So to use jQuery in inline <script> tags, you must use inline JavaScript modules instead, and add them after your @vite Blade directive.

To do this, use the option type="module on <script> blocks:

@vite('resources/js/app.js')

<script type="module">
$('h1').text('Hello, World')
</script>

Using the Vite directive on Blade

After you have installed, imported and configured Twitter Bootstrap and jQuery, it’s possible to load the assets app.js and app.css using the @vite Blade directive.

Just write this line on your Blade page or layout (template): @vite(['resources/js/app.css', 'resources/js/app.js']).

See a Blade page example:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Besttools App</title>

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

</head>
<body class="antialiased">
    This is how we install Twitter Bootstrap and jQuery using Vite on Laravel
</body>

Build the assets with Vite

Now you can compile / build the assets in app.js and app.css files using the following command:

npm run build

If you run npm run dev, Vite gonna start a local server, I don’t like it since I use Laradock to handle my local development environment.

Now if you visit your application on browser should see a simple page with that phrase: This is how we install Twitter Bootstrap and jQuery using Vite on Laravel. Ya that is not much but what we are interested on is about the HTML source code that has the assets being loaded correct in link tags:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Besttools App</title>

    <style>
        body {
            font-family: 'Nunito', sans-serif;
        }
    </style>

    <link rel="preload" as="style" href="https://varejoaqui.test/besttools/public/build/assets/app.525f5899.css" /><link rel="preload" as="style" href="https://varejoaqui.test/besttools/public/build/assets/app.525f5899.css" /><link rel="modulepreload" href="https://varejoaqui.test/besttools/public/build/assets/app.3f476645.js" /><link rel="stylesheet" href="https://varejoaqui.test/besttools/public/build/assets/app.525f5899.css" /><link rel="stylesheet" href="https://varejoaqui.test/besttools/public/build/assets/app.525f5899.css" /><script type="module" src="https://varejoaqui.test/besttools/public/build/assets/app.3f476645.js"></script>
</head>
<body class="antialiased">
        This is how we install Twitter Bootstrap and jQuery using Vite on Laravel
</body>

Conclusion

Switch from Webpack to Vite brings improvements on performance but also brings the needs to understand and set correctly the new way of bundle js and css assets on Laravel projects.