Skip to content

Carousels · Open source

Laravel Swiper

Swiper sliders, carousels and image galleries for Laravel as Blade components.

Laravel 12 and 13 PHP 8.3+ v1.0.1 Free · MIT
Laravel Swiper: Swiper sliders, carousels and image galleries for Laravel as Blade components.

What it solves

Dropping Swiper into a Laravel app is quick, but a Livewire update morphs its markup back to the server HTML: arrows double up, the slide jumps back to the start, and after wire:navigate it never starts.

The images also come from storage or models, not a hard-coded array, and carousel accessibility is easy to get wrong.

Navigation, pagination, thumbs, autoplay and effects are typed props on <x-swiper>. Slides come from your own markup, a collection of models or Spatie Media items, or a folder on a storage disk, and a carousel is rebuilt only when its content changed, on the same slide.

  • Typed, validated props for navigation, pagination, thumbs, autoplay, effects and breakpoints
  • Unchanged carousels survive Livewire updates; changed ones are rebuilt on the same slide
  • Starts again after wire:navigate, with no duplicate scripts
  • Image slides from paths, URLs, Eloquent models, Spatie Media items or a storage disk folder, private disks included
  • Lazy images with a fixed aspect ratio, a high-priority first image, and srcset from your image resizer
  • Labelled carousel region, button arrows, a pause button for autoplay, and prefers-reduced-motion support
An image carousel titled Folder on the public disk, with thumbs: a large blue slide labelled 1, lake at dawn, with previous and next arrows and pagination bullets, above a strip of six thumbnails with the first one highlighted.
An image carousel titled Folder on the public disk, with thumbs: a large blue slide labelled 1, lake at dawn, with previous and next arrows and pagination bullets, above a strip of six thumbnails with the first one highlighted.

Install

Requires PHP 8.3+ and Laravel 12 and 13.

composer require amjadiqbal/laravel-swiper

Usage

{{-- Every image in storage/app/public/gallery, with a thumbnail strip --}}
<x-swiper folder="gallery" disk="public" thumbs />

{{-- Any markup you like --}}
<x-swiper loop :autoplay="5000" label="Customer stories">
    @foreach ($stories as $story)
        <x-swiper.slide><x-story-card :story="$story" /></x-swiper.slide>
    @endforeach
</x-swiper>

Setup

The first <x-swiper> on a page prints Swiper 14.3.0 from jsDelivr, with Subresource Integrity hashes, and a small runtime. With Livewire, also put @swiperAssets in your layout's <head>.

<head>
    ...
    @swiperAssets
</head>

Slides and image carousels

:images takes paths, URLs, arrays, objects, Eloquent models or Spatie Media items. Without image-field it tries image, src, url, path, photo and cover; each *-field accepts dot notation or a closure. folder lists every image file directly in that folder, in natural order, and builds alt text from the file name. Paths are turned into URLs with the disk's url(). For a private disk or bucket, set swiper.images.temporary_urls to a number of minutes (for every disk, or per disk) and they use temporaryUrl() instead. Slide links from link-field only allow http(s), mailto, tel and relative URLs, so a javascript: URL in your data is dropped.

<x-swiper :images="$products"
          image-field="cover.path"
          :alt-field="fn ($p) => $p->name.' in '.$p->colour"
          caption-field="tagline"
          link-field="url" />

<x-swiper :images="$post->getMedia('gallery')" conversion="large" thumbs />

Responsive images

Laravel stores one file per image, so srcset needs an image CDN or resizer. Set srcset_url in config/swiper.php, or build the URLs with Swiper::srcsetUsing(). Spatie Media items use their own srcset. sizes is worked out from slides-per-view and breakpoints; [768 => 2] gives (min-width: 768px) 50vw, 100vw. SVGs never get a srcset.

// config/swiper.php
'images' => [
    'srcset_url' => '{url}?w={width}&fm=webp',
    'widths' => [480, 800, 1200, 1600, 2000],
],

Livewire and wire:navigate

Nothing to set up. A carousel stays as it is when an update does not change it, is rebuilt on the same slide when its slides or options change, and starts again after wire:navigate. If the visitor paused autoplay, it stays paused. swiper:init and swiper:slide-change events bubble from the carousel.

$this->dispatch('swiper:go', id: 'gallery', index: 2);   // Livewire

<button @click="$dispatch('swiper:go', { id: 'gallery', index: 0 })">Back to start</button>   {{-- Alpine --}}

Accessibility and assets

  • Each carousel is a region with your label (Carousel by default) and an aria-roledescription of carousel; each slide is labelled such as 2 of 5.
  • Arrows are <button> elements with labels, and pagination bullets are labelled Go to slide 3.
  • Autoplay adds a pause/play button and pauses while keyboard focus is inside or the mouse is over the carousel.
  • With prefers-reduced-motion: reduce there is no autoplay and slides change instantly (swiper.reduced_motion turns this off).
  • Arrow keys, Home and End move only the carousel in use.
  • SWIPER_ASSETS is cdn (the default), local (publish with --tag=swiper-assets) or none (you load Swiper with Vite). Messages are published with --tag=swiper-translations and the config with --tag=swiper-config.

Hire me

Need this built into your app, or something custom?

I wrote Laravel Swiper. I can wire it into your Laravel app, extend it for your case, or build the feature around it. Tell me what you need and you'll get a plan and a quote, free.

Support

Found a bug or want a feature? Open an issue on GitHub. For help adding it to your own project, use the quote form above.

More Laravel packages

All packages
Laravel Driver.js: Build Driver.js product tours in PHP and render them with one Blade component.

Laravel Driver.js

Build Driver.js product tours in PHP and render them with one Blade component.

Laravel Sonner: Sonner toast notifications for Laravel, sent from PHP and shown without React.

Laravel Sonner

Sonner toast notifications for Laravel, sent from PHP and shown without React.

Laravel Ninja Keys: A Cmd+K / Ctrl+K command palette for Laravel, with the actions defined in PHP.

Laravel Ninja Keys

A Cmd+K / Ctrl+K command palette for Laravel, with the actions defined in PHP.

Laravel SweetAlert2: SweetAlert2 popups, toasts and confirm dialogs from Laravel controllers, Livewire and Alpine.

Laravel SweetAlert2

SweetAlert2 popups, toasts and confirm dialogs from Laravel controllers, Livewire and Alpine.

Laravel Grid.js: Turn any Eloquent query into a searchable, sortable, paginated Grid.js data table with one fluent PHP call.

Laravel Grid.js

Turn any Eloquent query into a searchable, sortable, paginated Grid.js data table with one fluent PHP call.

Laralink: Work on a Composer package inside the Laravel app that uses it, then switch back to the Packagist release.

Laralink

Work on a Composer package inside the Laravel app that uses it, then switch back to the Packagist release.

Refresher: A drop-in replacement for Laravel's RefreshDatabase that restores a cached snapshot of your test database instead of running migrate:fresh.

Refresher

A drop-in replacement for Laravel's RefreshDatabase that restores a cached snapshot of your test database instead of running migrate:fresh.

Kiln: Artisan commands and an optional signed HTTP route to clear, warm and inspect OPcache when you deploy.

Kiln

Artisan commands and an optional signed HTTP route to clear, warm and inspect OPcache when you deploy.

Laravel Media Viewer: Show private PDFs, video and audio from any Laravel disk without making the files public.

Laravel Media Viewer

Show private PDFs, video and audio from any Laravel disk without making the files public.

Laravel MySQL Advisor: Read-only health checks for the MySQL or MariaDB database behind your Laravel app, with the SQL and the Laravel migration to fix a problem wherever a fix applies.

Laravel MySQL Advisor

Read-only health checks for the MySQL or MariaDB database behind your Laravel app, with the SQL and the Laravel migration to fix a problem wherever a fix applies.

Laravel Webhook Console: A dashboard and replay tool for the webhooks spatie/laravel-webhook-client stores in your Laravel app.

Laravel Webhook Console

A dashboard and replay tool for the webhooks spatie/laravel-webhook-client stores in your Laravel app.

Laravel Pennant Dashboard: A browser dashboard for laravel/pennant feature flags: per-scope toggles, sticky percentage rollouts, purge and an audit log.

Laravel Pennant Dashboard

A browser dashboard for laravel/pennant feature flags: per-scope toggles, sticky percentage rollouts, purge and an audit log.

Laravel Notification Inbox: Catches every non-mail Laravel notification in local and staging instead of sending it, and shows each one as it would look on the other end.

Laravel Notification Inbox

Catches every non-mail Laravel notification in local and staging instead of sending it, and shows each one as it would look on the other end.

Laravel WebPush Kit: The browser side of Laravel web push: a subscribe button with a two-step permission prompt, a service worker, and routes that save each user's subscription. Tested in Chrome so far.

Laravel WebPush Kit

The browser side of Laravel web push: a subscribe button with a two-step permission prompt, a service worker, and routes that save each user's subscription. Tested in Chrome so far.

Laravel Redis Advisor: Read-only health checks for the Redis or Valkey behind your Laravel cache, queues, sessions and Horizon, with the redis.conf line or Laravel config that fixes each problem.

Laravel Redis Advisor

Read-only health checks for the Redis or Valkey behind your Laravel cache, queues, sessions and Horizon, with the redis.conf line or Laravel config that fixes each problem.

Need something built?

Free quote in 60 seconds