Events

Embla Carousel provides a set of events you can listen to for reacting to carousel updates and user interactions.


Usage

Events are available only on an initialized carousel instance. They fire throughout the carousel's lifecycle, and any added listeners remain active even after a hard reset with the reInit method.

Adding event listeners

After initializing the carousel, you can subscribe to events. The following example shows how to listen for the slidesinview event:

import EmblaCarousel from 'embla-carousel'
const wrapperNode = document.querySelector('.embla')const viewportNode = wrapperNode.querySelector('.embla__viewport')
const emblaApi = EmblaCarousel(viewportNode, { loop: true })
const logSlidesInView = (emblaApi, event) => {  console.log(`${event.type}: ${event.detail.slidesInView}`)}
emblaApi.on('slidesinview', logSlidesInView)
<div class="embla">  <div class="embla__viewport">    <div class="embla__container">      <div class="embla__slide">Slide 1</div>      <div class="embla__slide">Slide 2</div>      <div class="embla__slide">Slide 3</div>    </div>  </div></div>

Removing event listeners

To remove an event listener, call the off method and pass the same callback reference that was originally used with on.

import EmblaCarousel from 'embla-carousel'
const wrapperNode = document.querySelector('.embla')const viewportNode = wrapperNode.querySelector('.embla__viewport')
const emblaApi = EmblaCarousel(viewportNode, { loop: true })
const logSlidesInViewOnce = (emblaApi, event) => {  console.log(`${event.type}: ${event.detail.slidesInView}`)  emblaApi.off('slidesinview', logSlidesInViewOnce)}
emblaApi.on('slidesinview', logSlidesInViewOnce)
<div class="embla">  <div class="embla__viewport">    <div class="embla__container">      <div class="embla__slide">Slide 1</div>      <div class="embla__slide">Slide 2</div>      <div class="embla__slide">Slide 3</div>    </div>  </div></div>

Cancelling events

Some events are cancellable, allowing you to prevent Embla Carousel's internal logic from running. To cancel an event, return false from the event handler. Returning any other value—such as true or undefined—will allow the event to proceed normally.

See the event reference to check which events are cancellable.

This code prevents pointer events (dragging) on the carousel whenever the allowPointerDownEvent variable is false.

import EmblaCarousel from 'embla-carousel'
const wrapperNode = document.querySelector('.embla')const viewportNode = wrapperNode.querySelector('.embla__viewport')
const emblaApi = EmblaCarousel(viewportNode, { loop: true })let allowPointerDownEvent = false
emblaApi.on('pointerdown', () => {  return allowPointerDownEvent})
<div class="embla">  <div class="embla__viewport">    <div class="embla__container">      <div class="embla__slide">Slide 1</div>      <div class="embla__slide">Slide 2</div>      <div class="embla__slide">Slide 3</div>    </div>  </div></div>

Event data

The event handler receives the event data as the second argument, providing useful information about the event. It includes:

  • type — the name of the event that was triggered.
  • detail — event-specific data. See the event reference for details on the data available for each event.
emblaApi.on('pointerdown', (api, event) => {  console.log('Event name:', event.type)  console.log('Event specific data:', event.detail)})

TypeScript

The EmblaEventModelType is exported from the core embla-carousel package and can be used to type event callback arguments precisely:

import EmblaCarousel, {  EmblaCarouselType,  EmblaEventModelType} from 'embla-carousel'
const wrapperNode = <HTMLElement>document.querySelector('.embla')const viewportNode = <HTMLElement>wrapperNode.querySelector('.embla__viewport')
const emblaApi = EmblaCarousel(viewportNode, { loop: true })
const logSelectEvent = (  emblaApi: EmblaCarouselType,  event: EmblaEventModelType<'select'>): void => {  const { sourceSnap, targetSnap } = event.detail
  console.log('Previous snap index: ', sourceSnap)  console.log('Current snap index: ', targetSnap)}
emblaApi.on('select', logSelectEvent)
<div class="embla">  <div class="embla__viewport">    <div class="embla__container">      <div class="embla__slide">Slide 1</div>      <div class="embla__slide">Slide 2</div>      <div class="embla__slide">Slide 3</div>    </div>  </div></div>

Alternatively, you can use the EmblaEventCallbackType to assign types to a callback constant:

import { EmblaEventCallbackType } from 'embla-carousel'
const logPointerDown: EmblaEventCallbackType<'pointerdown'> = (  emblaApi,  event) => {  console.log(event) // Will contain correct event type and detail}

If you pass the callback directly to the on method, TypeScript will automatically infer the correct types.

emblaApi.on('pointerdown', (emblaApi, event) => {  console.log(event) // Will contain correct event type and detail})

Reference

Below follows an exhaustive list of all Embla Carousel events together with information about how they work.


reinit

emblaApi.on('reinit', (emblaApi) => {})

Runs when the reInit method is called. When the container or any slide sizes change, or when slides are added/removed, Embla Carousel automatically calls the reInit method which will also fire this event.


destroy

emblaApi.on('destroy', (emblaApi) => {})

Runs when the carousel has been destroyed using the destroy method. This only fires once and will be the last event the carousel fires.


select

emblaApi.on('select', (emblaApi, event) => {  const { targetSnap, sourceSnap } = event.detail})

Runs when the selected scroll snap changes. The select event is triggered by drag interactions or the goToNext, goToPrev orgoTo methods.


scroll

emblaApi.on('scroll', (emblaApi, event) => {  const { isDragging } = event.detail})

Runs when the carousel is scrolling. It might be a good idea to throttle this if you're doing expensive stuff in your callback function.


settle

emblaApi.on('settle', (emblaApi) => {})

Runs when the carousel has settled after scroll has been triggered. Please note that this can take longer than you think when dragFree is enabled or when using slow durations.


resize

emblaApi.on('resize', (emblaApi, event) => {  const entries = event.detail})

Runs when the carousel container or the slide sizes change. It's using ResizeObserver under the hood.


slidesinview

emblaApi.on('slidesinview', (emblaApi, event) => {  const { slidesInView, slidesLeftView, slidesEnterView } = event.detail})

Runs when any slide has entered or exited the viewport. slidesInView contains the indexes of all slides currently in view, slidesLeftView contains the indexes of slides that have just exited the viewport, and slidesEnterView contains the indexes of slides that have just entered the viewport.


slideschanged

emblaApi.on('slideschanged', (emblaApi, event) => {  const mutationRecords = event.detail})

Runs when slides are added to, or removed from the carousel container. It's using MutationObserver under the hood.


slidefocus

emblaApi.on('slidefocus', (emblaApi, event) => {  const focusEvent = event.detail})

Runs when a slide receives focus. For example, when a focusable element like a button, link or input receives focus inside a slide.


pointerdown

emblaApi.on('pointerdown', (emblaApi, event) => {  const pointerEvent = event.detail})

Runs when the user has a pointer down on the carousel. It's triggered by a touchstart or a mousedown event.


pointermove

emblaApi.on('pointermove', (emblaApi, event) => {  const pointerEvent = event.detail})

Runs when the user is moving the pointer on the carousel. It's triggered by a touchmove or a mousemove event.


pointerup

emblaApi.on('pointerup', (emblaApi, event) => {  const pointerEvent = event.detail})

Runs when the user has released the pointer from the carousel. It's triggered by a touchend or a mouseup event.


scrolloptimize

emblaApi.on('scrolloptimize', (emblaApi, event) => {  const { slidesInView, slidesLeftView } = event.detail})

Runs when the carousel applies or removes GPU acceleration to slides to optimize scrolling performance. This event is triggered with an in view offset to ensure smooth scrolling performance when slides are entering or leaving the viewport.

Edit this page on GitHub