Vue-ssr-carousel - Performant Carousel Component

A performance focused Vue carousel designed for SSR/SSG environments. No JS is used to layout the carousel or it's slides. The goal is to improve LCP and CLS scores because there is no layout or markup changes when JS hydates. It's primarily designed for rendering "card" style slides (like for linking to articles or products) where the carousel-ness is conditionally applied based on the number of cards that are slotted in as well as the viewport width.

Check out the demo:


yarn add vue-ssr-carousel


import SsrCarousel from 'vue-ssr-carousel'
import ssrCarouselCss from 'vue-ssr-carousel/index.css'
Vue.component 'ssr-carousel', SsrCarousel


// nuxt.config.js
export default {
  buildModules: [ 'vue-ssr-carousel/nuxt' ]


  <div class="slide">Slide 1</div>
  <div class="slide">Slide 2</div>
  <div class="slide">Slide 3</div>

For more examples, see the demo:


  • If your slides are generated with v-for, use key values that are based on the data you are looping through. In other words, do v-for='slide in slides' :key='' rather that v-for='slide, index in slides' :key='index'.
  • Don't use v-if on the root element of slide components.



Props Default Description
slides-per-page 1 How many slides are shown per page. Can be set to null to allow for flexible widths for slides. See and note the caveats mentiond within.
gutter 20 The size of the space between slides. This can a number or any CSS resolvable string. See
paginate-by-slide false When false, dragging the carousel or interacting with the arrows will advance a full page of slides at a time. When true, the carousel will come to a rest at each slide.
pagination-label null Customizes the label used in aria labels to describe a page.
autoplay-delay 0 Add a delay in seconds for auto playing the slides. See
loop false Boolean to enable looping / infinite scroll. See
center false Render the first slide in the middle of the carousel. Should only be used with odd numbers of slides-per-page. This results in the slides being rendered visually in a different order than the DOM which is an accessibility concern. See
peek 0 A width value for how far adjacent cards should peek into the carousel canvas. This can a number or any CSS resolvable string. See
peek-left 0 Set peek value on just the left edge.
peek-right 0 Set peek value on just the right edge.
peek-gutter false Set peek value equal to gutter value.
feather false Fades out the left and right edges using a CSS mask-image gradient. Set to true to use the default 20px value or as number or any CSS resolvable string to set an explicit width. This is designed to be used with peek properties. See
overflow-visible false Disables the overflow:hidden that wraps the slide track. You would do this if you want to handle that masking in an ancestor element. See
no-drag false Disables the ability to drag the carousel.
show-arrows false Whether to show back/forward arrows. See
show-dots false Whether to show dot style pagination dots. See
value undefined Used as part of v-model to set the initial slide to show. See
responsive [] Adjust settings at breakpoints. See Note, loop and paginate-by-slide cannot be set responsively.


Slots Description
default Where your slides get injected.
back-arrow Replace the default back icon. Slot props:
disabled - True if at first page when not looping.
next-arrow Replace the default next icon. Slot props:
disabled - True if at last page when not looping.
dot Replace the default pagination dots. Slot props:
index - The page index that the dot represents.
disabled - True if dot represents current page.


Methods Description
next() Go forward a page or slide, depending on the paginate-by-slide prop
back() Go back a page or slide, depending on the paginate-by-slide prop
goto(index) Go to an index. If paginate-by-slide is false, this equates to a page offset. If true, this equates to a slide offset.



Events Description
change({ index }) Fired when the internal index counter changes.
input Same as change but intended for use with v-model.
press Fired on mouse or touch down.
release Fired on mouse or touch up.
drag:start Fired on start of dragging.
drag:end Fired on end of dragging.
tween:start({ index }) Fired when the carousel starts tweening to it's final position.
tween:end({ index }) Fired when the carousel has finished tweening to it's destination.