Adding lightbox to image in CMS rich text field

Here’s code that enables that functionality.

  (() => {
    function replaceImagesWithLightboxes(element) {
      const figures = element.querySelectorAll(".w-richtext-figure-type-image");

      figures.forEach((figure) => {
        const image = figure.querySelector("img");
        const imageUrl = image.getAttribute("src");
        const imageAlt = image.getAttribute("alt");
        const imageWidth = image.getAttribute("width"); // Added to retrieve the image width

        // Create lightbox HTML
        const lightbox = document.createElement("a");
        lightbox.setAttribute("href", "#");
        lightbox.classList.add("w-inline-block", "w-lightbox");

        const lightboxImage = document.createElement("img");
        lightboxImage.setAttribute("src", imageUrl);
        lightboxImage.setAttribute("loading", "lazy");
        lightboxImage.setAttribute("sizes", "100vw");
        lightboxImage.setAttribute("srcset", generateSrcset(imageUrl, imageWidth));
        lightboxImage.setAttribute("alt", imageAlt);

        const script = document.createElement("script");
        script.setAttribute("type", "application/json");
        script.textContent = JSON.stringify({
          items: [
              _id: Math.random().toString(),
              origFileName: imageAlt,
              fileName: imageAlt,
              url: imageUrl,
              width: imageWidth ? parseInt(imageWidth) : undefined, // Updated to use the retrieved image width
              type: "image",
          group: "",


        figure.innerHTML = "";

    function generateSrcset(imageUrl, imageWidth) {
      const sizes = [500, 800, 1080, 1600, 2000];
      const srcset = sizes
      .filter((size) => size <= imageWidth) // Filter sizes smaller than or equal to the original image width
      .map((size) => {
        return `${imageUrl.replace(".png", `-p-${size}.png`)} ${size}w`;

      srcset.push(`${imageUrl} ${imageWidth}w`);

      return srcset.join(", ");

    const containerElement = document.querySelector('.pillar-main__rte');

Let’s break down the code and understand its functionality:

  1. The code is wrapped in an immediately invoked function expression (IIFE) to create a local scope and avoid polluting the global namespace.
  2. The replaceImagesWithLightboxes function is defined. It accepts an element parameter, which should be an HTML element containing the images that need to be replaced with lightboxes.
  3. The function starts by selecting all elements with the class “w-richtext-figure-type-image” within the provided element. These elements are typically used to represent images within a Webflow rich text element.
  4. The function iterates over each of the selected figures using the forEach method.
  5. For each figure, the function retrieves the img element within it and extracts the URL (src attribute), alternate text (alt attribute), and width (width attribute) of the image.
  6. The code then proceeds to create the necessary HTML elements for the lightbox functionality. It creates an a element (lightbox) that serves as a container for the image and attaches the necessary classes (w-inline-block and w-lightbox).
  7. Inside the lightbox container, an img element (lightboxImage) is created and populated with attributes such as the image URL, lazy loading, sizes for responsiveness, and a srcset attribute generated by the generateSrcset function.
  8. Additionally, a script element is created to hold JSON data representing the image properties. It includes an array of objects representing the image data, such as ID, original and file names, URL, width, and type.
  9. The lightboxImage and script elements are appended as children to the lightbox container.
  10. After constructing the lightbox HTML, the figure’s contents are cleared (innerHTML = "") to remove the original image.
  11. Finally, the lightbox container is appended as a child to the figure, effectively replacing the original image with the lightbox.
  12. The generateSrcset function is defined to generate the srcset attribute for the lightbox image. It takes the image URL and width as input parameters.
  13. Inside the function, an array of sizes is defined (e.g., [500, 800, 1080, 1600, 2000]). It filters out sizes that are smaller than or equal to the original image width.
  14. For each remaining size, it generates a URL with the size appended (e.g., replacing “.png” with “-p-500.png”) and appends it to the srcset array with the corresponding width (size + "w").
  15. Finally, the srcset array is joined into a comma-separated string and returned.
  16. Outside the function definitions, the code selects the container element (specified by the class “RICH-TEXT-ELEMENT-CLASS”) where the images should be replaced with lightboxes.
  17. The replaceImagesWithLightboxes function is called with the container element as an argument, triggering the replacement of images within that element.

Overall, this code enhances the images within a Webflow rich text element by replacing them with lightboxes, which allow users to view the images in a larger size or in a modal popup. It also provides responsive behavior by generating a srcset attribute with different image sizes based on the

Explanation offered by ChatGPT, but seems right