Key Takeaways
- Swiper.js 11 (the current stable release as of 2025) ships as a native ES module and a UMD bundle, giving you flexible integration options.
- Bootstrap 5’s grid and Swiper’s
slidesPerViewbreakpoints solve different problems and must be configured independently to avoid layout conflicts. - Initialising Swiper after the DOM is ready prevents the most common “slides not rendering” bug.
- Accessibility requires explicit
aria-labelattributes and keyboard navigation settings that Swiper does not enable by default. - Canvas HTML Template bundles Swiper and exposes a data-attribute API that removes the need to write initialisation JavaScript by hand.
Why Swiper and Not the Native Bootstrap Carousel
Bootstrap 5 ships its own carousel component, and for a simple hero banner it is perfectly adequate. Swiper.js wins when you need features the native component lacks: multi-slide views, free-drag momentum scrolling, loop mode without cloning artefacts, lazy-loaded images, and a breakpoint system that mirrors CSS media queries. Swiper also separates its CSS from its JS cleanly, which matters when you are optimising a critical rendering path. For a thorough look at the native approach, How to Build a Bootstrap 5 Image Carousel with Custom Controls covers Bootstrap’s carousel in depth. Reading both will help you pick the right tool.
The short answer: use Bootstrap’s carousel for simple, full-width hero slides. Use Swiper when you need anything more than that.

Installing Swiper in a Bootstrap 5 Project
You have three installation paths.
Option 1: npm (recommended for build-tool projects)
npm install swiperThen import inside your JS entry point:
import Swiper from 'swiper';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';Option 2: CDN (quick prototyping)
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css">
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>Option 3: Canvas HTML Template’s bundled build
The Canvas HTML Template includes Swiper inside plugins.min.js. Slides are initialised via data attributes, so no custom JS is required for standard configurations. The template’s functions.bundle.js reads those attributes and calls the Swiper constructor internally.
Core Markup Structure Inside a Bootstrap Layout
Swiper has its own container, wrapper, and slide class names. These must not be replaced by Bootstrap grid classes. Place the Swiper container inside a Bootstrap column, not instead of one.
<div class="container">
<div class="row">
<div class="col-12">
<!-- Swiper container -->
<div class="swiper mySwiper">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="slide-1.jpg" alt="Slide 1 description" loading="lazy">
</div>
<div class="swiper-slide">
<img src="slide-2.jpg" alt="Slide 2 description" loading="lazy">
</div>
<div class="swiper-slide">
<img src="slide-3.jpg" alt="Slide 3 description" loading="lazy">
</div>
</div>
<!-- Navigation -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
<!-- Pagination -->
<div class="swiper-pagination"></div>
</div>
</div>
</div>
</div>One common mistake is applying overflow: hidden to a Bootstrap column that wraps a Swiper with spaceBetween set. The negative margin Swiper uses for spacing gets clipped. Remove any overflow constraint from the Bootstrap parent, or set overflow: visible explicitly.

Initialisation JavaScript
Always initialise after the DOM has parsed. Wrapping in DOMContentLoaded is the safest approach when you are not using a bundler with deferred imports.
<script>
document.addEventListener('DOMContentLoaded', function () {
var swiper = new Swiper('.mySwiper', {
loop: true,
speed: 600,
spaceBetween: 24,
slidesPerView: 1,
grabCursor: true,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: '.swiper-pagination',
clickable: true,
},
a11y: {
prevSlideMessage: 'Previous slide',
nextSlideMessage: 'Next slide',
},
});
});
</script>Note the a11y block. Swiper’s accessibility module generates aria-label attributes on navigation buttons automatically when this option is present, but the messages default to English only. If your site is multilingual, pass translated strings here.
Configuring Swiper Breakpoints to Match Bootstrap 5
This is where most slider integration problems live. Swiper’s breakpoints object uses min-width pixel values, which align exactly with Bootstrap 5’s default grid breakpoints: 576 (sm), 768 (md), 992 (lg), and 1200 (xl).
<script>
document.addEventListener('DOMContentLoaded', function () {
var swiper = new Swiper('.mySwiper', {
loop: true,
speed: 500,
spaceBetween: 16,
slidesPerView: 1,
grabCursor: true,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
pagination: {
el: '.swiper-pagination',
clickable: true,
},
breakpoints: {
// sm: 576px and up
576: {
slidesPerView: 2,
spaceBetween: 20,
},
// md: 768px and up
768: {
slidesPerView: 2,
spaceBetween: 24,
},
// lg: 992px and up
992: {
slidesPerView: 3,
spaceBetween: 28,
},
// xl: 1200px and up
1200: {
slidesPerView: 4,
spaceBetween: 32,
},
},
});
});
</script>The outer slidesPerView: 1 is the mobile-first default (below 576 pixels). Each breakpoint object overrides only the keys it lists, so you do not need to repeat every option at every breakpoint.
For testimonial or card-style sliders, the pattern above pairs well with the techniques in How to Create a Bootstrap 5 Testimonial Slider, which covers styling slide content to match a Bootstrap card aesthetic.
Theming Swiper with Bootstrap 5 and Canvas CSS Variables
Swiper exposes its own CSS custom properties for colour, including --swiper-theme-color (defaults to #007aff). In a Bootstrap 5 project you almost certainly want navigation dots and arrows to match your brand colour. Override it once at the root or on the Swiper container:
<style>
.mySwiper {
--swiper-theme-color: #0d6efd; / Bootstrap 5 primary /
}
</style>Inside Canvas, the equivalent variable is --cnvs-themecolor. You can reference it directly:
<style>
.mySwiper {
--swiper-theme-color: var(--cnvs-themecolor);
}
</style>This keeps the slider colour in sync with Canvas’s theme switcher without any JavaScript.
Common Pitfalls and How to Fix Them
- Slides have zero height: The parent container has no explicit height and the images have not loaded yet. Set a minimum height on
.swiperor ensure images carrywidthandheightattributes so the browser reserves space. - Loop mode duplicates wrong number of slides: Swiper requires at least as many real slides as the total of
slidesPerViewplusloopAdditionalSlides(default 0). If you have three slides andslidesPerView: 4, loop mode breaks. Either reduceslidesPerViewor add more slides. - Autoplay pauses permanently after tab switch: Swiper 11 pauses autoplay on visibility change by default. Resume it in the
visibilitychangeevent if that behaviour is unwanted for your use case. - Navigation arrows hidden behind Bootstrap modal overlay: Increase the
z-indexof.swiper-button-nextand.swiper-button-previf you embed a slider inside a modal. See the related post Making Bootstrap 5 Modals Accessible for z-index stacking context notes. - CSS not loading when using npm imports: Swiper 9 and above moved to named CSS imports per module. Importing only
swiper/csswithoutswiper/css/navigationleaves arrows unstyled. Import each module’s CSS separately.
Frequently Asked Questions
No. Swiper does not depend on or modify Bootstrap’s JavaScript. Both libraries operate independently. The one area to watch is CSS specificity: Swiper’s bundled stylesheet and Bootstrap’s reset may both target img or button elements. Load Swiper’s CSS after Bootstrap’s to keep Bootstrap as the baseline and Swiper as the override.
Use the keys 576, 768, 992, and 1200 in the Swiper breakpoints object. These correspond to Bootstrap 5’s sm, md, lg, and xl breakpoints respectively. Swiper interprets these as min-width thresholds, matching Bootstrap’s mobile-first approach. The xxl breakpoint (1400) can also be added if your design changes at that width.
Yes, but you must reinitialise Swiper after the modal’s shown.bs.modal event fires. Swiper calculates slide dimensions on mount. If the modal is hidden when Swiper initialises, it reads zero widths and renders incorrectly. Listen for the Bootstrap modal event and call swiper.update() or create a new instance at that point.
Canvas uses a data-attribute pattern processed by functions.bundle.js. You add attributes such as data-loop="true", data-speed="400", and data-slides-per-view="3" directly to the Swiper container element. The bundled script reads these at runtime and constructs the configuration object, so standard sliders require no custom JavaScript. Custom breakpoints or advanced options still benefit from a small inline script.
Swiper includes an a11y module that adds role="group", aria-label, and aria-roledescription attributes to slides and controls. Enable it by including the a11y key in your configuration object with appropriate message strings. Keyboard navigation (arrow keys) is enabled by default when the slider has focus. For autoplay sliders, always provide a visible pause button to meet WCAG 2.1 criterion 2.2.2.
Looking for a production-ready Bootstrap 5 HTML template? Browse Canvas Template demos and find the perfect starting point for your next project.
If you’re building with the Canvas HTML Template and want to ship production-ready Bootstrap 5 layouts faster, try Canvas Builder free — the visual builder that exports clean Canvas-ready markup in minutes.
Skip the setup and build it free
Spin up a complete Bootstrap 5 site, blog included, with Canvas Builder. No coding, no cost.
Canvas Team
Tutorials and tips for building beautiful Bootstrap 5 websites with the Canvas HTML Template and Canvas Builder.
More from the Canvas Blog