Integrating the Product Page

Learn how to setup the Extend product page offer!

Overview

In this section, we will go over the following steps:

  • Product Display Offer & Interstitial Modal Offer Examples
  • Locate Add To Cart button and form elements
  • Adding snippet to extend-product-page.liquid
Est. Time of Completion: 1:30 hour(s)

Video Guide

Product Display Page (PDP) Offer Example:

This offer will show right above the Add To Cart button, on any product that is mapped as "warrantable" by Extend.

Interstitial Modal Offer Example:

The modal will show when a customer clicks on the Add To Cart button without selecting a protection plan


Configuration

Locate

  1. Locate the add to cart button class name:

    1. Go to your Product Display Page and locate the add to cart button

    2. Right click then click inspect on the right click menu

    3. On the elements, tab hover over the elements until you locate the <button>
      Note: When you hover over the elements on the tab you should see them being highlighted on the page

    4. Locate the class name, this will be an attribute name after the statement class=

    5. Copy the class name and paste it somewhere else for later use
      Note: You can double click the class name and the editor should auto highlight it to be ready to be copied

  2. Locate the product form class name:

    1. Go to your Product Display Page and locate the add to cart button

    2. Right click then click inspect on the right-click menu

    3. On the elements, tab hover over the elements until you locate the <form>
      Note: When you hover over the elements on the tab you should see them being highlighted on the page

    4. Locate the class name, this will be an attribute name after the statement class=

    5. Copy the class name and paste it somewhere else for later use
      Note: You can double click the class name and the editor should auto highlight it to be ready to be copied

Create

  1. Under Snippets, click Add a new snippet.
  2. Add the following file and insert the respective code:

extend-product-page

<script>

    // Run scripts on DOMContentLoaded to avoid affecting site load time
    window.addEventListener('DOMContentLoaded', function () {
        // Checks if Extend lives in the window and the active currency is USD before showing Extend offers
        if (Extend && ExtendShopify && Shopify && Shopify.currency && Shopify.currency.active === Extend.integration.currency && meta.page.pageType == 'product') {

            /************************/
            /* Initial Variables    */
            /************************/
            const productForm = document.querySelector('form[action="/cart/add"]'); // Change this to the product form element
            const addToCartButton = productForm.querySelector('button[name="add"]'); // Change this to the Add-To-Cart element
            const dispatchSideCart = false; // Set to true if a sidecart opens after adding to cart via pdp
            const productCategory = (meta && meta.product) ? meta.product.type : null; // Grabs product category from meta object, works on most themes

            // Handles creating and prepending Extend offer div
            const extendOffer = document.createElement('div');
            if (!Extend.integration.pdpOffer) extendOffer.style.display = 'none';
            extendOffer.className = 'extend-offer';
            productForm.prepend(extendOffer);

            /************************/
            /* initProductOffer     */
            /************************/
            // Initializes product offers and handles ATC button functionality for the main PDP ATC
            function initProductOffer() {
                try {

                    // Fail safes
                    if (!productForm || !addToCartButton || !extendOffer) {
                        throw new Error("Exiting - missing productForm, addToCartButton, or extendOffer")
                    }

                    // Disables ATC if product is Extend
                    if (meta && meta.product && meta.product.vendor === 'Extend') addToCartButton.disabled = true;

                    // Grabs the variantId from the productForm and renders the initial offers for it
                    let variantId = productForm.id.value;

                    // Grabs the product price from the metadata, works on most themes
                    let productPrice = (meta && meta.product && meta.product.variants) ? parseInt(meta.product.variants.filter(variant => variant.id.toString() === variantId.toString())[0].price) : null;

                    // Saves the offer properties to an easily accessible window object that is initialized in the config
                    Extend.integration.offerProperties = {variant: variantId, category: productCategory, price: productPrice}

                    // Renders Extend offer
                    Extend.buttons.render(extendOffer, { referenceId: variantId, price: productPrice, category: productCategory });

                    // Listens for changes to the productForm and sets the activeProduct for extend via variantID
                    productForm.addEventListener('change', function () {
                        variantId = productForm.id.value
                        if (variantId) {
                            productPrice = (meta && meta.product && meta.product.variants) ? parseInt(meta.product.variants.filter(variant => variant.id.toString() === variantId.toString())[0].price) : null;
                            Extend.setActiveProduct(extendOffer, { referenceId: variantId, price: productPrice, category: productCategory });
                            if (meta && meta.product && meta.product.vendor === 'Extend') addToCartButton.disabled = true;
                            Extend.integration.offerProperties = {variant: variantId, category: productCategory, price: productPrice}
                        }
                    });

                    // click simulation handling add to cart
                    function handleAddToCart(e) {
                        e.preventDefault();
                        e.stopImmediatePropagation();

                        const quantityEl = productForm.querySelector('[name="quantity"]');
                        const quantity = quantityEl && quantityEl.value ? quantityEl.value : 1;

                        ExtendShopify.handleAddToCart(extendOffer, {
                            quantity: quantity,
                            modal: Extend.integration.pdpModalOffer,
                            done: function () {
                                // Trigger Analytics
                                if (Extend.integration.analytics) Extend.integration.productAnalytics(variantId, quantity);
                                // remove default click listener
                                addToCartButton.removeEventListener('click', handleAddToCart, true);
                                // click atc button
                                addToCartButton.click();
                                // add default click listener back
                                addToCartButton.addEventListener('click', handleAddToCart, true);
                                // If variable set to true, dispatches Extend side cart integration to run after adding to cart via pdp
                                if (dispatchSideCart) window.setTimeout(function () { window.dispatchEvent(new Event('refreshAjaxSideCart')) }, 500)
                            }
                        });
                    }
                    // run handleCaddtoCart when we click ATC, capturing event
                    addToCartButton.addEventListener('click', handleAddToCart, true);
                } catch (error) {
                    console.error("EXTEND:", error)
                }
            }
            // Initial product offer render
            if (!Extend.buttons.instance(extendOffer)) {
                initProductOffer();
            }
        }
    }, { once: true });
</script>

<style>
    .extend-offer {
        margin: 0 0 -15px 0 !important;
    }
</style>

Configure

  1. Once you have located the placement of the offer you can configure the following code within the extend-product-page.liquid (lines 11-12):
    1. Replace the productFormSelector string form[action="/cart/add"] with the form class acquired above.
      Note: The class names must use css selectors. Be sure to convert the class you've acquired to the proper syntax, this includes replacing any spaces with . periods. If you have trouble read through our helpful tips here
    2. Replace the addToCartButton string button[name="add"] with the add to cart button class acquired above.
      Note: The class names must use css selectors. Be sure to convert the class you've acquired to the proper syntax, this includes replacing any spaces with . periods. If you have trouble read through our helpful tips here
// lines 12-13
const productForm = 'form[action="/cart/add"]'; // Change this to the product form element
const addToCartButton = 'button[name="add"]'; // Change this to the Add-To-Cart element
  1. Click Save

Verify

  1. Open the preview of the theme you are working on:
    Helpful Tips: Right click the Preview Theme button and click Open in new Tab

  1. Navigate to a warrantable product on your site.
    Note: If you are having trouble locating a warrantable product please reach out to our team through your Merchant Portal.
  2. Confirm the Product Page offer is displayed:

  1. Confirm the Modal offer is displayed:

If both Offers are displayed, Congratulations! You are ready for the next step.

If you run into any issues during this integration process or have questions please reach out to our team through your Merchant Portal.


Checklist