Sliders are one of the most requested storefront features — and one of the most common causes of slow pages. This guide shows two approaches: Slick Carousel loaded through RequireJS for Luma themes, and a lightweight Alpine.js slider using CSS scroll snap for Hyvä, with no jQuery at all.

Download Slick's JavaScript and CSS into your theme or module, then declare it in requirejs-config.js with jQuery as a dependency:

// app/design/frontend/MageServices/luma-child/requirejs-config.js
var config = {
    paths: {
        slick: 'js/slick.min'
    },
    shim: {
        slick: {
            deps: ['jquery']
        }
    }
};

Initialise it in a template with data-mage-init, passing options as escaped JSON. The slider below shows four items on desktop and one on small screens:

<?php
/** @var \Magento\Framework\Escaper $escaper */
$options = [
    'slidesToShow' => 4,
    'slidesToScroll' => 1,
    'infinite' => false,
    'responsive' => [
        ['breakpoint' => 1024, 'settings' => ['slidesToShow' => 3]],
        ['breakpoint' => 640, 'settings' => ['slidesToShow' => 1]],
    ],
];
?>
<div class="product-slider"
     data-mage-init='<?= $escaper->escapeHtmlAttr(json_encode(['slick' => $options])) ?>'>
    <!-- slide items rendered here -->
</div>

Because Slick is a jQuery plugin, data-mage-init can call it directly with the options object. Load Slick's CSS in your theme's default_head_blocks.xml or include its styles in your LESS.

Option 2: An Alpine.js Slider for Hyvä

Hyvä does not load jQuery or RequireJS. Modern browsers can do most of a slider's work with CSS scroll snap; Alpine.js only adds the buttons:

<?php
/** @var \Magento\Framework\Escaper $escaper */
/** @var array<int, array{name: string, url: string, image: string}> $items */
?>
<section x-data="{
            scrollBy(direction) {
                const track = this.$refs.track;
                track.scrollBy({ left: direction * track.clientWidth * 0.8, behavior: 'smooth' });
            }
         }"
         class="relative"
         aria-label="<?= $escaper->escapeHtmlAttr(__('Featured products')) ?>">
    <div x-ref="track"
         class="flex snap-x snap-mandatory gap-4 overflow-x-auto scroll-smooth pb-4"
         tabindex="0">
        <?php foreach ($items as $item): ?>
            <a href="<?= $escaper->escapeUrl($item['url']) ?>"
               class="w-3/4 shrink-0 snap-start sm:w-1/3 lg:w-1/4">
                <img src="<?= $escaper->escapeUrl($item['image']) ?>"
                     alt="<?= $escaper->escapeHtmlAttr($item['name']) ?>"
                     width="300" height="300" loading="lazy" class="w-full rounded-md">
                <span class="mt-2 block text-sm font-medium"><?= $escaper->escapeHtml($item['name']) ?></span>
            </a>
        <?php endforeach; ?>
    </div>
    <button type="button" class="btn btn-secondary absolute left-0 top-1/3"
            @click="scrollBy(-1)" aria-label="<?= $escaper->escapeHtmlAttr(__('Previous')) ?>">‹</button>
    <button type="button" class="btn btn-secondary absolute right-0 top-1/3"
            @click="scrollBy(1)" aria-label="<?= $escaper->escapeHtmlAttr(__('Next')) ?>">›</button>
</section>

The slider remains usable without JavaScript (users can swipe or scroll), works with keyboard focus on the track, and adds almost no weight to the page. Prepare $items in a ViewModel.

Performance and Accessibility Tips

  • Do not lazy-load the first visible slide if it is the page's LCP image.
  • Avoid auto-rotating sliders; if you must, provide a pause control.
  • Set image width and height to prevent layout shift.
  • Limit the number of slides; each one adds images and DOM nodes.

Feeding the Slider From a ViewModel

Whichever slider you use, prepare the items in PHP. A ViewModel that loads, for example, products from a category with a product collection and returns only the name, URL and resized image URL keeps the template simple and lets you limit how many items are loaded. Use Magento's image helper or Hyvä's image ViewModels to request an image size that matches the slide width rather than loading full-size images.

Should You Use a Slider at All?

Usability studies and analytics on many stores show that few visitors interact with homepage carousels beyond the first slide. A static hero with one clear message, followed by a scrollable row of products, often performs better and is faster. Product carousels for "related" or "recently viewed" items are more useful because they help customers continue browsing. If you keep a slider, measure clicks on each slide and remove slides nobody uses.

Frequently Asked Questions

Can I use Slick Slider with Hyvä?

You can, but it requires jQuery, which removes much of Hyvä's performance benefit. A scroll-snap slider with Alpine.js is lighter.

Does Page Builder include a slider?

Yes. Page Builder has a Slider content type for banners, and Hyvä provides compatible rendering for Page Builder content.

🚀

Need help with this on your store?

Our Magento engineers can implement it for you, review your code or take on the whole project.

Explore Magento Extension Development
MS
About the author

Written by the Magento Services engineering team — Magento 2, Adobe Commerce and Hyvä specialists since 2014. We write about problems we solve on real client stores.