Integrate with a Shopify Hydrogen store
Learn how to integrate with a Shopify Hydrogen store, or with any headless Shopify store using a custom storefront
While this guide uses examples for Shopify's Hydrogen framework, the concepts and principles are true for any setup where you are using Shopify to power your ecommerce store’s backend, but have a custom storefront (a “headless” setup). This integration requires 2 main steps:
- Connect your Shopify store via Klaviyo’s native integration to sync order, catalog, and subscriber data
- Manually add code snippets to your site to enable onsite tracking functionality
For free accounts
As discussed below, if you don't have redirect rules in place from the myshopify.com domain to your hosted domain, or don't want shoppers to see the myshopify.com domain in Klaviyo emails, you will need to contact Klaviyo's customer support team to update the product URLs that automatically sync through your catalog. If you are using Klaviyo's free plan, you have 60 days of dedicated email support after account creation during which you can submit a request. After the 60 day period, you must upgrade your account to submit further requests.
Key integration components
The key components of integrating this type of ecommerce solution are:
- Customer data
Tracking information such as name, email, phone number, and other profile attributes - Subscribers
Tracking who opts in and to what marketing channel (e.g., your email newsletter subscribers) - Order activity
Tracking when a customer places an order, what products are ordered, etc. - Products
The items in your catalog - Website activity
Tracking who is active on your site, what products they view, etc.
With the exception of website activity, Klaviyo’s native Shopify integration will sync all of the above data for a headless Shopify store because this data is fetched server-side via API.
Additionally, if you don't have redirect rules in place from the myshopify.com domain to your hosted domain, or don't want shoppers to see the myshopify.com domain in Klaviyo emails, you will need to request that Klaviyo support update the product URLs that automatically sync through your catalog. Read the catalog section below to learn more.
Connect Klaviyo’s native Shopify integration
The first step is to integrate your Shopify store via Klaviyo’s native integration. Follow the steps in our Getting started with Shopify guide through step 14. Ignore the Onsite Tracking box and its status; you’ll add onsite tracking manually later.
Enable onsite tracking
For headless setups, you will need to manually install Klaviyo's “Active on Site” JavaScript (also known as Klaviyo.js). Klaviyo.js tracks when users are active on your site and enables Klaviyo forms.
If you want to track when users view specific products on your site (which can be leveraged in a browse abandonment flow), you’ll need to add Klaviyo’s Viewed Product tracking JavaScript snippet. Below, we provide code snippets and guidance for tracking Active on Site, Viewed Product, and Added to Cart events, which allow you to send cart abandonment flows.
Based on your Customer Privacy settings in Shopify, Klaviyo may not track onsite events (including Active on Site, Viewed Product, and Added to Cart) for visitors to your Shopify store in the EU, EEA, UK and Switzerland, unless they have provided consent. This does not affect logged-in user tracking.
Add Active on Site tracking
With Hydrogen 2, you’ll want to include import {Script} from '@shopify/hydrogen';
in root.jsx
and add our standard onsite snippet within a Script
element. Replace the placeholder value for the PUBLIC_API_KEY
in the example below with your Klaviyo Public API key.
export default function App() {
const nonce = useNonce();
/** @type {LoaderReturnData} */
const data = useLoaderData();
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<Meta />
<Links />
</head>
<body>
<Layout {...data}>
<Outlet />
</Layout>
<Script async type="text/javascript"
src="//static.klaviyo.com/onsite/js/PUBLIC_API_KEY/klaviyo.js" />
<ScrollRestoration nonce={nonce} />
<Scripts nonce={nonce} />
</body>
</html>
);
}
Add Viewed Product and Added to Cart tracking
To implement Viewed Product and Added to Cart tracking, we recommend first creating a component for our onsite tracking. In the example below, we create an Onsite component in app/components/Onsite.jsx
and then add our standard Viewed Product and Added to Cart tracking requests.
Make sure to update the values of the JSON properties in the snippet so that they dynamically pull from the relevant information needed for that property.
export function trackViewedProduct(product) {
let klaviyo = window.klaviyo || [];
let item = {
Name: product.title,
ProductID: product.id.substring(product.id.lastIndexOf('/') + 1),
ImageURL: product.selectedVariant.image.url,
Handle: product.handle,
Brand: product.vendor,
Price: product.selectedVariant.price.amount,
Metadata: {
Brand: product.vendor,
Price: product.selectedVariant.unitPrice,
CompareAtPrice: product.selectedVariant.compareAtPrice,
}
};
klaviyo.push(['track', 'Hydrogen Viewed Product', item]);
klaviyo.push(['trackViewedItem', item]);
}
export function trackAddedToCart(product) {
let klaviyo = window.klaviyo || []
let item = {
Name: product.title,
ProductID: product.id.substring(product.id.lastIndexOf('/') + 1),
ImageURL: product.selectedVariant.image.url,
Handle: product.handle,
Brand: product.vendor,
Price: product.selectedVariant.price.amount
}
klaviyo.push(['track', 'Hydrogen Added To Cart', item])
}
You can now import those functions into your product file (for example, app/routes/products.$handle.jsx
). Import the onsite functions and useEffect
into your product file:
import { useEffect } from "react";
import {trackViewedProduct, trackAddedToCart} from '~/components/Onsite';
Then, you can load trackViewedProduct
on page load via useEffect
within your Product()
function. Here’s an example of how this would look within your products.$handle.jsx
file:
export default function Product() {
/** @type {LoaderReturnData} */
const {product, variants} = useLoaderData();
const {selectedVariant} = product;
// Execute VP on page load ***
useEffect(() => {
trackViewedProduct(product);
},[]);
return ( ...
For trackAddedToCart
, you’ll want to invoke this within your added to cart click handler. Here’s an example snippet using the ProductForm()
function:
function ProductForm({product, selectedVariant, variants}) {
// define atc ***
const handleAtc = function () {
trackAddedToCart(product)
}
return (
<div className="product-form">
<VariantSelector
handle={product.handle}
options={product.options}
variants={variants}
>
{({option}) => <ProductOptions key={option.name} option={option} />}
</VariantSelector>
<br />
<AddToCartButton
disabled={!selectedVariant || !selectedVariant.availableForSale}
onClick={() => {
// Add our newly created click handler ***
handleAtc();
window.location.href = window.location.href + '#cart-aside';
}}
lines={
selectedVariant
? [
{
merchandiseId: selectedVariant.id,
quantity: 1,
},
]
: []
}
>
{selectedVariant?.availableForSale ? 'Add to cart' : 'Sold out'}
</AddToCartButton>
</div>
);
}
With our onsite scripts, forms should appear on local environments without any issues. However, content security policies can impact the functionality of our scripts both on local and production environments. We suggest testing through preview builds sent up to Shopify via Oxygen or custom deployments. If you encounter issues, you’ll need to configure your CSP to allow our JavaScript to function.
Example code for onsite tracking
Klaviyo has provided reference code to showcase how to implement the onsite tracking above. You can also check out the test store that utilizes this reference code.
Update your Shopify catalog URLs
Your Shopify catalog will sync with Klaviyo through the native integration, though the product catalog in Klaviyo will autopopulate with the myshopify.com URL. Contact Klaviyo support to request an update to this setting.
The URL can be updated from:
https://[INSTANCE].myshopify.com/products/[PRODUCT_HANDLE]
to:
https://[STOREFRONT_URL]/products/[PRODUCT_HANDLE]
Server-side and onsite metrics
Once you connect your store, the following metrics will sync through Klaviyo’s native Shopify integration:
- Checkout Started
When customers start a checkout and provide their contact information - Placed Order
When an order successfully processes on your system - Ordered Product
An event for each item in a processed order - Fulfilled Order
When an order is sent to the customer - Fulfilled Partial Order
When an order that has been placed is partially fulfilled - Canceled Order
When an order is canceled - Refunded Order
When a customer’s order is refunded
Checkout Started events will sync only if customers enter contact and shipping information on the first page of the checkout process and click continue.
For more information about metrics synced from Shopify and their properties, check out our Shopify data reference.
The following onsite metrics can be tracked in Klaviyo by manually adding the code snippets shared above to your site:
- Active on Site
When someone visits your website - Viewed Product
When someone views a product - Added to Cart
When someone adds an item to their cart
Additional resources
Klaviyo resources
Shopify resources
Updated about 2 months ago