React
Embla Carousel provides a wrapper for React that ensures seamless integration of the carousel into your React project and automatic cleanup on component unmount.
Start by installing the Embla Carousel npm package and add it to your dependencies.
npm install embla-carousel-react --savepnpm add embla-carousel-reactyarn add embla-carousel-reactThe component structure
A recommended setup uses an overflow wrapper and a scroll container, though the outer wrapper is optional. The element with the class name embla__viewport serves as both the root and the overflow wrapper. To avoid drag conflicts, place navigation buttons outside the viewport. Start by adding the following structure to your carousel:
import React from 'react'import useEmblaCarousel from 'embla-carousel-react'
export function EmblaCarousel() { const [emblaRef] = useEmblaCarousel()
return ( <div className="embla"> <div className="embla__viewport" ref={emblaRef}> <div className="embla__container"> <div className="embla__slide">Slide 1</div> <div className="embla__slide">Slide 2</div> <div className="embla__slide">Slide 3</div> </div> </div>
<button className="embla__prev">Scroll to prev</button> <button className="embla__next">Scroll to next</button> </div> )}Styling the carousel
The element with the classname embla__viewport acts as an overflow wrapper, ensuring that any scroll overflow is hidden. The element with the classname embla__container is the scrollable area that holds and moves the slides. Add the following CSS to style these elements:
.embla__viewport { overflow: hidden;}
.embla__container { display: flex; touch-action: pan-y pinch-zoom;}
.embla__slide { flex: 0 0 100%; min-width: 0;}Accessing the carousel API
Use the useEmblaCarousel hook and pass your options as the first argument. You can access the API directly from the hook, and use it to control the carousel or respond to user actions, as shown below:
import React from 'react'import useEmblaCarousel from 'embla-carousel-react'
export function EmblaCarousel() { const [emblaRef, emblaApi] = useEmblaCarousel({ loop: false })
const goToPrev = () => emblaApi?.goToPrev() const goToNext = () => emblaApi?.goToNext()
return ( <div className="embla"> <div className="embla__viewport" ref={emblaRef}> <div className="embla__container"> <div className="embla__slide">Slide 1</div> <div className="embla__slide">Slide 2</div> <div className="embla__slide">Slide 3</div> </div> </div>
<button className="embla__prev" onClick={goToPrev}> Scroll to prev </button> <button className="embla__next" onClick={goToNext}> Scroll to next </button> </div> )}Adding plugins
Plugins let you extend your carousel with additional features beyond the built-in core functionality. To get started, install the plugin you want to use. In this example, we'll add the Autoplay plugin:
npm install embla-carousel-autoplay --savepnpm add embla-carousel-autoplayyarn add embla-carousel-autoplayYou can pass an optional plugin array as the second argument to the useEmblaCarousel hook. Here's how to extend the carousel from the previous example with Autoplay:
import React, { useEffect } from 'react'import useEmblaCarousel from 'embla-carousel-react'import Autoplay from 'embla-carousel-autoplay'
export function EmblaCarousel() { const [emblaRef, emblaApi] = useEmblaCarousel({ loop: false }, [Autoplay()])
const goToPrev = () => emblaApi?.goToPrev() const goToNext = () => emblaApi?.goToNext()
useEffect(() => { if (!emblaApi) return emblaApi.plugins().autoplay?.play() }, [emblaApi])
return ( <div className="embla"> <div className="embla__viewport" ref={emblaRef}> <div className="embla__container"> <div className="embla__slide">Slide 1</div> <div className="embla__slide">Slide 2</div> <div className="embla__slide">Slide 3</div> </div> </div>
<button className="embla__prev" onClick={goToPrev}> Scroll to prev </button> <button className="embla__next" onClick={goToNext}> Scroll to next </button> </div> )}Congratulations! You just created your first Embla Carousel component.