07/16/2021

A lightweight, responsive gallery slider/carousel solution for Hyva Theme - Glide.js

Author: Michał Ł.

Many e-commerce shops are moving towards mobile-centric marketing, including landing and product pages. This creates a need for product galleries, picture-based attributes like fabrics and other showcase images to be more responsive than ever. There are many ways to deal with limited space, which can be resized without reloading the page.

The proposed solution

Hyva Theme is as light as it gets and it can be extended with the required functionality by 3rd party functional libraries, one of which is Glide.js, a modular slider and carousel library. It fits perfectly in the lightweight and dependency-free concept of Hyvas. Satisfying the need for proper content presentation, Glide.js is a suitable solution to be used in many components like product galleries, content card-based sliders or even video galleries.

Challenges

Working with Glide.js and Hyva Theme proves their high customizability is extremely useful. However, because of the assumption that scripts should be small and local, we need to mind some cases like Magento2 full page cache whenever we provide JavaScript inline with the Hyvas concept. There are 3 challenges to make it work:

  1. Scripts must be declared once, even when the block is cached and repeated
  2. Scripts must be in conjunction with AlpineJS to leverage its functionality
  3. Gide.js object initialisation must be avoided when there are not enough slides to show.

The declaration

The first challenge is simple and can be solved in many ways, the simplest one being a conditional object definition, e.g.

if (!window.exampleObject) {
  window.exampleObject = (() => {})}
}

The classic approach with the function exampleObject() {} would result in

  • an error of function redeclaration whenever a block is cached and repeated,
  • lack of functionality for repeated blocks.

This simple step allows us to define the required object within the window scope and makes it reusable: we only load it once.

The scope

The next challenge is very important. To take advantage of AlpineJS we need to clearly define the scope of the object we use, here is an example:

if (!window.exampleObject) {
   window.exampleObject = (() => {
     return {
       isOpen: false,
       toggle() {
          this.isOpen = !this.isOpen
       }
     })
   }

At this point object methods and attributes are accessible after simple implementation in the AlpineJS e.g.:

x-data="exampleObject", x-show="isOpen" and @click="toggle"

Initialize only when needed

The last but not least challenge is to initialize the object's components only when it is required and after the page is loaded. AlpineJS provides the @load.window construction and it is perfect to use in this case. It allows us to execute a function based on the object in the x-data part when the page is fully loaded, for example:

<div class="glide" x-data="customObject" @load.window="initGlide()">...</div>

This approach allows us to place logic in the initGlide method to check if there are enough slides to build a Glide.js slider or carousel for the current element’s width.

Further information

Because of the mobile-first world we live in, we need to account for device rotation, which means changing the width of the slider/carousel. For example, when we start in a horizontal page layout, there might be enough space not to initialize Glide.js objects in the initGlide() method, but when the device rotates to a vertical position, we need to check if the carousel/slider needs to be initialized. This is when the AlpineJS attribute @resize.window comes in handy. Therefore we can check if the Glide object was already initialized and if it’s necessary to do so.

Edge cases

As tricky as it sounds, it is worth it to handle the slider/carousel initialisation despite the page being loaded, especially in extreme cases like comparison pages with lots of small galleries for sliding factors like shapes, materials, bundle options, etc. or even in corner cases like the gallery used in a popup: when don’t know if and when the end-user will open the slider/carousel.

Related Posts

Contact with: Michał Ł.