I want to use Bootstrap 5 with Vue 3. As Bootstrap 5 uses vanilla JS (no JQuery), can I use Bootstrap 5 directly in a Vue 3 project (without using Bootstrap-Vue)? Can someone guide me how to use Bootstrap 5 with Vue 3?
-
Check this: https://therichpost.com/how-to-add-bootstrap-5-in-vue-3-application/ – Therichpost May 10 '21 at 07:59
-
I've set a small boilerplate for Vue 3 with Bootstrap 5 and some other things. May will help you - https://github.com/howbizarre/starter-template_vue-3-vite-bootstrap-5-with-icons – howbizarre Jun 28 '21 at 12:20
7 Answers
Bootstrap 5 no longer needs jQuery so it's easier to use with Vue, and no longer requires a library like bootstrap-vue.
Install bootstrap as you would any other JS module in the Vue project using npm install or by adding it to the package.json
...
npm install --save bootstrap
npm install --save @popperjs/core
Next, add the Bootstrap CSS and JS components to the Vue project entrypoint (ie: src/main.js
)...
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap"
Then, the simplest way to use Bootstrap components is via the data-bs-
attributes. For example here's the Bootstrap Collapse component...
<button
class="btn btn-primary"
data-bs-target="#collapseTarget"
data-bs-toggle="collapse">
Bootstrap collapse
</button>
<div class="collapse py-2" id="collapseTarget">
This is the toggle-able content!
</div>
Or, you can import any Bootstrap components and "wrap" them as Vue components. For example here's the Popover component...
import { Popover } from bootstrap;
const popover = Vue.component('bsPopover', {
template: `
<slot/>
`,
props: {
content: {
required: false,
default: '',
},
title: {
default: 'My Popover',
},
trigger: {
default: 'click',
},
delay: {
default: 0,
},
html: {
default: false,
},
},
mounted() {
// pass bootstrap popover options from props
var options = this.$props
var ele = this.$slots.default[0].elm
new Popover(ele,options)
},
})
<bs-popover
title="Hello Popover"
content="This is my content for the popover!"
trigger="hover">
<button class="btn btn-danger">
Hover for popover
</button>
</bs-popover>

- 351,302
- 90
- 710
- 624
-
Would you please exemplify how can one use https://getbootstrap.com/docs/5.0/forms/select/ without manually writing all the options (they are dynamic anyway), but similar to https://bootstrap-vue.org/docs/components/form-select#form-select ? – Marius Jun 14 '21 at 10:08
-
1Sadly, this doesn't work if you're using TypeScript: "TS7016: Could not find a declaration file for module 'bootstrap'" – Coreus Jul 02 '21 at 14:51
-
1May I ask how do you wrap bootstrap using vue-class-component in the .vue component file? – yossi elimelech Jul 29 '21 at 13:16
-
I don't suppose you have an example of this using the Vue composition API for a multi page app? I am having some issues getting the popovers to work with it – mellows Jul 05 '22 at 13:04
-
Why is import "bootstrap" required additionally to import "bootstrap/dist/css/bootstrap.min.css"? – ShadowGames Jul 15 '22 at 19:04
-
1
-
2@Coreus i had the same problem, to install the TypeScript types for bootstrap fixed it for me: `npm i --save-dev @types/bootstrap` // https://www.npmjs.com/package/@types/bootstrap – Zeussi Aug 05 '22 at 09:16
Yes, you can use Bootstrap without Bootstrap-Vue. Install these two packages with npm:
npm install --save @popperjs/core bootstrap@next
Import Bootstrap to src/main.js:
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";
Example usage for Vue Template:
<div class="dropdown">
<button
class="btn btn-secondary dropdown-toggle"
type="button"
id="dropdownMenuButton1"
data-bs-toggle="dropdown"
aria-expanded="false"
>
Check Bootstrap
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
Result:

- 11,939
- 3
- 73
- 67

- 832
- 1
- 6
- 15
-
3
-
@LaoShaw there is no extra code. Once you import the files as in this answer you'll have the CSS in all other components hosted by the root application – Nicholas Jan 31 '22 at 10:17
-
8while bt5 does not use jquery, bt5 might still use some native js that modifies DOM directly which will not work with vue3's virtual DOM – Shawn Shaw Feb 13 '22 at 02:56
-
What about adding popper.min.js? Is this not required? The shown code above does not work for me unfortunately. The HTML is in the DOM, but the popup is not displayed when I click the button. – ShadowGames Jul 15 '22 at 20:12
-
I get `npm ERR! notarget No matching version found for bootstrap@next.`. – rubebop Apr 28 '23 at 10:13
While the Bootstrap CSS can be used with any framework (React, Vue, Angular, etc), the Bootstrap JavaScript is not fully compatible with them.
Here's the official reasoning from the Bootstrap 5 docs:
While the Bootstrap CSS can be used with any framework, the Bootstrap JavaScript is not fully compatible with JavaScript frameworks like React, Vue, and Angular which assume full knowledge of the DOM. Both Bootstrap and the framework may attempt to mutate the same DOM element, resulting in bugs like dropdowns that are stuck in the “open” position.
The docs state to use an alternative framework-specific package instead of the Bootstrap JavaScript such as React Bootstrap, BootstrapVue, and ng-bootstrap.
Unfortunately, BootstrapVue is only compatible with Vue2/Nuxt2 and there is no version available for Vue3/Nuxt3 yet.

- 4,815
- 13
- 75
- 138
It's easy to implement this once you understand how Bootstrap modals work. Bootstrap modals have a div element with a class of modal fade
. When it is triggered, this element gets the show
and d-block
class as well. In addition, the body tag gets an additional class of modal-open
. When the modal is closed, this process is reversed. Understanding this, we can easily implement Bootstrap 5 modals in one's code:
Import Bootstrap 5's CDN in your code. Add both the CSS and JS to your code.
Our sample Single Page Component will look like this:
<template>
<div>
<p>Test modal<a href="#" @click="modalToggle">now</a></p>
<div>
<button type="button" class="btn btn-primary" @click="modalToggle">My Modal</button>
<div
ref="modal"
class="modal fade"
:class="{ show: active, 'd-block': active }"
tabindex="-1"
role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
@click="modalToggle">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
</div>
</div>
</div>
<div v-if="active" class="modal-backdrop fade show"></div>
</div>
</div>
</template>
Here we are using the basic Bootstrap 5 modal.
<script>
export default {
data() {
return {
active: false,
}
},
methods: {
modalToggle() {
const body = document.querySelector("body")
this.active = !this.active
this.active ? body.classList.add("modal-open") : body.classList.remove("modal-open")
},
},
}
</script>
Here, we have a variable active
which is initially set false. So modal will not show up on page load. On clicking a link, we use a method to toggle this variable. This will remove the show attribute and the d-block class from our modalm and remove the modal-open
property from the body tag.

- 7,561
- 15
- 54
- 86
bootstrap 5 must have popper for run , try with this npm :
npm install --save bootstrap
npm i @popperjs/core

- 166
- 1
- 4
Going tag on to this answer however late it is, probably because I'll end up doing this again in a few months for another client.
I'm porting over a template from StartBootstrap into Vue, specifically the SB Admin 2 template and initially I couldn't get the navbar dropdown menu's to work. Turns out, the data attributes changed I guess between BS 4 and BS 5
Previous
<a
class="nav-link collapsed"
href="#"
data-toggle="collapse"
data-target="#collapseTwo"
aria-expanded="true"
aria-controls="collapseTwo"
>
<i class="fas fa-fw fa-cog"></i>
<span>Components</span>
</a>
<div
id="collapseTwo"
class="collapse"
aria-labelledby="headingTwo"
data-parent="#accordionSidebar"
>
<div class="bg-white py-2 collapse-inner rounded">
<h6 class="collapse-header">Custom Components:</h6>
<a class="collapse-item" href="buttons.html">Buttons</a>
<a class="collapse-item" href="cards.html">Cards</a>
</div>
</div>
You need to add -bs
to the existing data-
attributes as long as those attributes previously reference bootstrap functionality. Don't just go and do a Cntrl-F and Replace please.
Here is the after of the above example .
<a
class="nav-link collapsed"
href="#"
data-bs-toggle="collapse"
data-bs-target="#collapseTwo"
aria-expanded="true"
aria-controls="collapseTwo"
>
<i class="fas fa-fw fa-cog"></i>
<span>Components</span>
</a>
<div
id="collapseTwo"
class="collapse"
aria-labelledby="headingTwo"
data-parent="#accordionSidebar"
>
<div class="bg-white py-2 collapse-inner rounded">
<h6 class="collapse-header">Custom Components:</h6>
<a class="collapse-item" href="buttons.html">Buttons</a>
<a class="collapse-item" href="cards.html">Cards</a>
</div>
</div>
EDIT: The above assumes you've followed this answer already

- 456
- 3
- 19
-
1If you're using the bootstrap sass-files (see https://getbootstrap.com/docs/5.2/customize/css-variables/) you can get rid of "-bs" easily. So noe need to change any code. Just change die $prefix variable in SASS to "". – mkours Jul 23 '23 at 08:00