CMS Multi-Image Lightbox on static page

Who does not know the limitation of Webflow? The Multi Image Field cannot be selected or displayed on static pages in the Collection List. The same applies to the Lightbox. It is not possible to select the Multi Image Field natively in the Webflow Designer. This functionality was not only missing for me, but also for X other Webflow developers. Therefore, I would like to share and explain my JavaScript solution with you.

You need the following elements and attributes in your project:
Static page (where the lightboxes are located):

  • Collection List with the attribute [lightbox-cms="list"]
    • Link to the template page of the item with the attribute [lightbox-cms="template-link"] (Must be outside the lightbox)

    • Native Webflow Lightbox

Template page:

  • Collection List with the attribute [lightbox-cms="template-list"] and linked to the Multi Image Field.
    • Image linked to the Multi Image

Don’t forget: Scripts belong in the “Before </body> Tag”.

const staticItems = document.querySelectorAll('[lightbox-cms="list"] .w-dyn-item');
const promises = [];

staticItems.forEach(function loadMultiImages(staticItem) {
  const promise = (async () => {
    const templateLink = staticItem.querySelector('[lightbox-cms="template-link"]');
    const templateUrl = templateLink.getAttribute('href');
    const jsonElement = staticItem.querySelector('script.w-json');
    const json = JSON.parse(jsonElement.textContent.trim());
    json.group = templateLink.innerText.trim();

    try {
      const response = await fetch(templateUrl);
      const templateHTML = await response.text();
      const parser = new DOMParser();
      const templateDoc = parser.parseFromString(templateHTML, 'text/html');
      const templateImages = templateDoc.querySelectorAll('[lightbox-cms="template-list"] img');

      templateImages.forEach(function(templateImage) {
        json.items.push({
          url: templateImage.src,
          type: 'image'
        });
      });

      jsonElement.textContent = JSON.stringify(json, null, 2);
    } catch (error) {
      console.error('Fehler beim Laden der Template-Seite:', error);
    }
  })();
  promises.push(promise);
});

Promise.all(promises)
  .then(function() {
    restartWebflow('lightbox');
  })
  .catch(console.error);

//Reinitialisierung
function restartWebflow(modules) {
    var Webflow = window.Webflow;

    if (!Webflow || !('destroy' in Webflow) || !('ready' in Webflow) || !('require' in Webflow))
        return;

    if (modules && !modules.length)
        return;

    // Global
    if (!modules) {
        Webflow.destroy();
        Webflow.ready();
    }

    // IX2
    if (!modules || modules.indexOf('ix2') !== -1) {
        var ix2 = Webflow.require('ix2');
        if (ix2) {
            var store = ix2.store;
            var actions = ix2.actions;
            var eventState = store.getState().ixSession.eventState;
            var stateEntries = Object.entries(eventState);

            if (!modules) {
                ix2.destroy();
            }

            ix2.init();
            var promises = stateEntries.map(function(state) {
                return new Promise(function(resolve) {
                    resolve(store.dispatch(actions.eventStateChanged.apply(actions, state)));
                });
            });

            return Promise.all(promises);
        }
    }

    // Commerce
    if (!modules || modules.indexOf('commerce') !== -1) {
        var commerce = Webflow.require('commerce');
        var siteId = getSiteId();

        if (commerce && siteId) {
            commerce.destroy();
            commerce.init({ siteId: siteId, apiUrl: 'https://render.webflow.com' });
        }
    }

    // Lightbox
    if (modules && modules.indexOf('lightbox') !== -1) {
        var lightbox = Webflow.require('lightbox');
        if (lightbox) {
            lightbox.ready();
        }
    }

    // Slider
    if (modules && modules.indexOf('slider') !== -1) {
        var slider = Webflow.require('slider');
        if (slider) {
            slider.redraw();
            slider.ready();
        }
    }

    // Tabs
    if (modules && modules.indexOf('tabs') !== -1) {
        var tabs = Webflow.require('tabs');
        if (tabs) {
            tabs.redraw();
        }
    }

    return new Promise(function(resolve) {
        Webflow.push(function() {
            resolve(undefined);
        });
    });
}
1 Like

This worked perfectly for me! Thank you!

Hi Michael, just to clarify for people who encounter this post - the multi-image field is a list field ( just like a multi-ref field is ), so you access it using a nested collection list. Easy to do.

However it comes with the nested-list limitations as well- including the 5 items max.

Script based solutions are definitely the way to go when you need to break that.