In this tutorial, we’ll learn how to sync two nestable sliders in Bricks: one will be the main slider and the other one will be a thumbnail slider.
Table of Contents
- Introduction
- The DOM tree
- The JSON settings for the Thumbnail slider
- The JavaScript Code
- The result
- Resources
Introduction
This tutorial is a follow-up to the great video of Udoro ‘Cracka’ Essien shared recently in the group. He explained how to sync two nested sliders in Bricks: one main slider and one used as a thumbnail.
This tutorial enhances the previous code shared by Cracka and allows you to:
- set and forget the Javascript Code. Once enqueued, you don’t have to touch it again as it’s based on classes rather than IDs
- insert multiple sync sliders on the same page
- avoid possible conflict with other plugins/snippets
- reduce the amount of JS calculation by debouncing the function on resize
Let’s dive into it!
The DOM tree
In order to work, we need
- a container (or a section / block / div) with the class
.sync-sliders-wrapper - the two sliders to be children of the container
- the main slider needs the class
.sync-sliders-main - the thumbnail slider needs the class
.sync-sliders-thumb

The JSON settings for the Thumbnail slider
As explained by Cracka in his video, you need to insert a custom JSON object as the thumbnail slider setting options. I’ll just paste the code for reference:
{
"type":"slide",
"direction":"ltr",
"keyboard":"global",
"height":"auto",
"gap":10,
"start":0,
"perPage":"3",
"perMove":1,
"speed":400,
"interval":3000,
"autoHeight":true,
"autoplay":false,
"pauseOnHover":false,
"pauseOnFocus":false,
"arrows":false,
"pagination":false,
"focus": "center",
"isNavigation": true,
"updateOnMove": true,
"breakpoints":{
"580":{
"perPage":"2"
}
}
}
The most important string here is "isNavigation": true that will set the slider as a navigation slider.

The JavaScript Code
Enqueue the following code in your child theme or use a code snippet plugin:
document.addEventListener('DOMContentLoaded', () => {
// Query all the wrappers
const wrappers = document.querySelectorAll('.sync-sliders-wrapper');
// Stop the function if there is no sync slider
if (wrappers.length < 1) return;
// Debounce function
const debounce = (fn, threshold) => {
var timeout;
threshold = threshold || 200;
return function debounced() {
clearTimeout(timeout);
var args = arguments;
var _this = this;
function delayed() {
fn.apply(_this, args);
}
timeout = setTimeout(delayed, threshold);
};
};
// Init function
const init = (mainSliderId, thumbSliderId) => {
const main = bricksData.splideInstances[mainSliderId],
thumbnail = bricksData.splideInstances[thumbSliderId];
// Mount the sync slider
main.sync(thumbnail);
};
// Loop into each wrapper
wrappers.forEach(wrapper => {
// Set the ID of the main slider
const mainSlider = wrapper.querySelector('.sync-sliders-main');
// Check if the main slider class is correctly set
if (!mainSlider) return console.log('No .sync-sliders-main class found');
const mainSliderId = mainSlider.dataset.scriptId;
// Set the ID of the thumb slider
const thumbSlider = wrapper.querySelector('.sync-sliders-thumb');
// Check if the thumb slider class is correctly set
if (!thumbSlider) return console.log('No .sync-sliders-thumb class found');
const thumbSliderId = thumbSlider.dataset.scriptId;
// Run the function on load
setTimeout(() => {
init(mainSliderId, thumbSliderId);
}, 0);
// Rerun the function on resize because bricks reinit the sliders on each resize event
window.addEventListener("resize", debounce(() => {
init(mainSliderId, thumbSliderId);
}, 300));
});
});
The result
If everything worked, you should see this result on frontend:
Resources
Debounce function
https://www.freecodecamp.org/news/javascript-debounce-example/
