Replace Tailwind With Bootstrap
medium.com How to Install Laravel Jetstream with InertiaJs and Bootstrap 5 Giovanni López Orenday 8–11 minutes
Hi everyone!
This is my first post, and I’m going to show you how to Install Laravel Jetstream with InertiaJs and Bootstrap 5
By default Jetstream use tailwindcss, It’s a nice tool but some times you need to make an MVP quickly, and Bootstrap could be a helpfull tool for that. So let’s go:
First you will need a clear installation of Laravel Jetstream with InertiaJs.
After that, We need to install Bootstrap, popperjs and sass via npm:
npm i --save bootstrap @popperjs/core
npm i --save-dev sass
Next, We will to add bootstrap alias in the vite.config.js like this way:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';const path = require('path')export default defineConfig({
resolve: {
alias: {
'~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap'),
}
},
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
});
Create the app.scss on this path resources/scss and import the Bootstrap styles:
// Import all of Bootstrap's CSS
@import "~bootstrap/scss/bootstrap";
Then, import this file and Bootstrap Scripts in your resources/js/app.js file:
import '../scss/app.scss'; // Import all of Bootstrap's JS
import * as bootstrap from 'bootstrap'
Good! Now you have Bootstrap on your app.. If you want you can remove Tailwindcss.
I will give you some Vue view examples that you can replace to use Bootstrap components:
resources/js/Pages/Welcome.vue
<script setup>
import { Head, Link } from "@inertiajs/inertia-vue3";defineProps({
canLogin: Boolean,
canRegister: Boolean,
});
</script><template>
<Head title="Welcome" /><div class="container-fluid text-end py-2">
<Link
v-if="$page.props.user"
:href="route('dashboard')"
class="btn btn-primary"
>Dashboard</Link
><template v-else>
<Link
:href="route('login')"
class="btn btn-primary me-2"
>Log in</Link
><Link
v-if="canRegister"
:href="route('register')"
class="btn btn-secondary"
>Register</Link
>
</template>
</div>
</template>
resources/js/Pages/Auth/Login.vue
<script setup>
import { Head, Link, useForm } from "@inertiajs/inertia-vue3";defineProps({
canResetPassword: Boolean,
status: String,
});const form = useForm({
email: "",
password: "",
remember: false,
});const submit = () => {
form.transform((data) => ({
...data,
remember: form.remember ? "on" : "",
})).post(route("login"), {
onFinish: () => form.reset("password"),
});
};
</script><template>
<Head title="Log in" /><div class="container">
<div class="row">
<div class="col-md-4 offset-md-4">
<div class="card mt-5">
<div class="card-body">
<div v-if="status" class="alert alert-success">
{{ status }}
</div>
<form @submit.prevent="submit">
<div class="mb-3">
<label for="email" class="form-label"
>Email</label
>
<input
type="email"
class="form-control"
id="email"
v-model="form.email"
required
autofocus
/>
<p class="text-danger" v-if="form.errors.email" v-text="form.errors.email"></p>
</div><div class="mb-3">
<label for="password">Password</label>
<input type="password" class="form-control" required v-model="form.password">
<p class="text-danger" v-if="form.errors.password" v-text="form.errors.password"></p>
</div><div class="form-check">
<input id="remember" type="checkbox" class="form-check-input" v-model="form.remember">
<label for="remember" class="form-check-label">Remember me</label>
</div><div class="d-flex align-items-center justify-content-end mt-4">
<Link
v-if="canResetPassword"
:href="route('password.request')"
class="btn btn-link"
>
Forgot your password?
</Link>
<button type="submit" class="btn btn-primary" :class="{ 'opacity-25': form.processing }" :disabled="form.processing">Log in</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
resources/js/Layouts/AppLayout.vue
<script setup>
import { ref } from 'vue';
import { Inertia } from '@inertiajs/inertia';
import { Head, Link } from '@inertiajs/inertia-vue3';
import Menu from './Menu.vue';defineProps({
title: String,
});const showingNavigationDropdown = ref(false);const switchToTeam = (team) => {
Inertia.put(route('current-team.update'), {
team_id: team.id,
}, {
preserveState: false,
});
};const logout = () => {
Inertia.post(route('logout'));
};
</script><template>
<div>
<Head :title="title" /><!-- <Banner /> -->
<Menu/><div class="min-h-screen bg-gray-100">
<!-- Page Heading -->
<header v-if="$slots.header" class="bg-white shadow">
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<slot name="header" />
</div>
</header>
<!-- Page Content -->
<main class="container pt-5">
<slot />
</main>
</div>
</div>
</template>
resources/js/Layouts/Menu.vue
<script setup>
import { ref } from "vue";
import { Inertia } from "@inertiajs/inertia";
import { Head, Link } from "@inertiajs/inertia-vue3";const logout = () => {
Inertia.post(route("logout"));
};
</script>
<template>
<nav class="navbar navbar-expand-lg bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">App</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<Link class="nav-link" aria-current="page" :href="route('dashboard')"
>Dashboard</Link
>
</li>
</ul>
<ul class="navbar-nav ms-auto">
<li class="nav-item dropdown">
<a
href="#"
class="nav-link dropdown-toggle"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
{{ $page.props.user.name }}
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><hr class="dropdown-divider" /></li>
<li>
<a
href="#"
@click="logout"
role="button"
class="dropdown-item"
>Log out</a
>
</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
</template>
Thank for reading and have a good day! ;)