
Swiper is the JavaScript library that powers every carousel in Elementor: the Image Carousel, Media Carousel, Testimonial Carousel, Loop Carousel, and every third-party Elementor carousel widget you’ve installed. It’s not an Elementor feature. It’s an open-source slider library that Elementor bundles.
Knowing that changes how you debug a broken carousel. When a slider stops working, the problem is almost never the widget. It’s that Swiper didn’t load, didn’t initialise, or initialised before its container had a width.
If you’re here because a working carousel suddenly died, try this before reading anything else:
If the carousel comes back, JS optimisation broke it, and the fix is an exclusion rather than leaving optimisation off. Exact exclusions further down.
Three nested elements. A container, a wrapper inside it, and slides inside that. Swiper reads the container’s width, calculates how much to move the wrapper for each slide, and applies a CSS transform on the wrapper. The slides never move individually; the whole strip slides underneath a window.
Which is why two categories of bug dominate:
The script didn’t run. Nothing initialises, so you see all the slides stacked or in a row with no interaction. Swiper’s CSS is usually still there, so it looks half-styled rather than plainly broken.
The container had no width when it measured. Swiper calculated against zero, so slides overlap, sit at the wrong size, or the track jumps. This is the tab and accordion bug: a carousel inside a hidden panel measures itself while hidden.
The most common cause by a wide margin.
Swiper has to be defined before the inline initialisation code runs. Combining JS reorders files. Deferring pushes execution past the inline call. Delaying JS holds the library back until user interaction, by which time the init already fired and failed.
Open your browser console. If you see Swiper is not defined or Cannot read properties of undefined, this is your problem.
Fix: exclude the swiper handles from optimisation rather than disabling it wholesale. In LiteSpeed Cache that’s under Page Optimization → JS Settings. Add:
swiper
elementor-frontend
jquery-coreOne thing people miss on LiteSpeed: there are separate exclusion fields, and Guest Mode has its own. If you only fill the main JS Excludes box, logged-in users see a working carousel and logged-out visitors don’t, which is exactly the bug that survives testing, because you’re logged in while you test. Put the same exclusions in the Guest Mode field.
WP Rocket: File Optimization → Excluded JavaScript Files, plus the same strings under Delay JavaScript Execution. Autoptimize: Extra → Exclude scripts from Autoptimize.
A carousel in a tab, accordion or off-canvas panel initialises while the panel is display: none. Width reads as zero, and the maths is wrong from the first frame. Open the tab and you get overlapping slides or a track that won’t move.
Fix: most widgets expose an “observer” setting. Turn it on and Swiper watches for size changes and recalculates. If yours doesn’t, put the carousel in the first tab, which is visible on load.
Loop works by cloning slides to fake the wrap-around. It needs at least twice the slides-per-view count to have enough to clone. Four slides at three-per-view produces a visible jump, blank gaps, or a track that stops halfway.
Fix: add slides, or turn loop off. There’s no setting that makes a short loop smooth.
Elementor bundles a version; some addons bundle their own. Both register the same global. Whichever loads second wins, and if a widget was built against a different API, it breaks, often with an error about a method that doesn’t exist.
Fix: in the console, run Swiper.version. Then deactivate addons one at a time until it stops changing. Well-behaved plugins reuse Elementor’s copy rather than shipping their own.
Aggressive image lazy loading, especially a separate lazy-load plugin on top of the theme’s, can leave slide images at zero height until they scroll into view. Except they never scroll into view, because they’re on a horizontal track. Result: a carousel of empty boxes.
Fix: exclude the carousel’s image class from the lazy-load plugin, or set explicit width and height on the images so the boxes reserve space.
Thirty seconds, and it tells you which half of the problem you have.
typeof Swiper and press enter."function" means the library loaded, so your problem is initialisation: look at hidden containers or loop settings. "undefined" means it never arrived, and the cause is JS optimisation or a script that failed earlier in the chain. Scroll up in the console for the first red error, not the last; later errors are usually consequences of the first.
Most widgets expose these under Carousel Settings, sometimes with different labels:
Where these appear in the free Image Carousel widget: the image carousel walkthrough has the panel screenshots.
No, in almost every case. Elementor’s copy is already on the page whenever a carousel widget is present, and adding a second one causes the version conflict above.
The exception is a custom slider on a page with no Elementor carousel widget at all. Then Elementor’s Swiper isn’t enqueued and you need your own. Enqueue it conditionally, on that template only, so you don’t reintroduce the conflict everywhere else.
Swiper is the open-source JavaScript slider library that Elementor uses for all its carousel and slider widgets. Elementor bundles it and enqueues it whenever a carousel widget appears on the page. Most third-party Elementor carousel addons use the same copy rather than shipping their own.
Nine times out of ten it’s JavaScript optimisation from a caching plugin: combine, defer or delay JS reordering the scripts so Swiper isn’t defined when the init code runs. Turn those three off and reload. If the slider returns, add swiper, elementor-frontend and jquery-core to the plugin’s JS exclusions instead of leaving optimisation disabled.
The library didn’t load before the initialisation code ran. Exclude swiper from JS combining, deferring and delaying in your cache plugin. On LiteSpeed, add the exclusions to the Guest Mode field as well as the main one, otherwise it works for logged-in users and breaks for visitors.
It changes with Elementor releases. Check it on any page with a carousel by opening the console and running Swiper.version. If that returns a different number than you expect, an addon is loading its own copy and overriding Elementor’s.
Swiper measured the container at zero width, usually because the carousel sits inside a hidden tab, accordion or popup at page load. Enable the observer setting so it recalculates when the container becomes visible, or move the carousel to a panel that’s open by default.
Caching. Logged-in users typically bypass the cache and get unoptimised scripts, so the slider works. Visitors get the cached, combined and deferred version and it breaks. Test in a private window, and check for a separate guest or unauthenticated exclusion list in your cache plugin.
Work in this order: console check first (typeof Swiper), then cache exclusions, then deactivate addons one at a time in a staging copy. That sequence finds the cause in under ten minutes for almost every case.
Designs imported through the Widget Builder use the same Swiper build as the stock widgets, so these fixes apply to them too. The pricing page covers which of the twenty need a licence.
If you’d rather start from something known-good, every carousel widget on the Elementor Carousel Widgets page ships with the exclusion-safe script handles documented, and the Loop Carousel guide covers the dynamic-query variant of the same problems.
Get all the premium widgets and templates you desire, built with clean code that keeps your site fast. Ditch the bloat, not the features.

110+ Premium Widgets & Lifetime Updates – Build Beyond Limits. An Exclusive Creation by Pixar Labs