📍 Bolt Help / Integrations / Marketing & Communications / Connect Klaviyo with Bolt
Connect Klaviyo with Bolt
Learn how to connect Klaviyo with Bolt.

Klaviyo is a marketing automation tool that merchants can use to send marketing newsletters, abandoned cart and abandoned checkout emails, SMS marketing, and other custom customer communication flows. Using callbacks in checkout, you can configure a variety of Klaviyo’s messaging features manually via Bolt.

How It Works

An email or phone number is needed to identify a shopper. You can obtain this data from a pop-up form or at checkout by checking the marketing consent box. A cookie used for tracking is generated once a shopper is identified.. Klaviyo manages event capture and consent for most e-commerce platforms, but modifications may be necessary for Bolt’s checkout experience.

Integration

DEPRECATION

Bolt has deprecated the Klaviyo automatic integration. Use the manual integration method instead, which is outlined in this article.

Before You Start

Before you can integrate Bolt with Klaviyo, ensure that:

  1. You know which Klaviyo features you would like to enable.
  2. You have installed Klaviyo on your ecommerce platform so you can leverage their APIs to track events.
  3. You have reviewed Klaviyo’s documentation on using Sign-Up Forms to identify shoppers.

Available Events

Klaviyo tracks shopper activity on your site by capturing events.

Most events are transmitted automatically when you are integrated with Klaviyo. However, a few events such as those related to Checkout (e.g., Started Checkout) require additional setup. To capture these events, identify the shopper through a callback during checkout or through a Klavyo Form using the Javascript Track API.

Expand each section below to learn more about enabling that Klaviyo event or feature with your ecommerce platform.

Active on site

Click to expand.

Viewed product

Click to expand.

Added to cart

Click to expand.

Started checkout

Click to expand.

Placed order

Click to expand.

Ordered product

Click to expand.

Fulfilled, cancelled, or refunded order

Click to expand.

Features

Feature BigCommerce Shopify WooCommerce M2 Server-side API
Identify shopper Identify User through Bolt SSO or via callbacks Identify User via callbacks Install WooCommerce plugin for Klaviyo and the Bolt Plugin Identify User via callbacks Integrate a platform without a pre-built Klaviyo integration
Email consent at checkout Server-side API: Captured from platform Customer data Server-side API: Captured from platform Customer data Install WooCommerce plugin for Klaviyo and the Bolt Plugin Server-side API: Captured from platform Customer data Integrate a platform without a pre-built Klaviyo integration
SMS consent at checkout Proxy API Proxy API Install WooCommerce plugin for Klaviyo and the Bolt Plugin Proxy API Integrate a platform without a pre-built Klaviyo integration

SMS Marketing

To use SMS Marketing with Klaviyo, you must first setup an SMS plan and sender number. See Klaviyo’s Getting Started with SMS guide. You can then leverage Klaviyo’s Proxy API along with callbacks to collect customer information and send SMS notifications.

Set Up for BigCommerce

Before You Start

Install the Klaviyo native integration in BigCommerce, according to Klaviyo’s How to Integrate with BigCommerce guide.

Events

The Klaviyo integrations can be implemented in the Bolt callbacks function.

Event Trigger Data location
Started Checkout onEmailEnter Client-side JS object
Placed Order success Client-side JS object
Order Product success Client-side JS object
Email Consent at Checkout success Data sent by client-side subscription service call
SMS Consent at Checkout success Data sent by client-side subscription service call
Identify Shopper onEmailEnter Client-side JS object

Example Script

This example is a script that captures these shopper events. Replace the variables in the table below with your store’s data.

Variable Definition
COMPANY_ID The Merchant’s Klaviyo Company ID. Can be found in their Klaviyo script in the Script Manager.
EMAIL_LIST_ID The Email consent list ID in Klaviyo. Should be provided by the merchant.
SMS_LIST_ID The SMS consent list ID in Klaviyo. Should be provided by the merchant.
NEWSLETTER_CHECKBOX_ID The public ID of the newsletter checkbox in the Bolt admin dashboard.
SMS_CHECKBOX_ID The public ID of the SMS checkbox in the Bolt admin dashboard.
var fetchCart = async function() {
      const response = await fetch('/api/storefront/cart', {credentials: 'include'});
      const data = await response.json();
      return data;
  }
  
  var createSubscription = function(list_id, email, phone) {
      const url = 'https://a.klaviyo.com/client/subscriptions/?company_id=COMPANY_ID';
      let attributes = {
        list_id: list_id  
      };
      if (email) {
          attributes.email = email;
      }
      if (phone) {
          attributes.phone_number = phone;
      }
      const options = {
          method: 'POST',
          headers: {revision: '2023-01-24', 'content-type': 'application/json'},
          body: JSON.stringify({
              data: {
                  type: "subscription",
                  attributes: attributes
              }
          })
      };
      fetch(url, options)
      .then(res => res.text())
      .then(data => console.log(data))
      .catch(err => console.error('error:' + err));
  };
  
  var createEvent = function(data) {
      const url = 'https://a.klaviyo.com/client/events/?company_id=COMPANY_ID';
      const options = {
          method: 'POST',
          headers: {
            accept: 'application/json',
            revision: '2023-01-24',
            'content-type': 'application/json'
          },
          body: JSON.stringify({
            data: data
          })
        };
        
        fetch(url, options)
          .then(res => res.text())
          .then(data => console.log(data))
          .catch(err => console.error('error:' + err));
  };
  var items = [];
  var itemNames = [];
  var cartAmount = 0;
  var callbacks = {
      check : function () {
          // Executes just before the checkout form loads.
          // Must return a boolean that will determine if Bolt should proceed with checkout.
          return true;
      },
      onCheckoutStart : async function () {
          // Executes after the checkout form is presented to the user
          let cart = await fetchCart();
          items = [].concat(cart[0].lineItems.customItems, cart[0].lineItems.digitalItems, cart[0].lineItems.giftCertificates, cart[0].lineItems.physicalItems);
          let tempItems = [];
          for(let i = 0; i < items.length; i++) {
              tempItems.push(items[i].name);
          }
          itemNames = tempItems;
          cartAmount = cart[0].cartAmount;

      },
      onEmailEnter: function (email) {
          // Executes after the user enters their email address.
          var _learnq = _learnq || []; 
          _learnq.push(['identify', {'$email': email}]);

          _learnq.push(['track','Started checkout', {
             "$event_id": "StartedCheckout_" + Date.now() + "_" + email,
             "$value": cartAmount,
             "ItemNames": itemNames,
             "CheckoutURL": "{{settings.secure_base_url}}{{urls.cart}}",
             "Items": items
          }]);
      },
      onShippingDetailsComplete: function (address) {
          // Executes when the user proceeds to the shipping options page.
          // This is applicable only to multi-step checkout.
          // When available the first parameter will contain a user's name and address info.
      },
      onShippingOptionsComplete: function () {
          // Executes when the user proceeds to the payment details page.
          // This is applicable only to multi-step checkout.
      },
      onPaymentSubmit: function () {
          // Executes after the user clicks the pay button.
      },
      success: function (transaction, callback) {
          // Executes when the Bolt checkout transaction is successful.
          // **IMPORTANT** callback() must be executed at the end of the success function
        var customFields = transaction.custom_field_responses;
        for (let i = 0; i< customFields.length; i++) {
        if (customFields[i].public_id === 'NEWSLETTER_CHECKBOX_ID' &&  customFields[i].response === true) { // Newsletter Consent
              createSubscription('EMAIL_LIST_ID', transaction.shipping_address.email, '');
          }
          if (customFields[i].public_id === 'SMS_CHECKBOX_ID' &&  customFields[i].response === true) { // SMS Consent
              let phone = transaction.from_consumer.phones[0] ? transaction.from_consumer.phones[0].number : null;
              if (phone) {
                  phone = phone.replace(/ /g,'');
                  createSubscription('SMS_LIST_ID', '', phone);
              }
          }      
        }

          // Placed Order event
          let profile = {
              "$email": transaction.shipping_address.email,
              "$phone_number": transaction.shipping_address.phone,
              "$first_name": transaction.shipping_address.first_name,
              "$last_name": transaction.shipping_address.last_name,
              "$city": transaction.shipping_address.locality,
              "$region": transaction.shipping_address.region,
              "$country": transaction.shipping_address.country,
              "$zip": transaction.shipping_address.postal_code
          };
          let placedOrderData = {
              type: 'event',
              attributes: {
                profile: profile,
                metric: {name: 'Placed Order'},
                properties: {
                    OrderId: transaction.merchant_order_number,
                    BillingAddress: {
                        "FirstName": transaction.billing_address.first_name,
                        "LastName": transaction.billing_address.last_name,
                        "Company": transaction.billing_address.company,
                        "Address1": transaction.billing_address.street_address1,
                        "Address2": transaction.billing_address.street_address2,
                        "City": transaction.billing_address.locality,
                        "Region": transaction.billing_address.region,
                        "Country": transaction.billing_address.country,
                        "CountryCode": transaction.billing_address.country_code,
                        "Zip": transaction.billing_address.postal_code,
                        "Phone": transaction.billing_address.phone
                    },
                    ShippingAddress: {
                        "FirstName": transaction.shipping_address.first_name,
                        "LastName": transaction.shipping_address.last_name,
                        "Company": transaction.shipping_address.company,
                        "Address1": transaction.shipping_address.street_address1,
                        "Address2": transaction.shipping_address.street_address2,
                        "City": transaction.shipping_address.locality,
                        "Region": transaction.shipping_address.region,
                        "Country": transaction.shipping_address.country,
                        "CountryCode": transaction.shipping_address.country_code,
                        "Zip": transaction.shipping_address.postal_code,
                        "Phone": transaction.shipping_address.phone
                    },
                    ItemNames: itemNames,
                    Items: items
                },
                value: Number(transaction.amount.amount) / 100,
                unique_id: transaction.merchant_order_number
              }
            };
          createEvent(placedOrderData);
          // Orderd Product
          for (let i = 0; i < items.length; i++) {
              let orderedProductData = {
                  type: 'event',
                  attributes: {
                    profile: profile,
                    metric: {name: 'Ordered Product'},
                    properties: {
                      OrderId: transaction.merchant_order_number,
                      ProductID: items[i].productId,
                      SKU: items[i].sku,
                      ProductName: items[i].name,
                      Quantity: items[i].quantity,
                      ProductURL: items[i].url,
                      ImageURL: items[i].imageUrl
                    },
                    value: items[i].salePrice,
                    unique_id: 'OrderedProduct_' + Date.now() + '_' + items[i].sku
                  }
                };
                createEvent(orderedProductData);
          }
          callback()
      },
      close: function () {
          // This function is called when the Bolt checkout modal is closed.
          // This will not be called when create_order endpoint returns a valid URL
          // and authorization is successful
      }
  }

Enable Newsletters

To collect email conset, enable the newsletter in BigCommerce.

This automatically adds anyone who opts-in to newsletters when checking out via Bolt to the subscriber list. Bolt will send the data to BigCommerce and BigCommerce will pass the data to Klaviyo.

Set Up for Magento 2 / Adobe Commerce

Before You Start

Install the Klaviyo integration in Magento 2, according to Klaviyo’s How to Integrate with Magento 2 guide.

Enable Newsletter

If enabling the newsletter subscriber function, configure a newsletter checkbox in Bolt checkout by contacting your customer success manager.

This automatically adds anyone who opts-in to newsletters when checking out via Bolt to the subscriber list.

Klaviyo then pulls customer emails from this list via the Klaviyo integration installed on the platform. Bolt does not directly pass this information to Klaviyo.

Enable Callbacks

  1. To leverage additional Klaviyo functionality, merchants should use our callbacks functionality to trigger messaging based on shopper actions in checkout.

  2. If you are unsure which properties are available in a given callback, use console.log to return the arguments object. You’ll then see all available arguments you can use to build out callbacks in checkout:

    console.log(arguments) / console.log(JSON.stringify(arguments))
    
  3. To configure the desired callbacks in your Magento admin account go to Stores > Configuration > Sales > Payment Methods > Bolt Pay > Advanced Options.


Set Up for WooCommerce

Before You Start

Enable Newsletters

If enabling the newsletter subscriber function, configure a newsletter checkbox in Bolt checkout by contacting your customer success manager.

This automatically adds anyone who opts-in to newsletters when checking out via Bolt to a list.

Klaviyo then pulls customer emails from the list via the Klaviyo integration installed in the platform. Bolt does not directly pass this information to Klaviyo.

Enable Callbacks

  1. To leverage any additional Klaviyo functionality, merchants should use Bolt callback functionality to trigger messaging based on shopper actions in checkout.

  2. If you are unsure which properties are available in a given callback, use console.log to return the arguments object. You’ll then see all available arguments you can use to build out callbacks in checkout:

    console.log(arguments) / console.log(JSON.stringify(arguments))
    
  3. Configure the desired callbacks in your WooCommerce admin account by navigating to Plugins > WooCommerce Bolt Checkout > Settings.

Send Started Checkout Event (Optional)

To trigger the Started Checkout event when an email is captured, add the following snippet to the Bolt plugin Settings in WooCommerce:

window.dispatchEvent(new CustomEvent('boltKlaviyoStartedCheckout', { detail: { email: email }}));

You can collect shopper consent at checkout to opt in to email marketing using the Klaviyo integration. Contact a Bolt representative.

You can collect shopper consent at checkout to opt in to SMS marketing using the Klaviyo integration. Contact a Bolt representative.

Set Up Callbacks for Other Commerce Platforms

In the event that you don’t use any of the ecommerce platforms in this guide, you may still be able to set up an integration between Klaviyo and Bolt using callbacks.

How you do this usually varies per commerce platform, however, it typically requires providing your Publishable Bolt API key and enabling Bolt Pay. Then, you’ll need to set up callbacks and other Bolt functionalities in checkout according to the Klaviyo Feature Enablement Options section.

Set Up for Direct API

For all events and features, use the Klaviyo guide for direct API implementations: Integrate a platform without a pre-built Klaviyo integration.

Additional Resources