Large dataset (50 slides)

Only the active slide ± 2 neighbours are rendered in the DOM at once. The other 45 slides are empty placeholders. Navigate and inspect the DOM — you'll see content appear and disappear as you move through.

View code
<div class="c--slider-a" id="my-slider">
  <!-- Wrapper is populated by JS before init -->
  <div class="c--slider-a__wrapper" id="my-wrapper"></div>
</div>
<div id="my-pag" class="c--slider-a__pagination"></div>
.c--slider-a { position: relative; width: 100%; overflow: hidden; }
.c--slider-a__wrapper { display: flex; will-change: transform; }
.c--slider-a__slide { flex-shrink: 0; width: 100%; height: 260px; }
.c--slider-a {
  position: relative;
  width: 100%;
  overflow: hidden;

  &__wrapper {
    display: flex;
    will-change: transform;
  }

  &__slide {
    flex-shrink: 0;
    width: 100%;
    height: 260px;
  }
}
import { Slider } from '@andresclua/sliderkit'
import { arrows, virtualSlides, pagination } from '@andresclua/sliderkit-plugins'

// Build slides in JS before init
const wrapper = document.getElementById('my-wrapper')
for (let i = 0; i < 50; i++) {
  const slide = document.createElement('div')
  slide.className = 'c--slider-a__slide'
  slide.setAttribute('data-slide', '')
  slide.textContent = String(i + 1)
  wrapper.appendChild(slide)
}

new Slider('#my-slider', {
  loop: false,
  rewind: true,
  plugins: [
    virtualSlides({ preRender: 2 }), // render active ± 2
    arrows(),
    pagination({ el: '#my-pag', type: 'fraction' }),
  ],
})

Dynamic content on demand

Combine virtualSlides with an async fetch — only request the content for slides that are about to be rendered. The onRender callback fires when a slide enters the preRender window, letting you populate it just in time.

View code
<div class="c--slider-a" id="my-slider">
  <div class="c--slider-a__wrapper" id="my-wrapper"></div>
</div>
<div id="my-pag" class="c--slider-a__pagination"></div>
.c--slider-a { position: relative; width: 100%; overflow: hidden; }
.c--slider-a__wrapper { display: flex; will-change: transform; }
.c--slider-a__slide {
  flex-shrink: 0; width: 100%; height: 260px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1rem; color: #6b7280;
}
.slide-loaded {
  font-size: 2rem; font-weight: 700; color: #fff;
}
.slide-loaded {
  font-size: 2rem;
  font-weight: 700;
  color: #fff;
}

.c--slider-a {
  position: relative;
  width: 100%;
  overflow: hidden;

  &__wrapper {
    display: flex;
    will-change: transform;
  }

  &__slide {
    flex-shrink: 0;
    width: 100%;
    height: 260px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    color: #6b7280;
  }
}
import { Slider } from '@andresclua/sliderkit'
import { arrows, virtualSlides, pagination } from '@andresclua/sliderkit-plugins'

const TOTAL = 100
const wrapper = document.getElementById('my-wrapper')

// Create empty placeholder slides
for (let i = 0; i < TOTAL; i++) {
  const slide = document.createElement('div')
  slide.className = 'c--slider-a__slide'
  slide.setAttribute('data-slide', '')
  slide.setAttribute('data-index', String(i))
  slide.textContent = 'Loading…'
  wrapper.appendChild(slide)
}

// Simulate async content fetch
async function loadSlide(slide, index) {
  await new Promise(r => setTimeout(r, 80)) // simulated network delay
  slide.textContent = String(index + 1)
  slide.classList.add('slide-loaded')
}

new Slider('#my-slider', {
  loop: false,
  rewind: true,
  plugins: [
    virtualSlides({
      preRender: 3,
      onRender: (slide) => {
        const index = parseInt(slide.getAttribute('data-index'), 10)
        if (!slide.classList.contains('slide-loaded')) {
          loadSlide(slide, index)
        }
      },
    }),
    arrows(),
    pagination({ el: '#my-pag', type: 'fraction' }),
  ],
})