Product Card Template Code using the Refresh theme

Below is a product card template. Copy this template and paste it into the custom code section.

function loadScript(src) {
 const script = document.createElement('script');
 script.src = src;
 script.defer = true;
 return document.body.appendChild(script);
}

function stringToSlug(text) {
  if (!text) return text;

  return text
    .toLowerCase()
    .replace(/[^\w ]+/g, "")
    .replace(/ +/g, "-");
}

function setElementAttribute({ element, attributeName, value }) {
  if (element && element.hasAttribute(attributeName)) {
    element.setAttribute(attributeName, value);
  }
}

function setSelectedOption({ element, optionName }) {
  const optionsButton = element.target.offsetParent
    .querySelector(`.options-button-${stringToSlug(optionName)}`)
    .querySelectorAll(`button`);

  const defaultSelectedClassChanger = () => {
    optionsButton.forEach((button, index) => {
      button.classList.remove("sledge__product-variant-size-swatch-active");
      element.target.className += " sledge__product-variant-size-swatch-active";
    });
  };

  const colorSelectedClassChanger = () => {
    optionsButton.forEach((button, index) => {
      button.classList.remove("sledge__product-variant-color-swatch-active");
      element.target.className +=
        " sledge__product-variant-color-swatch-active";
    });
  };

  switch (optionName) {
    case "Color":
      colorSelectedClassChanger();
      break;
    case "Size":
      defaultSelectedClassChanger();
      break;
    default:
      defaultSelectedClassChanger();
  }
}

function addToCartTrigger({ sourceApp, productId }) {
  window?.sledge?.addToCartTrigger?.({
    sourceApp,
    productId,
  });
}

function productClickTrigger({ sourceApp, productId }) {
  window?.sledge?.productClickTrigger?.({
    sourceApp,
    productId,
  });
}

function setSelectedVariant({ id, element, value, optionIndex, sourceApp }) {
  const productCard = element?.target?.offsetParent;
  const selectedInput = productCard.querySelector(
    `.sledge__product-grid-card-selected-option[data-product-id='${id}']`
  );

  setElementAttribute({
    element: selectedInput,
    attributeName: `data-selected-option${optionIndex}`,
    value: value,
  });

  // define option1 and option 2
  const option1 = `[data-option-1="${stringToSlug(
    selectedInput?.attributes?.["data-selected-option1"]?.value
  )}"]`;
  const option2 = `${
    selectedInput?.attributes?.["data-selected-option2"]
      ? `[data-option-2="${stringToSlug(
          selectedInput?.attributes?.["data-selected-option2"]?.value
        )}"]`
      : ""
  }`;

  // define selected option
  const selectOption = productCard.querySelector(
    `select option${option1}${option2}`
  );
  const variantId = selectOption?.attributes?.[
    "data-graphql-id"
  ]?.value?.replace(/^gid:\/\/shopify\/ProductVariant\/(\d+)$/, "$1");
  const imageId = selectOption?.attributes?.["data-image-id"]?.value;
  const inventoryQuantity =
    selectOption?.attributes?.["data-inventory-quantity"]?.value;
  const inventoryManagement =
    selectOption?.attributes?.["data-inventory-management"]?.value;
  const inventoryPolicy =
    selectOption?.attributes?.["data-inventory-policy"]?.value;
  const availability = selectOption?.attributes?.["data-availability"]?.value;
  const price = selectOption?.attributes?.["data-price"]?.value;
  const compareAtPrice =
    selectOption?.attributes?.["data-compare-at-price"]?.value;
  const salePercent = selectOption?.attributes?.["data-sale-percent"]?.value;

  const isOnSale = parseFloat(String(compareAtPrice))
    ? parseFloat(String(compareAtPrice)) > parseFloat(String(price))
    : false;

  const links = productCard.querySelectorAll(`a[data-product-url="true"]`);

  links?.forEach((link) => {
    if (link?.href) {
      const url = new URL(link.href);
      url.searchParams.set("variant", variantId);
      link.href = url.toString();
    }
  });

  const setOther = () => {
    //set data-variant-id attribute
    setElementAttribute({
      element: selectedInput,
      attributeName: "data-variant-id",
      value: selectOption?.attributes?.["data-graphql-id"]?.value || "",
    });

    const variantInputs = productCard.querySelectorAll("input[name=id]");
    variantInputs?.forEach((inputElement) => {
      if (inputElement) {
        setElementAttribute({
          element: inputElement,
          attributeName: "value",
          value:
            selectOption?.attributes?.["data-graphql-id"]?.value?.replace(
              /gid:\/\/shopify\/ProductVariant\/(\d+)/,
              "$1"
            ) || "",
        });
      }
    });

    setElementAttribute({
      element: selectedInput,
      attributeName: "data-inventory-quantity",
      value: inventoryQuantity || "",
    });
    setElementAttribute({
      element: selectedInput,
      attributeName: "data-availability",
      value: availability || "",
    });
    setElementAttribute({
      element: selectedInput,
      attributeName: "data-inventory-management",
      value: inventoryManagement || "",
    });
    setElementAttribute({
      element: selectedInput,
      attributeName: "data-inventory-policy",
      value: inventoryPolicy || "",
    });
    setElementAttribute({
      element: selectedInput,
      attributeName: "data-price",
      value: price || "",
    });
    setElementAttribute({
      element: selectedInput,
      attributeName: "data-compare-at-price",
      value: compareAtPrice || "",
    });
    setElementAttribute({
      element: selectedInput,
      attributeName: "data-sale-percent",
      value: salePercent || "",
    });

    //change product image by variant
    if (imageId && imageId !== "null") {
      const imageElement = productCard.querySelector(
        `img.sledge__product-grid-card-image-featured-image`
      );
      const sourceImage = productCard.querySelector(
        `div.sledge__product-grid-card-variant-images img[id="${imageId}"]`
      ).src;

      if (imageElement) imageElement.src = sourceImage;
    }
  };

  updateBadge({
    productCard,
    availability,
    variantId,
    sourceApp,
    isOnSale,
    salePercent,
  });
  updatePrice({ price, compareAtPrice, productCard, isOnSale });
  setOther();

  const result = {
    variantId,
    imageId,
  };

  return result;
}

function updateBadge({
  productCard,
  availability,
  variantId,
  sourceApp,
  isOnSale,
  salePercent,
}) {
  const instantSearchSettings = JSON.parse(
    String(localStorage.getItem("sledge-instant-search-setting") || null)
  );
  const language_sold_out =
    instantSearchSettings?.languages?.["out of stock"] || "Out of Stock";

  const badgeList = productCard.querySelector(
    ".sledge__product-grid-card-image"
  );
  if (!badgeList) return;
  const existingSoldOutBadge = badgeList.querySelector(
    ".sledge__product-grid-card-out-of-stock"
  );
  const existingOnSaleBadge = badgeList.querySelector(
    ".sledge__product-grid-badge-on-sale"
  );

  const isOutOfStock = !(
    availability && availability.toLowerCase() === "in stock"
  );

  if (existingSoldOutBadge) {
    badgeList.removeChild(existingSoldOutBadge);
  }

  if (existingOnSaleBadge) {
    badgeList.removeChild(existingOnSaleBadge);
  }

  if (isOutOfStock) {
    const soldOutBadge = document.createElement("div");
    soldOutBadge.className = "sledge__product-grid-card-out-of-stock";
    soldOutBadge.textContent = language_sold_out;
    badgeList.insertAdjacentElement("beforeend", soldOutBadge);
  }

  if (isOnSale) {
    const onSaleBadge = document.createElement("span");
    onSaleBadge.className = "sledge__product-grid-badge-on-sale";
    onSaleBadge.textContent = `On Sale`;
    badgeList.insertAdjacentElement("beforeend", onSaleBadge);
  }

  updateAddToCartButton({ productCard, isOutOfStock, variantId, sourceApp });
}

function updatePrice({ price, compareAtPrice, productCard, isOnSale }) {
  const priceList = productCard.querySelector(
    ".sledge__product-grid-card-price"
  );
  if (!priceList) return;

  const salePriceElement = priceList.querySelector(
    ".sledge__product-grid-card-price div:not(.sledge__product-grid-card-compare-at-price)"
  );
  const existingCompareAtPriceElement = priceList.querySelector(
    ".sledge__product-grid-card-compare-at-price"
  );

  if (salePriceElement) {
    salePriceElement.innerHTML = window?.sledge?.shopifyFormatMoney?.(price);
  }

  if (existingCompareAtPriceElement) {
    priceList.removeChild(existingCompareAtPriceElement);
  }

  if (isOnSale) {
    const compareAtPriceElement = document.createElement("div");
    compareAtPriceElement.className =
      "sledge__product-grid-card-compare-at-price";
    compareAtPriceElement.innerHTML = `${window?.sledge?.shopifyFormatMoney?.(
      compareAtPrice
    )}`;
    priceList.insertAdjacentElement("beforeend", compareAtPriceElement);
  } else {
  }
}

function updateAddToCartButton({
  productCard,
  isOutOfStock,
  variantId,
  sourceApp,
}) {
  const instantSearchSettings = JSON.parse(
    String(localStorage.getItem("sledge-instant-search-setting") || null)
  );
  const language_add_to_cart =
    instantSearchSettings?.languages?.add_to_cart || "Add to cart";
  const language_sold_out =
    instantSearchSettings?.languages?.["out of stock"] || "Out of Stock";
  const productHandle = productCard
    .querySelector("[data-product-handle]")
    .getAttribute("data-product-handle");
  let productUrl = `/products/${productHandle}`;

  const buttonContainer = productCard.querySelector(
    ".sledge__product-grid-button-wrapper"
  );
  if (!buttonContainer) return;

  const productId = productCard.getAttribute("data-product-id");
  if (!productId) return;

  const addToCartButtonDisabled = `
            <button class="sledge__button sledge__product-grid-button-add-to-cart" data-button-color-type="light" data-button-full-width="false" type="button" disabled>
              <span class="sledge-icon__bag">
                <svg width="15" height="15" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <g id="vuesax/bold/bag-2">
                    <g id="bag-2">
                      <path id="Vector" d="M14.3711 6.04627C13.919 5.54693 13.2374 5.25677 12.2927 5.15555V4.64271C12.2927 3.71824 11.9013 2.82752 11.2131 2.20671C10.518 1.57241 9.6138 1.2755 8.67584 1.36322C7.06309 1.51842 5.70676 3.07719 5.70676 4.76417V5.15555C4.76205 5.25677 4.08051 5.54693 3.6284 6.04627C2.97385 6.77505 2.9941 7.74674 3.06833 8.42154L3.54068 12.1801C3.68238 13.496 4.21547 14.8455 7.11707 14.8455H10.8824C13.784 14.8455 14.3171 13.496 14.4588 12.1869L14.9312 8.41479C15.0054 7.74674 15.0189 6.77505 14.3711 6.04627ZM8.77031 2.30118C9.4451 2.24045 10.0862 2.44963 10.5855 2.90174C11.0781 3.34711 11.3548 3.98141 11.3548 4.64271V5.11506H6.64472V4.76417C6.64472 3.56304 7.63666 2.40915 8.77031 2.30118ZM6.58399 8.87365H6.57724C6.2061 8.87365 5.90245 8.56999 5.90245 8.19885C5.90245 7.82772 6.2061 7.52406 6.57724 7.52406C6.95512 7.52406 7.25878 7.82772 7.25878 8.19885C7.25878 8.56999 6.95512 8.87365 6.58399 8.87365ZM11.3075 8.87365H11.3008C10.9296 8.87365 10.626 8.56999 10.626 8.19885C10.626 7.82772 10.9296 7.52406 11.3008 7.52406C11.6787 7.52406 11.9823 7.82772 11.9823 8.19885C11.9823 8.56999 11.6787 8.87365 11.3075 8.87365Z" fill="currentColor"></path>
                    </g>
                  </g>
                </svg>
              </span>
              <span>${language_sold_out}</span>
            </button>`;
  const addToCartButtonEnabled = `
            <form
              method="post"
              action="/cart/add"
              id="product_form_${productId}"
              accept-charset="UTF-8"
              class="shopify-product-form"
              enctype="multipart/form-data"
              is="product-form"
              onsubmit="addToCartTrigger({ sourceApp: '${sourceApp}', productId: '${productId}' })"
            >
              <input type="hidden" name="form_type" value="product" />
              <input
                type="hidden"
                name="utf8"
                value="✓"
              />
              <input type="hidden" name="id" value="${variantId}" />
              <input type="hidden" name="product-id" value="${productId}">
              <button class="sledge__button sledge__product-grid-button-add-to-cart" data-button-color-type="light" data-button-full-width="false" type="submit">
              <span class="sledge-icon__bag">
                <svg width="15" height="15" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <g id="vuesax/bold/bag-2">
                    <g id="bag-2">
                      <path id="Vector" d="M14.3711 6.04627C13.919 5.54693 13.2374 5.25677 12.2927 5.15555V4.64271C12.2927 3.71824 11.9013 2.82752 11.2131 2.20671C10.518 1.57241 9.6138 1.2755 8.67584 1.36322C7.06309 1.51842 5.70676 3.07719 5.70676 4.76417V5.15555C4.76205 5.25677 4.08051 5.54693 3.6284 6.04627C2.97385 6.77505 2.9941 7.74674 3.06833 8.42154L3.54068 12.1801C3.68238 13.496 4.21547 14.8455 7.11707 14.8455H10.8824C13.784 14.8455 14.3171 13.496 14.4588 12.1869L14.9312 8.41479C15.0054 7.74674 15.0189 6.77505 14.3711 6.04627ZM8.77031 2.30118C9.4451 2.24045 10.0862 2.44963 10.5855 2.90174C11.0781 3.34711 11.3548 3.98141 11.3548 4.64271V5.11506H6.64472V4.76417C6.64472 3.56304 7.63666 2.40915 8.77031 2.30118ZM6.58399 8.87365H6.57724C6.2061 8.87365 5.90245 8.56999 5.90245 8.19885C5.90245 7.82772 6.2061 7.52406 6.57724 7.52406C6.95512 7.52406 7.25878 7.82772 7.25878 8.19885C7.25878 8.56999 6.95512 8.87365 6.58399 8.87365ZM11.3075 8.87365H11.3008C10.9296 8.87365 10.626 8.56999 10.626 8.19885C10.626 7.82772 10.9296 7.52406 11.3008 7.52406C11.6787 7.52406 11.9823 7.82772 11.9823 8.19885C11.9823 8.56999 11.6787 8.87365 11.3075 8.87365Z" fill="currentColor"></path>
                    </g>
                  </g>
                </svg>
              </span>
              <span>${language_add_to_cart}</span>
            </button>
            </form>`;

  if (isOutOfStock) {
    buttonContainer.innerHTML = addToCartButtonDisabled;
  } else {
    buttonContainer.innerHTML = addToCartButtonEnabled;
  }
}

function renderProductCard({ product, sourceApp }) {
  const {
    id,
    admin_graphql_api_id,
    title,
    image,
    handle,
    url,
    vendor,
    product_type,
    body_html,
    currency,
    variants,
    review,
    options: productOptions,
    created_at,
  } = product || {};
  const variantsInStock = variants?.filter(
    (variant) => variant?.availability?.toLowerCase() === "in stock"
  );

  const {
    id: variant_id = "",
    admin_graphql_api_id: variant_admin_graphql_api_id = "",
    title: variant_title = "",
    price = "",
    compare_at_price = "",
    sku = "",
    availability,
    sale_percent,
    inventory_quantity,
  } = variantsInStock?.length ? variantsInStock[0] : variants?.[0];
  const { total: totalReview, average: averageReview } = review || {};

  const instantSearchSettings =
    JSON.parse(
      String(localStorage.getItem("sledge-instant-search-setting") || "null")
    ) || {};
  const generalSettings =
    JSON.parse(
      String(localStorage.getItem("sledge-general-setting") || "null")
    ) || {};

  const {
    show_price = true,
    show_vendor = true,
    show_sku = true,
  } = instantSearchSettings?.display?.search || {};

  const isOnSale = parseFloat(String(compare_at_price))
    ? parseFloat(String(compare_at_price)) > parseFloat(String(price))
    : false;
  const isOutOfStock = !Boolean(availability === "in stock");
  const isLowInStock = !isOutOfStock && Number(inventory_quantity) <= 20;
  const isVeryLowInStock = !isOutOfStock && Number(inventory_quantity) <= 10;

  const productUrl = `/products/${handle}?variant=${variant_id}`;
  const productImageReplacingSrc = ({ src, width = 500 }) => {
    if (!src)
      return "https://sledgeassets.nyc3.cdn.digitaloceanspaces.com/images/blank-image.png";

    try {
      const imageUrl = new URL(src);
      imageUrl.searchParams.set("width", width);
      return imageUrl.toString();
    } catch (error) {
      // Handle invalid URLs
      return src;
    }
  };

  const productImageUrl = productImageReplacingSrc({
    src: image?.src,
    width: 500,
  });

  const options = product?.options ? Object.entries(product.options) : [];
  const images = product?.images ?? [];
  const defaultSelected = {};

  const secondaryImage = images?.[1];
  const secondaryProductImageUrl = secondaryImage
    ? productImageReplacingSrc({
        src: secondaryImage?.src,
        width: 500,
      })
    : null;

  const ratingTotalAttribute =
    typeof totalReview !== "undefined"
      ? `data-rating-total="${totalReview}"`
      : "";
  const ratingAverageAttribute =
    typeof averageReview !== "undefined"
      ? `data-rating-average="${averageReview}"`
      : "";

  function setDefaultFunction() {
    let variantList = [];
    if (variantsInStock?.length) {
      variantList = variantsInStock;
    } else if (variants?.length) {
      variantList = variants;
    } else {
      return;
    }

    defaultSelected["data-product-id"] = id;
    defaultSelected["data-product-handle"] = handle;
    defaultSelected["data-selected-option1"] = variantList[0].option1;
    if (variantList[0].option2) {
      defaultSelected["data-selected-option2"] = variantList[0].option2;
    }
    defaultSelected["data-variant-id"] = variantList[0].admin_graphql_api_id;
    defaultSelected["data-inventory-quantity"] =
      variantList[0].inventory_quantity;
    defaultSelected["data-inventory-management"] =
      variantList[0].inventory_management;
    defaultSelected["data-inventory-policy"] = variantList[0].inventory_policy;
  }

  setDefaultFunction();

  const language_add_to_cart =
    instantSearchSettings?.languages?.add_to_cart || "Add to cart";
  const language_sold_out =
    instantSearchSettings?.languages?.["out of stock"] || "Out of Stock";
  const language_in_stock =
    instantSearchSettings?.languages?.["in stock"] || "In Stock";

  const variantImagesHtml =
    images
      ?.map?.(
        (image) =>
          `<img decoding="async" loading="lazy" alt="${image?.alt || ""}" id="${
            image?.id
          }" src="${image?.src}" />`
      )
      ?.join?.("") || "";

  const variantOptionsHtml =
    variants
      ?.map?.((variant) => {
        const {
          title,
          option1,
          option2,
          position,
          id,
          admin_graphql_api_id,
          image_id,
          inventory_quantity,
          inventory_management,
          inventory_policy,
          price,
          compare_at_price,
          sale_percent,
          availability,
        } = variant;

        let optionAttributes = {
          "data-option-1": stringToSlug(option1),
          "data-option-2": option2 ? stringToSlug(option2) : "",
          "data-inventory-quantity": inventory_quantity,
          "data-inventory-management": inventory_management,
          "data-inventory-policy": inventory_policy,
          "data-position": position,
          "data-id": id,
          "data-graphql-id": admin_graphql_api_id,
          "data-image-id": image_id,
          "data-price": price,
          "data-compare-at-price": compare_at_price,
          "data-sale-percent": sale_percent,
          "data-availability": availability,
          "data-product-handle": handle,
        };

        return `<option ${Object.keys(optionAttributes).reduce(
          (acc, item) => acc + `${item}="${optionAttributes[item]}"`,
          ""
        )}>${title}</option>`;
      })
      ?.join?.("") || "";

  const colorOptionsHtml =
    options
      ?.filter((option) => option?.[0] === "Color")
      ?.map?.((option) => {
        const optionName = option?.[0];
        const optionValues = option?.[1];
        const optionIndex =
          options.findIndex((item) => item[0] === optionName) + 1;

        const initialVisibleCount = 2;
        const hiddenOptionsCount = optionValues.length - initialVisibleCount;
        const showMoreText = `${hiddenOptionsCount}+`;
        const selectedOption =
          defaultSelected[`data-selected-option${optionIndex}`];

        const showMoreButton = `
              <a
                  class="sledge-custom__product-card-link ${
                    optionName === "Color"
                      ? "sledge__product-variant-color-swatch"
                      : "sledge__product-variant-size-swatch"
                  }"
                  href="${productUrl}"
                  data-show-more
              >
                  ${showMoreText}
              </a>
          `;

        if (optionValues[0] === "Default Title") return "";

        const colorButtonsHtml =
          optionValues
            ?.slice(0, initialVisibleCount)
            ?.map?.((item, index) => {
              const defaultOptionClass = `${
                selectedOption === item
                  ? "sledge__product-variant-size-swatch-active"
                  : ""
              } sledge__product-variant-size-swatch`;
              const colorOptionClass = `${
                selectedOption === item
                  ? "sledge__product-variant-color-swatch-active"
                  : ""
              } sledge__product-variant-color-swatch`;
              const colorDataSettings = instantSearchSettings?.colors || [];
              const getColorSwatch =
                colorDataSettings?.filter?.(({ name }) => name === item)[0] ||
                {};
              const colorSwatch = getColorSwatch?.image
                ? `url(${getColorSwatch?.image})`
                : getColorSwatch?.rgb || item;

              return `
              <button
                  type="button"
                  class="${
                    optionName === "Color"
                      ? colorOptionClass
                      : defaultOptionClass
                  }"
                  style="${
                    optionName === "Color"
                      ? `
                  background: ${colorSwatch};
                  background-size: contain;
                  `
                      : ""
                  }"
                  onclick="setSelectedVariant({ id: '${id}', element: event, value: '${item}', optionIndex: ${optionIndex}, sourceApp: '${sourceApp}' }); setSelectedOption({ element: event, optionName: '${optionName}' })"
                  title="${item}"
              >
                  ${optionName === "Color" ? "" : item}
              </button>`;
            })
            ?.join?.("") || "";

        return `
          <div class="sledge__product-variant-size-swatch-flex options-button-${stringToSlug(
            optionName
          )}">
              ${colorButtonsHtml}
              ${hiddenOptionsCount > 0 ? showMoreButton : ""}
          </div>`;
      })
      ?.join?.("") || "";

  const otherOptionsHtml =
    options
      ?.filter((option) => option?.[0] !== "Color")
      ?.map?.((option) => {
        const optionName = option?.[0];
        const optionValues = option?.[1];
        const optionIndex =
          options.findIndex((item) => item[0] === optionName) + 1;

        if (optionValues[0] === "Default Title") return "";
        const defaultValue =
          defaultSelected[`data-selected-option${optionIndex}`];

        const optionItemsHtml =
          optionValues
            .map(
              (item, index) =>
                `<option ${
                  item == defaultValue ? "selected" : ""
                } value="${item}">${item}</option>`
            )
            ?.join?.("") || "";

        return `<select class="sledge__product-variant-size-swatch-select options-button-${stringToSlug(
          optionName
        )}" data-option-name="${optionName}" onchange="setSelectedVariant({ id: '${id}', element: event, value: event.target.value, optionIndex: ${optionIndex}, sourceApp: '${sourceApp}' });">
            ${optionItemsHtml}
          </select>`;
      })
      ?.join?.("") || "";

  return `
        <div class="sledge__product-grid-card" data-product-id="${id}">
          <div class="sledge__product-grid-content">
            <div class="sledge__product-grid-card-image">
              <a href="${productUrl}" data-product-url="true" class="sledge__product-grid-card-image-link">
                <div
                  data-component="wishlist-trigger"
                  data-product-id="${id}"
                  data-product-variant-id="${variant_id}"
                  data-product-name="${title}"
                  data-product-vendor="${vendor}"
                  data-product-sku="${sku}"
                  data-product-variant-name="${variant_title}"
                  data-product-link="${url}"
                  data-product-image="${image?.src || ""}"
                  data-product-currency="${currency}"
                  data-product-price="${price}"
                  data-trigger-badge="rerender"
                  data-on-after-add-wishlist="onAfterAddWishlist"
                  data-on-after-remove-wishlist="onAfterRemoveWishlist"
                ></div>
                <div class="sledge__product-grid-card-featured-image-element">
                  <img
                    alt="${title || "Product Image"}"
                    loading="lazy"
                    class="sledge__product-grid-card-image-featured-image"
                    src="${productImageUrl}"
                  />
                  ${
                    secondaryProductImageUrl
                      ? `
                    <img
                      src="${secondaryProductImageUrl}"
                      alt="${title || "Product Secondary Image"}"
                      class="sledge__product-grid-card-image-featured-image sledge__product-grid-card-image-featured-image--secondary"
                    />
                  `
                      : ""
                  }
                </div>
                <div class="sledge__product-grid-card-variant-images">
                  ${variantImagesHtml}
                </div>
              </a>
              ${
                isOnSale
                  ? `<div class="sledge__product-grid-badge-on-sale">ON SALE</div>`
                  : ""
              }
              ${
                isOutOfStock
                  ? `<div class="sledge__product-grid-card-out-of-stock">${language_sold_out}</div>`
                  : ""
              }
            </div>
            <div class="sledge__product-grid-card-desc">
              <div class="sledge__product-grid-card-title">
                <div class="sledge__product-grid-card-price">
                  <div>${
                    window?.sledge?.shopifyFormatMoney?.(price) || price
                  }</div>
                  ${
                    isOnSale
                      ? `<div class="sledge__product-grid-card-compare-at-price">${
                          window?.sledge?.shopifyFormatMoney?.(
                            compare_at_price
                          ) || compare_at_price
                        }</div>`
                      : ""
                  }
                </div>
                ${
                  show_vendor
                    ? `<div class="sledge__product-grid-badge-vendor" title="${vendor}">
                  Vendor: ${vendor}
                </div>`
                    : ""
                }
              </div>
            <div class="sledge__product-grid-card-rating">
              <span class="jdgm-preview-badge" data-id="${id}"></span>
                ${
                    product.metafields["judgeme.badge"]
                    ? product.metafields["judgeme.badge"]
                    : ""
                }
            </div>
              <a href="${productUrl}" data-product-url="true">
                <h3 class="sledge__product-grid-card-product-name">${title}</h3>
              </a>
              <div class="sledge__product-grid-card-text">
                ${show_sku && sku ? `<div>SKU: ${sku}</div>` : ""}
              </div>
              <div class="sledge__product-grid-card-variant-swatch">
                <input type="hidden" ${Object.keys(defaultSelected).reduce(
                  (acc, item) => acc + `${item}="${defaultSelected[item]}" `,
                  ""
                )} class="sledge__product-grid-card-selected-option" />
    
                <select class="variant-picker sledge__product-grid-card-variant-picker">
                  ${variantOptionsHtml}
                </select>
                ${colorOptionsHtml}
                ${otherOptionsHtml}
              </div>
            </div>
          </div>
          <div class="sledge__product-grid-button-wrapper">
            ${
              isOutOfStock
                ? `<button
              class="sledge__button sledge__product-grid-button-add-to-cart"
              data-button-color-type="light"
              data-button-full-width="false"
              type="button"
              disabled
            >
              <span class="sledge-icon__bag">
                <svg width="15" height="15" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <g id="vuesax/bold/bag-2">
                    <g id="bag-2">
                      <path
                        id="Vector"
                        d="M14.3711 6.04627C13.919 5.54693 13.2374 5.25677 12.2927 5.15555V4.64271C12.2927 3.71824 11.9013 2.82752 11.2131 2.20671C10.518 1.57241 9.6138 1.2755 8.67584 1.36322C7.06309 1.51842 5.70676 3.07719 5.70676 4.76417V5.15555C4.76205 5.25677 4.08051 5.54693 3.6284 6.04627C2.97385 6.77505 2.9941 7.74674 3.06833 8.42154L3.54068 12.1801C3.68238 13.496 4.21547 14.8455 7.11707 14.8455H10.8824C13.784 14.8455 14.3171 13.496 14.4588 12.1869L14.9312 8.41479C15.0054 7.74674 15.0189 6.77505 14.3711 6.04627ZM8.77031 2.30118C9.4451 2.24045 10.0862 2.44963 10.5855 2.90174C11.0781 3.34711 11.3548 3.98141 11.3548 4.64271V5.11506H6.64472V4.76417C6.64472 3.56304 7.63666 2.40915 8.77031 2.30118ZM6.58399 8.87365H6.57724C6.2061 8.87365 5.90245 8.56999 5.90245 8.19885C5.90245 7.82772 6.2061 7.52406 6.57724 7.52406C6.95512 7.52406 7.25878 7.82772 7.25878 8.19885C7.25878 8.56999 6.95512 8.87365 6.58399 8.87365ZM11.3075 8.87365H11.3008C10.9296 8.87365 10.626 8.56999 10.626 8.19885C10.626 7.82772 10.9296 7.52406 11.3008 7.52406C11.6787 7.52406 11.9823 7.82772 11.9823 8.19885C11.9823 8.56999 11.6787 8.87365 11.3075 8.87365Z"
                        fill="currentColor"
                      ></path>
                    </g>
                  </g>
                </svg>
              </span>
              <span>${language_sold_out}</span>
            </button>`
                : `<form
              method="post"
              action="/cart/add"
              id="product_form_${id}"
              accept-charset="UTF-8"
              class="shopify-product-form"
              enctype="multipart/form-data"
              is="product-form"
              onsubmit="addToCartTrigger({ sourceApp: '${sourceApp}', productId: '${id}' })"
            >
              <input type="hidden" name="form_type" value="product" />
              <input
                type="hidden"
                name="utf8"
                value="✓"
              />
              <input type="hidden" name="id" value="${variant_id}" />
              <input type="hidden" name="product-id" value="${id}">
              <button
              class="sledge__button sledge__product-grid-button-add-to-cart"
              data-button-color-type="light"
              data-button-full-width="false"
              type="submit"
            >
              <span class="sledge-icon__bag">
                <svg width="15" height="15" viewBox="0 0 18 17" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <g id="vuesax/bold/bag-2">
                    <g id="bag-2">
                      <path
                        id="Vector"
                        d="M14.3711 6.04627C13.919 5.54693 13.2374 5.25677 12.2927 5.15555V4.64271C12.2927 3.71824 11.9013 2.82752 11.2131 2.20671C10.518 1.57241 9.6138 1.2755 8.67584 1.36322C7.06309 1.51842 5.70676 3.07719 5.70676 4.76417V5.15555C4.76205 5.25677 4.08051 5.54693 3.6284 6.04627C2.97385 6.77505 2.9941 7.74674 3.06833 8.42154L3.54068 12.1801C3.68238 13.496 4.21547 14.8455 7.11707 14.8455H10.8824C13.784 14.8455 14.3171 13.496 14.4588 12.1869L14.9312 8.41479C15.0054 7.74674 15.0189 6.77505 14.3711 6.04627ZM8.77031 2.30118C9.4451 2.24045 10.0862 2.44963 10.5855 2.90174C11.0781 3.34711 11.3548 3.98141 11.3548 4.64271V5.11506H6.64472V4.76417C6.64472 3.56304 7.63666 2.40915 8.77031 2.30118ZM6.58399 8.87365H6.57724C6.2061 8.87365 5.90245 8.56999 5.90245 8.19885C5.90245 7.82772 6.2061 7.52406 6.57724 7.52406C6.95512 7.52406 7.25878 7.82772 7.25878 8.19885C7.25878 8.56999 6.95512 8.87365 6.58399 8.87365ZM11.3075 8.87365H11.3008C10.9296 8.87365 10.626 8.56999 10.626 8.19885C10.626 7.82772 10.9296 7.52406 11.3008 7.52406C11.6787 7.52406 11.9823 7.82772 11.9823 8.19885C11.9823 8.56999 11.6787 8.87365 11.3075 8.87365Z"
                        fill="currentColor"
                      ></path>
                    </g>
                  </g>
                </svg>
              </span>
              <span>${language_add_to_cart}</span>
            </button>
            </form>`
            }
          </div>
        </div>
      `;
}
Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us