Carousel (Slider)
A slideshow component for cycling through elements (images or slides with various content) like a carousel.
The Carousel component relies on the Swiper component. Ensure that you have imported all necessary component's files. Below is an example of imports necessary for the slider with navigation buttons and pagination (bullets):
import { Swiper, SwiperSlide } from 'swiper/react'
import { Navigation, Pagination } from 'swiper/modules'
import 'swiper/css'
import 'swiper/css/pagination'
See also:
Pagination
'use client'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Button from 'react-bootstrap/Button'
import Ratio from 'react-bootstrap/Ratio'
import { Swiper, SwiperSlide } from 'swiper/react'
import { Navigation, Pagination, Scrollbar } from 'swiper/modules'
import 'swiper/css'
import 'swiper/css/pagination'
import 'swiper/css/scrollbar'
export default function CarouselPaginationDemo() {
return (
<Row xs={1} md={2} className="g-4">
<Col>
{/* Pagination: Bullets */}
<Swiper
className="hover-effect-opacity"
modules={[Navigation, Pagination]}
spaceBetween={20}
loop={true}
navigation={{
prevEl: '.btn-prev',
nextEl: '.btn-next',
}}
pagination={{ clickable: true }}
>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
1
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
2
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
3
</div>
</Ratio>
</SwiperSlide>
<div className="position-absolute top-50 start-0 z-2 translate-middle-y ms-3 hover-effect-target opacity-0">
<Button
variant="outline-secondary"
className="btn-prev btn-icon animate-slide-start rounded-circle me-1"
aria-label="Prev"
>
<i className="ci-chevron-left fs-lg animate-target"/>
</Button>
</div>
<div className="position-absolute top-50 end-0 z-2 translate-middle-y me-3 hover-effect-target opacity-0">
<Button
variant="outline-secondary"
className="btn-next btn-icon animate-slide-end rounded-circle"
aria-label="Next"
>
<i className="ci-chevron-right fs-lg animate-target"/>
</Button>
</div>
</Swiper>
</Col>
<Col>
{/* Pagination: Progress bar */}
<Swiper
className="hover-effect-opacity"
modules={[Navigation, Pagination]}
spaceBetween={20}
navigation={{
prevEl: '.btn-prev',
nextEl: '.btn-next',
}}
pagination={{ type: 'progressbar' }}
>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
1
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
2
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
3
</div>
</Ratio>
</SwiperSlide>
<div className="position-absolute top-50 start-0 z-2 translate-middle-y ms-3 hover-effect-target opacity-0">
<Button
variant="outline-secondary"
className="btn-prev btn-icon animate-slide-start rounded-circle me-1"
aria-label="Prev"
>
<i className="ci-chevron-left fs-lg animate-target"/>
</Button>
</div>
<div className="position-absolute top-50 end-0 z-2 translate-middle-y me-3 hover-effect-target opacity-0">
<Button
variant="outline-secondary"
className="btn-next btn-icon animate-slide-end rounded-circle"
aria-label="Next"
>
<i className="ci-chevron-right fs-lg animate-target"/>
</Button>
</div>
</Swiper>
</Col>
<Col>
{/* Pagination: Fraction */}
<Swiper
className="hover-effect-opacity"
modules={[Navigation, Pagination]}
spaceBetween={20}
navigation={{
prevEl: '.btn-prev',
nextEl: '.btn-next',
}}
pagination={{
el: '.swiper-pagination',
type: 'fraction',
}}
>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
1
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
2
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
3
</div>
</Ratio>
</SwiperSlide>
<div className="position-absolute top-50 start-0 z-2 translate-middle-y ms-3 hover-effect-target opacity-0">
<Button
variant="outline-secondary"
className="btn-prev btn-icon animate-slide-start rounded-circle me-1"
aria-label="Prev"
>
<i className="ci-chevron-left fs-lg animate-target"/>
</Button>
</div>
<div className="position-absolute top-50 end-0 z-2 translate-middle-y me-3 hover-effect-target opacity-0">
<Button
variant="outline-secondary"
className="btn-next btn-icon animate-slide-end rounded-circle"
aria-label="Next"
>
<i className="ci-chevron-right fs-lg animate-target"/>
</Button>
</div>
<div className="swiper-pagination text-body-secondary fs-6 opacity-50 fw-semibold mb-2" />
</Swiper>
</Col>
<Col>
{/* Pagination: Scrollbar */}
<Swiper
className="hover-effect-opacity"
modules={[Navigation, Scrollbar]}
spaceBetween={20}
navigation={{
prevEl: '.btn-prev',
nextEl: '.btn-next',
}}
scrollbar={{ draggable: true }}
mousewheel={true}
>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
1
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
2
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-body-tertiary">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
3
</div>
</Ratio>
</SwiperSlide>
<div className="position-absolute top-50 start-0 z-2 translate-middle-y ms-3 hover-effect-target opacity-0">
<Button
variant="outline-secondary"
className="btn-prev btn-icon animate-slide-start rounded-circle me-1"
aria-label="Prev"
>
<i className="ci-chevron-left fs-lg animate-target"/>
</Button>
</div>
<div className="position-absolute top-50 end-0 z-2 translate-middle-y me-3 hover-effect-target opacity-0">
<Button
variant="outline-secondary"
className="btn-next btn-icon animate-slide-end rounded-circle"
aria-label="Next"
>
<i className="ci-chevron-right fs-lg animate-target"/>
</Button>
</div>
</Swiper>
</Col>
</Row>
)
}
Multiple slides per view (Responsive)
'use client'
import Button from 'react-bootstrap/Button'
import Ratio from 'react-bootstrap/Ratio'
import { Swiper, SwiperSlide } from 'swiper/react'
import { Navigation, Pagination } from 'swiper/modules'
import 'swiper/css'
import 'swiper/css/pagination'
export default function CarouselMultipleSlidesDemo() {
return (
<div className="position-relative px-5">
{/* External slider prev/next buttons */}
<Button
variant="outline-secondary"
className="btn-icon animate-slide-start rounded-circle position-absolute top-50 start-0 translate-middle-y mt-n3"
id="prev"
aria-label="Prev"
>
<i className="ci-chevron-left fs-lg animate-target"/>
</Button>
<Button
variant="outline-secondary"
className="btn-icon animate-slide-end rounded-circle position-absolute top-50 end-0 translate-middle-y mt-n3"
id="next"
aria-label="Next"
>
<i className="ci-chevron-right fs-lg animate-target"/>
</Button>
{/* Slider */}
<Swiper
className="px-2"
modules={[Navigation, Pagination]}
slidesPerView={1}
spaceBetween={16}
loop={true}
navigation={{
prevEl: '#prev',
nextEl: '#next',
}}
pagination={{
el: '.swiper-pagination',
clickable: true,
}}
breakpoints={{
'600': {
slidesPerView: 2,
},
'1000': {
slidesPerView: 3,
},
}}
>
<SwiperSlide>
<Ratio aspectRatio="4x3" className="bg-info-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
1
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="4x3" className="bg-success-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
2
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="4x3" className="bg-danger-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
3
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="4x3" className="bg-warning-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
4
</div>
</Ratio>
</SwiperSlide>
{/* Pagination (Bullets) */}
<div className="swiper-pagination position-static mt-3" />
</Swiper>
</div>
)
}
Fade transition
'use client'
import Button from 'react-bootstrap/Button'
import Ratio from 'react-bootstrap/Ratio'
import { Swiper, SwiperSlide } from 'swiper/react'
import { EffectFade, Navigation } from 'swiper/modules'
import 'swiper/css'
import 'swiper/css/effect-fade'
export default function CarouselFadeTransitionDemo() {
return (
<Swiper
className="hover-effect-opacity"
modules={[EffectFade, Navigation]}
effect="fade"
loop={true}
navigation={{
prevEl: '.btn-prev',
nextEl: '.btn-next',
}}
>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-info-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
First
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-danger-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
Second
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="16x9" className="bg-warning-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
Third
</div>
</Ratio>
</SwiperSlide>
{/* Prev button */}
<div className="position-absolute top-50 start-0 z-2 translate-middle-y ms-3 ms-sm-4 hover-effect-target opacity-0">
<Button
variant="secondary"
className="btn-prev btn-icon bg-body border-0 rounded-circle animate-slide-start"
aria-label="Prev"
>
<i className="ci-chevron-left fs-lg animate-target"/>
</Button>
</div>
{/* Next button */}
<div className="position-absolute top-50 end-0 z-2 translate-middle-y me-3 me-sm-4 hover-effect-target opacity-0">
<Button
variant="secondary"
className="btn-next btn-icon bg-body border-0 rounded-circle animate-slide-end"
aria-label="Next"
>
<i className="ci-chevron-right fs-lg animate-target"/>
</Button>
</div>
</Swiper>
)
}
Thumbnails
'use client'
import { useState } from 'react'
import Button from 'react-bootstrap/Button'
import Ratio from 'react-bootstrap/Ratio'
import { Swiper, SwiperSlide } from 'swiper/react'
import { Thumbs, Navigation } from 'swiper/modules'
import type { Swiper as SwiperType } from 'swiper'
import 'swiper/css'
export default function CarouselThumbnailsDemo() {
// store thumbs swiper instance
const [thumbsSwiper, setThumbsSwiper] = useState<SwiperType | null>(null)
return (
<>
{/* Main Swiper -> pass thumbs swiper instance */}
<Swiper
className="hover-effect-opacity"
modules={[Thumbs, Navigation]}
loop={true}
navigation={{
prevEl: '.btn-prev',
nextEl: '.btn-next',
}}
thumbs={{ swiper: thumbsSwiper }}
>
{['primary', 'success', 'warning', 'danger', 'info', 'secondary', 'warning'].map((color, index) => (
<SwiperSlide key={index}>
<Ratio aspectRatio="16x9" className={`bg-${color}-subtle rounded`}>
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-4">
{index + 1}
</div>
</Ratio>
</SwiperSlide>
))}
<div className="position-absolute top-50 start-0 z-2 translate-middle-y ms-3 ms-sm-4 hover-effect-target opacity-0">
<Button
variant="secondary"
className="btn-prev btn-icon bg-body border-0 rounded-circle animate-slide-start"
aria-label="Prev"
>
<i className="ci-chevron-left fs-lg animate-target"/>
</Button>
</div>
<div className="position-absolute top-50 end-0 z-2 translate-middle-y me-3 me-sm-4 hover-effect-target opacity-0">
<Button
variant="secondary"
className="btn-next btn-icon bg-body border-0 rounded-circle animate-slide-end"
aria-label="Next"
>
<i className="ci-chevron-right fs-lg animate-target"/>
</Button>
</div>
</Swiper>
{/* Thumbs Swiper -> store swiper instance */}
{/* It is also required to set watchSlidesProgress prop */ }
<Swiper
className="swiper-load swiper-thumbs pt-2 mt-1"
modules={[Thumbs]}
watchSlidesProgress
onSwiper={setThumbsSwiper}
loop={true}
spaceBetween={12}
slidesPerView={3}
breakpoints={{
'340': {
slidesPerView: 4,
},
'500': {
slidesPerView: 5,
},
'600': {
slidesPerView: 6,
},
'768': {
slidesPerView: 4,
},
'992': {
slidesPerView: 5,
},
'1200': {
slidesPerView: 6,
},
}}
>
{['primary', 'success', 'warning', 'danger', 'info', 'secondary', 'warning'].map((color, index) => (
<SwiperSlide key={index} className="swiper-thumb">
<Ratio aspectRatio="1x1" className={`bg-${color}-subtle rounded`}>
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center fs-3 fw-semibold">
{index + 1}
</div>
</Ratio>
</SwiperSlide>
))}
</Swiper>
</>
)
}
Synchronized sliders
'use client'
import { useState } from 'react'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Button from 'react-bootstrap/Button'
import Ratio from 'react-bootstrap/Ratio'
import { Swiper, SwiperSlide } from 'swiper/react'
import { Controller, Navigation, EffectFlip } from 'swiper/modules'
import type { Swiper as SwiperType } from 'swiper'
import 'swiper/css'
import 'swiper/css/effect-flip'
export default function CarouselSyncDemo() {
// store controlled swiper instance
const [controlledSwiper, setControlledSwiper] = useState<SwiperType | null>(null)
return (
<Row className="align-items-center">
<Col md={5} className="mb-4 mb-md-0 pb-1 pb-md-0">
{/* Controlled Swiper -> store swiper instance */}
<Swiper
modules={[Controller, EffectFlip]}
onSwiper={setControlledSwiper}
allowTouchMove={false}
loop={true}
effect="flip"
flipEffect={{
slideShadows: false,
}}
>
<SwiperSlide>
<Ratio aspectRatio="4x3" className="bg-success-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
<i className="ci-image text-success opacity-75"/>
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="4x3" className="bg-warning-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
<i className="ci-image text-warning opacity-75"/>
</div>
</Ratio>
</SwiperSlide>
<SwiperSlide>
<Ratio aspectRatio="4x3" className="bg-info-subtle rounded">
<div className="position-absolute top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center display-5">
<i className="ci-image text-info opacity-75"/>
</div>
</Ratio>
</SwiperSlide>
</Swiper>
</Col>
<Col md={7} className="ps-xl-5">
{/* Main Swiper -> pass controlled swiper instance */}
<Swiper
className="text-center text-md-start"
modules={[Controller, Navigation]}
controller={{ control: controlledSwiper }}
spaceBetween={32}
loop={true}
speed={400}
navigation={{
prevEl: '#prev-btn',
nextEl: '#next-btn',
}}
>
<SwiperSlide>
<h3>First slide</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque varius pulvinar dui eu
ullamcorper. Donec a nisl sed felis pretium posuere ut vitae arcu.
</p>
</SwiperSlide>
<SwiperSlide>
<h3>Second slide</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque varius pulvinar dui eu
ullamcorper. Donec a nisl sed felis pretium posuere ut vitae arcu.
</p>
</SwiperSlide>
<SwiperSlide>
<h3>Third slide</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque varius pulvinar dui eu
ullamcorper. Donec a nisl sed felis pretium posuere ut vitae arcu.
</p>
</SwiperSlide>
<div className="d-flex justify-content-center justify-content-md-start gap-2 pt-2">
<Button
variant="outline-secondary"
className="btn-icon animate-slide-start rounded-circle me-1"
id="prev-btn"
aria-label="Prev"
>
<i className="ci-chevron-left fs-lg animate-target"/>
</Button>
<Button
variant="outline-secondary"
className="btn-icon animate-slide-end rounded-circle"
id="next-btn"
aria-label="Next"
>
<i className="ci-chevron-right fs-lg animate-target"/>
</Button>
</div>
</Swiper>
</Col>
</Row>
)
}