React
Installation
To start using Embla Carousel in your React project, install the embla-carousel-react package:
npm install embla-carousel-react
Basic Usage
The React integration is built around the useEmblaCarousel hook. This hook initializes the carousel and manages its lifecycle. You simply need to attach the returned emblaRef to the element that acts as the viewport of your carousel.
import React from 'react'
import useEmblaCarousel from 'embla-carousel-react'
export function EmblaCarousel() {
const [emblaRef] = useEmblaCarousel()
return (
<div className="embla" ref={emblaRef}>
<div className="embla__container">
<div className="embla__slide">Slide 1</div>
<div className="embla__slide">Slide 2</div>
<div className="embla__slide) index">Slide 3</div>
</div>
</div>
)
}
The useEmblaCarousel Hook
The hook accepts two optional arguments and returns a tuple containing a ref and the api.
Parameters
| Parameter | Type | Description |
| :--- | :--- | :--- |
| options | EmblaOptionsType | Configuration object for the carousel (e.g., loop, align, axis). |
| plugins | EmblaPluginType[] | An array of plugins to extend functionality (e.g., Autoplay). |
Return Values
| Value | Type | Description |
| :--- | :--- | :--- |
| emblaRef | (node: HTMLElement \| null) => void | A callback ref to be attached to the viewport element. |
| emblaApi | EmblaCarouselType \| undefined | The API instance, available once the carousel is initialized. |
Accessing the API
The emblaApi allows you to interact with the carousel programmatically. Because the API is initialized asynchronously when the ref is attached, you should interact with it inside a useEffect hook.
import React, { useEffect } from 'react'
import useEmblaCarousel from 'embla-carousel-react'
export function EmblaCarousel() {
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true })
useEffect(() => {
if (emblaApi) {
console.log(emblaApi.slideNodes()) // Access slides
}
}, [emblaApi])
return (
<div className="embla" ref={emblaRef}>
<div className="embla__container">
{/* Slides go here */}
</div>
</div>
)
}
Event Listeners
You can use the API to subscribe to events like select or scroll.
useEffect(() => {
if (!emblaApi) return
const onSelect = () => {
console.log(`Current snap index: ${emblaApi.selectedSnap()}`)
}
emblaApi.on('select', onSelect)
}, [emblaApi])
Using Plugins
Plugins are passed as the second argument to the hook. For plugins to work correctly with React's rendering cycle, they should be initialized within the hook call.
import Autoplay from 'embla-carousel-autoplay'
import useEmblaCarousel from 'embla-carousel-react'
export function EmblaCarousel() {
const [emblaRef] = useEmblaCarousel({ loop: false }, [Autoplay()])
return (
<div className="embla" ref={emblaRef}>
<div className="embla__container">
{/* Slides */}
</div>
</div>
)
}
Global Options
If you want to apply the same configuration to every carousel instance in your application, you can set global options.
import useEmblaCarousel from 'embla-carousel-react'
useEmblaCarousel.globalOptions = { loop: true }
TypeScript
embla-carousel-react is written in TypeScript and provides types for the API and options. This is useful when you need to type your own component props or helper functions.
import { EmblaOptionsType, EmblaCarouselType } from 'embla-carousel'
import useEmblaCarousel from 'embla-carousel-react'
type PropType = {
options?: EmblaOptionsType
}
export const EmblaCarousel: React.FC<PropType> = (props) => {
const { options } = props
const [emblaRef, emblaApi] = useEmblaCarousel(options)
// ...
}