title | description | order | date |
---|---|---|---|
Plugins |
Learn how to add plugins to Embla Carousel and extend it. |
3 |
2021-11-06 |
import { Tabs } from 'components/Tabs/Tabs' import { TabsItem } from 'components/Tabs/TabsItem' import { TABS_LIBRARY } from 'consts/tabs' import { TABS_PACKAGE_MANAGER } from 'consts/tabs'
It's possible to extend Embla carousel with additional features using plugins. The complete list of official plugins can be found here.
All official plugins are separate NPM packages. They're all prefixed with embla-carousel
followed by its unique plugin name. For example, the Autoplay
plugin is installed like so:
<script src="https://unpkg.com/embla-carousel-autoplay/embla-carousel-autoplay.umd.js"></script>
npm install embla-carousel-autoplay --save
yarn add embla-carousel-autoplay
The Embla Carousel constructor accepts an array of plugins. Each plugin might have its own options, methods and events.
The constructor plugin array is the default way of providing plugins to Embla Carousel. In the following example, the Autoplay plugin is added to the carousel:
import EmblaCarousel from 'embla-carousel'
import Autoplay from 'embla-carousel-autoplay'
const emblaNode = document.querySelector('.embla')
const embla = EmblaCarousel(emblaNode, { loop: true }, [Autoplay()])
import useEmblaCarousel from 'embla-carousel-react'
import Autoplay from 'embla-carousel-autoplay'
export function EmblaCarousel() {
const [emblaRef] = useEmblaCarousel({ loop: true }, [Autoplay()])
// ...
}
<script setup>
import emblaCarouselVue from 'embla-carousel-vue'
import Autoplay from 'embla-carousel-autoplay'
const [emblaRef] = emblaCarouselVue({ loop: true }, [Autoplay()])
// ...
</script>
import createEmblaCarousel from 'embla-carousel-solid'
import Autoplay from 'embla-carousel-autoplay'
export function EmblaCarousel() {
const [emblaRef] = createEmblaCarousel(
() => ({ loop: true }),
() => [AutoPlay()]
)
// ...
}
<script>
import emblaCarouselSvelte from 'embla-carousel-svelte'
import Autoplay from 'embla-carousel-autoplay'
let plugins = [Autoplay()]
</script>
<div class="embla" use:emblaCarouselSvelte="{{ plugins }}">...</div>
Plugins have their own specific options which is the first argument of the plugin constructor. This allows for configuring the plugin to your liking:
import EmblaCarousel from 'embla-carousel'
import Autoplay from 'embla-carousel-autoplay'
const emblaNode = document.querySelector('.embla')
const embla = EmblaCarousel(emblaNode, { loop: true }, [
Autoplay({ delay: 4000 })
])
import useEmblaCarousel from 'embla-carousel-react'
import Autoplay from 'embla-carousel-autoplay'
export function EmblaCarousel() {
const [emblaRef] = useEmblaCarousel({ loop: true }, [
Autoplay({ delay: 4000 })
])
// ...
}
<script setup>
import emblaCarouselVue from 'embla-carousel-vue'
import Autoplay from 'embla-carousel-autoplay'
const [emblaRef] = emblaCarouselVue({ loop: true }, [
Autoplay({ delay: 4000 })
])
// ...
</script>
import createEmblaCarousel from 'embla-carousel-solid'
import Autoplay from 'embla-carousel-autoplay'
export function EmblaCarousel() {
const [emblaRef] = createEmblaCarousel(
() => ({ loop: true }),
() => [AutoPlay({ delay: 4000 })]
)
// ...
}
<script>
import emblaCarouselSvelte from 'embla-carousel-svelte'
import Autoplay from 'embla-carousel-autoplay'
let plugins = [Autoplay({ delay: 4000 })]
</script>
<div class="embla" use:emblaCarouselSvelte="{{ plugins }}">...</div>
All official plugins allows you to set global options that will be applied to all instances. This allows for overriding the default plugin options with your own:
import EmblaCarousel from 'embla-carousel'
import Autoplay from 'embla-carousel-autoplay'
Autoplay.globalOptions = { delay: 4000 }
const emblaNode = document.querySelector('.embla')
const embla = EmblaCarousel(emblaNode, { loop: true }, [Autoplay()])
import useEmblaCarousel from 'embla-carousel-react'
import Autoplay from 'embla-carousel-autoplay'
Autoplay.globalOptions = { delay: 4000 }
export function EmblaCarousel() {
const [emblaRef] = useEmblaCarousel({ loop: true }, [Autoplay()])
// ...
}
<script setup>
import emblaCarouselVue from 'embla-carousel-vue'
import Autoplay from 'embla-carousel-autoplay'
Autoplay.globalOptions = { delay: 4000 }
const [emblaRef] = emblaCarouselVue({ loop: true }, [Autoplay()])
// ...
</script>
import createEmblaCarousel from 'embla-carousel-solid'
import Autoplay from 'embla-carousel-autoplay'
Autoplay.globalOptions = { delay: 4000 }
export function EmblaCarousel() {
const [emblaRef] = createEmblaCarousel(
() => ({ loop: true }),
() => [AutoPlay()]
)
// ...
}
<script>
import emblaCarouselSvelte from 'embla-carousel-svelte'
import Autoplay from 'embla-carousel-autoplay'
Autoplay.globalOptions = { delay: 4000 }
let plugins = [Autoplay()]
</script>
<div class="embla" use:emblaCarouselSvelte="{{ plugins }}">...</div>
Additionally, some plugins expose their own API methods. You can access plugin methods by calling the plugin method like demonstrated below:
import EmblaCarousel from 'embla-carousel'
import Autoplay from 'embla-carousel-autoplay'
const emblaNode = document.querySelector('.embla')
const emblaApi = EmblaCarousel(emblaNode, { loop: true }, [Autoplay()])
emblaApi.plugins().autoplay.stop()
import { useEffect } from 'react'
import useEmblaCarousel from 'embla-carousel-react'
import Autoplay from 'embla-carousel-autoplay'
export function EmblaCarousel() {
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }, [Autoplay()])
useEffect(() => {
if (emblaApi) emblaApi.plugins().autoplay.stop()
}, [emblaApi])
// ...
}
<script setup>
import { onMounted } from 'vue'
import emblaCarouselVue from 'embla-carousel-vue'
import Autoplay from 'embla-carousel-autoplay'
const [emblaRef, emblaApi] = emblaCarouselVue({ loop: true }, [Autoplay()])
onMounted(() => {
if (emblaApi.value) emblaApi.value.plugins().autoplay.stop()
})
// ...
</script>
import { onMount } from 'solid-js'
import createEmblaCarousel from 'embla-carousel-solid'
import Autoplay from 'embla-carousel-autoplay'
export function EmblaCarousel() {
const [emblaRef, emblaApi] = createEmblaCarousel(
() => ({ loop: true }),
() => [AutoPlay()]
)
onMount(() => {
const api = emblaApi()
if (api) api.plugins().autoplay.stop()
})
// ...
}
<script>
import emblaCarouselSvelte from 'embla-carousel-svelte'
import Autoplay from 'embla-carousel-autoplay'
let emblaApi
let plugins = [Autoplay()]
function onInit(event) {
emblaApi = event.detail
emblaApi.plugins().autoplay.stop()
}
</script>
<div
class="embla"
use:emblaCarouselSvelte="{{ plugins }}"
on:emblaInit="{onInit}"
>
...
</div>
Some plugins fire their own events. Plugin events are structured as follows <plugin-name>:eventname
. Adding and removing plugin event listeners is done the same way as native Embla events. Here's an example where an event is added to the autoplay plugin:
import EmblaCarousel from 'embla-carousel'
import Autoplay from 'embla-carousel-autoplay'
const emblaNode = document.querySelector('.embla')
const emblaApi = EmblaCarousel(emblaNode, { loop: true }, [Autoplay()])
function logPluginEvent(emblaApi, eventName) {
console.log(`Autoplay just triggered ${eventName}!`)
}
emblaApi.on('autoplay:stop', logPluginEvent)
import { useEffect, useCallback } from 'react'
import useEmblaCarousel from 'embla-carousel-react'
import Autoplay from 'embla-carousel-autoplay'
export function EmblaCarousel() {
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }, [Autoplay()])
const logPluginEvent = useCallback((emblaApi, eventName) => {
console.log(`Autoplay just triggered ${eventName}!`)
}, [])
useEffect(() => {
if (emblaApi) emblaApi.on('autoplay:stop', logPluginEvent)
}, [emblaApi, logPluginEvent])
// ...
}
<script setup>
import { onMounted } from 'vue'
import emblaCarouselVue from 'embla-carousel-vue'
import Autoplay from 'embla-carousel-autoplay'
const [emblaRef, emblaApi] = emblaCarouselVue({ loop: true }, [Autoplay()])
function logPluginEvent(emblaApi, eventName) {
console.log(`Autoplay just triggered ${eventName}!`)
}
onMounted(() => {
if (emblaApi.value) emblaApi.value.on('autoplay:stop', logPluginEvent)
})
// ...
</script>
import { onMount } from 'solid-js'
import createEmblaCarousel from 'embla-carousel-solid'
import Autoplay from 'embla-carousel-autoplay'
export function EmblaCarousel() {
const [emblaRef, emblaApi] = createEmblaCarousel(
() => ({ loop: true }),
() => [AutoPlay()]
)
function logPluginEvent(emblaApi, eventName) {
console.log(`Autoplay just triggered ${eventName}!`)
}
onMount(() => {
const api = emblaApi()
if (api) api.on('autoplay:stop', logPluginEvent)
})
// ...
}
<script>
import emblaCarouselSvelte from 'embla-carousel-svelte'
import Autoplay from 'embla-carousel-autoplay'
let emblaApi
let plugins = [Autoplay()]
function logPluginEvent(emblaApi, eventName) {
console.log(`Autoplay just triggered ${eventName}!`)
}
function onInit(event) {
emblaApi = event.detail
emblaApi.on('autoplay:stop', logPluginEvent)
}
</script>
<div
class="embla"
use:emblaCarouselSvelte="{{ plugins }}"
on:emblaInit="{onInit}"
>
...
</div>
The EmblaPluginType
is obtained directly from the core package embla-carousel
and used like so:
import EmblaCarousel, { EmblaPluginType } from 'embla-carousel'
import Autoplay from 'embla-carousel-autoplay'
const emblaNode = document.querySelector('.embla')
const plugins: EmblaPluginType[] = [Autoplay()]
const emblaApi = EmblaCarousel(emblaNode, { loop: true }, plugins)
import React from 'react'
import { EmblaPluginType } from 'embla-carousel'
import useEmblaCarousel from 'embla-carousel-react'
import Autoplay from 'embla-carousel-autoplay'
type PropType = {
plugins?: EmblaPluginType[]
}
export function EmblaCarousel(props) {
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }, props.plugins)
// ...
}
This is because even though `embla-carousel-react` has `embla-carousel` as a dependency, `pnpm` makes nested dependencies inaccessible by design.
<script setup lang="ts">
import { EmblaPluginType } from 'embla-carousel'
import emblaCarouselVue from 'embla-carousel-vue'
import Autoplay from 'embla-carousel-autoplay'
const plugins: EmblaPluginType[] = [Autoplay()]
const [emblaRef] = emblaCarouselVue({ loop: true }, plugins)
// ...
</script>
This is because even though `embla-carousel-vue` has `embla-carousel` as a dependency, `pnpm` makes nested dependencies inaccessible by design.
import { EmblaPluginType } from 'embla-carousel'
import createEmblaCarousel from 'embla-carousel-solid'
import Autoplay from 'embla-carousel-autoplay'
type PropType = {
plugins?: EmblaPluginType[]
}
export function EmblaCarousel(props) {
const [emblaRef, emblaApi] = createEmblaCarousel(
() => ({ loop: true }),
props.plugins
)
// ...
}
This is because even though `embla-carousel-solid` has `embla-carousel` as a dependency, `pnpm` makes nested dependencies inaccessible by design.
<script>
import { EmblaPluginType } from 'embla-carousel'
import emblaCarouselSvelte from 'embla-carousel-svelte'
import Autoplay from 'embla-carousel-autoplay'
let emblaApi
let plugins: EmblaPluginType[] = [Autoplay()]
</script>
<div class="embla" use:emblaCarouselSvelte="{{ plugins }}">...</div>
This is because even though `embla-carousel-svelte` has `embla-carousel` as a dependency, `pnpm` makes nested dependencies inaccessible by design.