Fullstory's recommended approach is to use the new Shopify app.
The new Shopify app allows for events to be sent to Fullstory without any code to be managed by admins in your Shopify account. Additionally, for Shopify Plus customers, the Shopify app will allow you to capture session replay on your checkout flow where available. Session replay capabilities for checkout flow is not possible via the (legacy) pixel method described in this article.
Shopify is an eCommerce platform that provides tools to help online sellers run their businesses.
Once the data capture snippet and pixel have been added to your store as described below, Fullstory will be able to show user sessions on storefront pages (e.g. non-checkout pages) and listen out for events happening as the user moves through your checkout flow. Session replay will be unavailable on the checkout pages—only checkout event data for analytics will be present.
Fullstory provides shop administrators:
A recommended Order Status page script that sends a data-rich “Order Completed” event.
A custom web pixel that captures newly available analytics events. The pixel can be configured by a Shopify admin user and will work out-of-the-box with no custom development required.
Configuration Steps
Adding the Fullstory Checkout Extensibility pixel to Shopify
Configure a Revenue Event (Requires Fullstory Enterprise or Advanced)
Additional Information
- Events captured by Fullstory after creating a pixel
- Looking for Shopify Events in Fullstory
- Known limitations with the Fullstory Checkout Extensibility pixel
- Frequently Asked Questions
Step 1 - Installation
Method 1 - Add Fullstory snippet to the theme in Shopify
-
-
Login to your Shopify account, and open your Admin
panel.
-
Navigate to Online Stores > Themes.
-
Next to the theme you want to edit, click on the
ellipsis (...) button > Edit Code.
-
Locate
theme.liquidin the Layout folder, paste your Fullstory data capture snippet (learn how to find it here) into the<head>of the theme, and click Save.
Note: If you’re using a custom theme, it’s possible that the theme file has a name other thantheme.liquid. Check with the Shopify theme’s developer to verify. -
Login to your Shopify account, and open your Admin
panel.
Method 2 - Add Fullstory snippet via a Tag Manager
First, you’ll need to ensure that your tag manager has been installed on your Shopify store. To do this, please follow the steps below:
- In Shopify Admin, navigate to Online Stores > Themes.
- Find your current theme, click the (...) button > Edit Code.
- In the Layout folder, open
theme.liquid. - Check to see if your tag manager snippet is there. If not, paste your tag manager snippet just before the closing
</head>tag.
Next, you’ll want to install your Fullstory data capture snippet within your tag manager. You can find more detailed instructions for deploying using a tag manager here.
The web pixel is designed to send events to the outer page (e.g. collection or product) even if the outer page’s capture is delayed. Once the tag manager loads Fullstory, any events received will be processed at that time.
Step 2 - Adding the Fullstory Checkout Extensibility pixel to Shopify
Previously, merchants could manually add JavaScript snippets in several places in their online store: in online preferences, in checkout scripts, and in apps. Shopify is moving away from this approach to improve security, so customers using this method of deployment will need to manage scripts to track customer events using Shopify's pixel manager instead.
You can create a pixel for Fullstory by following the Add a custom pixel steps provided by Shopify:
- From your Shopify admin, go to Settings > Customer events.
- Click the Add custom pixel button.
- Name the pixel Fullstory Checkout Extension or similar.
- Click the Add pixel button.
-
Under Customer privacy, select the following:
-
Copy and paste the pixel’s JavaScript code from this article:
window._fs_org = '<org id>';
window._fs_identify_customer = false;
window._fs_use_order_completed = true;
window._fs_additional_scripts_snippet = false;
window._fs_host = 'fullstory.com';
window._fs_namespace = 'FS';
window._fs_debug = false;
window._fs_script = !window._fs_debug ? 'edge.fullstory.com/s/fs.js' : 'edge.fullstory.com/s/fs-debug.js';
function isAdditionalScriptAllowed() {
return Date.now() < new Date('2026-06-30');
}
function isCheckout() {
return document.location.pathname.indexOf('/checkouts/') !== -1;
}
function isThankYou() {
return document.location.pathname.indexOf('/thank_you') !== -1;
}
if (isCheckout() || isThankYou()) {
if (isCheckout()) {
window._fs_is_outer_script = true;
} else {
if (isAdditionalScriptAllowed() && window._fs_additional_scripts_snippet) {
window._fs_capture_on_startup = false;
} else {
window._fs_is_outer_script = true;
}
}
} else {
window._fs_run_in_iframe = true;
}
!function(m,n,e,t,l,o,g,y){var s,f,a=function(h){
return!(h in m)||(m.console&&m.console.log&&m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].'),!1)}(e)
;function p(b){var h,d=[];function j(){h&&(d.forEach((function(b){var d;try{d=b[h[0]]&&b[h[0]](h[1])}catch(h){return void(b[3]&&b[3](h))}
d&&d.then?d.then(b[2],b[3]):b[2]&&b[2](d)})),d.length=0)}function r(b){return function(d){h||(h=[b,d],j())}}return b(r(0),r(1)),{
then:function(b,h){return p((function(r,i){d.push([b,h,r,i]),j()}))}}}a&&(g=m[e]=function(){var b=function(b,d,j,r){function i(i,c){
h(b,d,j,i,c,r)}r=r||2;var c,u=/Async$/;return u.test(b)?(b=b.replace(u,""),"function"==typeof Promise?new Promise(i):p(i)):h(b,d,j,c,c,r)}
;function h(h,d,j,r,i,c){return b._api?b._api(h,d,j,r,i,c):(b.q&&b.q.push([h,d,j,r,i,c]),null)}return b.q=[],b}(),y=function(b){function h(h){
"function"==typeof h[4]&&h[4](new Error(b))}var d=g.q;if(d){for(var j=0;j<d.length;j++)h(d[j]);d.length=0,d.push=h}},function(){
(o=n.createElement(t)).async=!0,o.crossOrigin="anonymous",o.src="https://"+l,o.onerror=function(){y("Error loading "+l)}
;var b=n.getElementsByTagName(t)[0];b&&b.parentNode?b.parentNode.insertBefore(o,b):n.head.appendChild(o)}(),function(){function b(){}
function h(b,h,d){g(b,h,d,1)}function d(b,d,j){h("setProperties",{type:b,properties:d},j)}function j(b,h){d("user",b,h)}function r(b,h,d){j({
uid:b},d),h&&j(h,d)}g.identify=r,g.setUserVars=j,g.identifyAccount=b,g.clearUserCookie=b,g.setVars=d,g.event=function(b,d,j){h("trackEvent",{
name:b,properties:d},j)},g.anonymize=function(){r(!1)},g.shutdown=function(){h("shutdown")},g.restart=function(){h("restart")},
g.log=function(b,d){h("log",{level:b,msg:d})},g.consent=function(b){h("setIdentity",{consent:!arguments.length||b})}}(),s="fetch",
f="XMLHttpRequest",g._w={},g._w[f]=m[f],g._w[s]=m[s],m[s]&&(m[s]=function(){return g._w[s].apply(this,arguments)}),g._v="2.0.0")
}(window,document,window._fs_namespace,"script",window._fs_script);
var customer = init.data.customer;
if (window._fs_identify_customer && customer && customer.id) {
window[window._fs_namespace]('setIdentity', {
uid: customer.id,
properties: {
email: customer.email,
displayName: customer.firstName + ' ' + customer.lastName,
ordersCount: customer.ordersCount
}
});
}
function format(obj) {
var keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
if (keys && keys.length > 0) {
for (var key in obj) {
if (keys.includes(key)) {
delete obj[key];
} else if (typeof obj[key] === 'object' && obj[key] !== null) {
format(obj[key], keys);
}
}
}
return obj;
}
function trackEvent(name) {
var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (window._fs_debug) {
console.log(Date.now() + ' ' + name + ' ' + JSON.stringify(properties));
}
window[window._fs_namespace]('trackEvent', {
name: name,
properties: properties
}, 'shopify-pixel-v1');
}
if (isCheckout()) {
analytics.subscribe('clicked', function (event) {
trackEvent(event.name, format(event.data.element, ['value']));
});
analytics.subscribe('input_changed', function (event) {
trackEvent(event.name, format(event.data.element, ['value']));
});
}
analytics.subscribe('page_viewed', function (event) {
});
analytics.subscribe('cart_viewed', function (event) {
trackEvent(event.name, format(event.data.cart, ['lines']));
});
analytics.subscribe('collection_viewed', function (event) {
trackEvent(event.name, {
productVariants: event.data.collection.productVariants.length,
title: event.data.collection.title
});
});
analytics.subscribe('product_viewed', function (event) {
trackEvent(event.name, format(event.data.productVariant, ['image', 'url']));
});
analytics.subscribe('product_added_to_cart', function (event) {
trackEvent(event.name, format(event.data.cartLine, ['image', 'url']));
});
analytics.subscribe('product_removed_from_cart', function (event) {
trackEvent(event.name, format(event.data.cartLine, ['image', 'url']));
});
analytics.subscribe('search_submitted', function (event) {
trackEvent(event.name, {
productVariants: event.data.searchResult.productVariants.length,
query: event.data.searchResult.query
});
});
analytics.subscribe('checkout_started', function (event) {
trackEvent(event.name);
});
analytics.subscribe('checkout_address_info_submitted', function (event) {
trackEvent(event.name);
});
analytics.subscribe('checkout_contact_info_submitted', function (event) {
trackEvent(event.name);
});
analytics.subscribe('checkout_shipping_info_submitted', function (event) {
trackEvent(event.name);
});
analytics.subscribe('payment_info_submitted', function (event) {
trackEvent(event.name);
});
analytics.subscribe('checkout_completed', function (event) {
var checkout = event.data.checkout;
var properties = {
attributes: checkout.attributes.map(function (c) {
return c.key + "=" + c.value;
}),
currencyCode: checkout.currencyCode,
discountApplications: checkout.discountApplications.map(function (d) {
return d.allocationMethod + ':' + d.targetSelection + ':' + d.targetType + ':' + d.type;
}),
discountTitles: checkout.discountApplications.map(function (d) {
return d.title;
}),
lineItems: checkout.lineItems.length,
orderId: checkout.order.id,
subtotalPrice: checkout.subtotalPrice,
totalPrice: checkout.totalPrice,
totalTax: checkout.totalTax,
transactionGateways: checkout.transactions.map(function (t) {
return t.gateway;
})
};
if (window._fs_use_order_completed || !isAdditionalScriptAllowed()) {
properties.products = checkout.lineItems.map(function (l) {
return {
quantity: l.quantity,
productTitle: l.title,
price: l.variant?.price?.amount || 'unknown price',
sku: l.variant?.sku || 'unknown sku',
variantTitle: l.variant?.title || 'unknown variant title'
};
});
trackEvent('Order Completed', properties);
} else {
trackEvent(event.name, properties);
}
}); - Replace the text <org id> in the pixel’s code with your Org Id. To locate your Org Id, see the article How do I find my Fullstory Org Id. The resulting line will typically appear in this format: window._fs_org = 'o-0rGId-na1'; or window._fs_org = 'o-0rGId-eu1'; but may look a bit different for older accounts.
- Click the Save button.
-
Activate the pixel by clicking the Connect button.
It’s recommended that most customers use the pixel’s default configuration. For more advanced configuration and customization, please contact support@fullstory.com to inquire about Fullstory Professional Services.
Step 3 - Check 'Capture data by domain' settings
Go to Settings > Data Capture and Privacy > Data Capture and make sure 'All Other domains' is toggled ON:
This setting is required to allow the web pixel to work, as Fullstory’s capture data by domain feature is unable to identify the pixel’s iframe origin and determine if the domain is allowed. As a result, all domains must be allowed.
Step 4 - Configure a Revenue Event (Requires Fullstory Enterprise or Advanced)
As the pixel provides a conversion event, Admin users on a Fullstory Advanced or Enterprise plans with access to Conversions will be able to configure a revenue event as described here.
Choose the "Order Completed” event and select either total_price_real or totalPrice_real as the revenue property.
Events captured by Fullstory after creating a pixel
Fullstory custom events will now appear throughout session replays shortly after activating the pixel. More specifically, the following custom events have been instrumented:
Any theme page where the Fullstory snippet has been added:
- cart_viewed
- collection_viewed
- product_viewed
- product_added_to_cart
- product_removed_from_cart
- search_submitted
Payments page:
- checkout_started
- checkout_address_info_submitted
- checkout_contact_info_submitted
- checkout_shipping_info_submitted
- payment_info_submitted
- clicked (the value property will be removed to protect user privacy)
- input_changed (the value property will be removed to protect user privacy)
Thank you page (after August 28, 2025):
- checkout_completed renamed to “Order Completed”
Note: Some events may have data incompatible with Fullstory and may be omitted. You can check if this is the case under Settings > API Errors. Additionally, the pixel specifically omits the value property of Shopify DOM events as it could include sensitive or personal information.
Looking for Shopify Events in Fullstory
As a best practice (for both pixel and historical integration), segments and metrics using custom events on the thank you page should add the Entry Page is false criteria. When users become inactive on the thank you page and later active, Shopify may generate analytics events again. The Entry Page is false criteria excludes sessions and events that are the result of the user resuming activity on the thank you page after their previous session has ended.
Known limitations with the Fullstory Checkout Extensibility pixel
Due to technical limitations of the pixel sandbox provided by Shopify, the following issues are known to occur:
- Web pixels only run when visitors have provided the permissions required in the pixel configuration, you can read more about this requirement here: Customer privacy. By default, new pixels created will be set to require Marketing and Analytics permissions, e.g via a cookie banner. See Manage customer privacy settings for more information.
- The Checkout (Information, Shipping, Payment and Thank You) pages will appear as a blank white page in session replay. Fullstory session replays will show website content on all pages leading up to the Checkout page. Events will come in from the pixel accurately reflecting the time and user activity on these Checkout pages to use for analytics / search.
- To provide a fast experience for end-users, Shopify does not consistently trigger the
checkout_completedevent or "Order Completed" event for all purchases, so the purchase details are not always shared with Fullstory. This is more common on mobile devices. For this reason, you may see lower revenue totals in Fullstory compared to Shopify and discrepancies greater than about 15% can be expected. - You may have previously been able to capture session replay on the Thank You pages with a feature called Additional Scripts. As this feature is being deprecated over the period between January 2026 and June 2026, data capture on the order confirmation page using this method will no longer be available via the pixel.
- Fullstory's Browser APIs will not work on Shopify Checkout pages due to Shopify's security restrictions. This means you will be unable to instrument our browser APIs, such as our Identify Users API, Analytics Events API, Set Page Properties API, Shutdown & Restart APIs, and other Fullstory Browser APIs.
- Core Web Vital Metrics are not available through Shopify's APIs, which means customers cannot view or analyze these metrics for Shopify Checkout pages. Please note that Shopify extensively monitors checkout page performance for all merchants.
- Frustration signals (rage clicks, dead clicks, error clicks and thrashed cursor) and Watched Elements cannot be detected on Checkout pages.
- Fullstory's Heatmaps can not be used with Checkout pages or URLs, as this feature uses session replay data to create the visuals for click and scroll maps, which is not available unless you are using Fullstory’s Shopify App with a Shopify Plus plan instead of the pixel method.
Frequently Asked Questions
How can we determine if users apply discount codes or gift cards during checkout?
Depending on your configuration either the checkout_completed or “Order Completed” event will have discount code related information. The discountTitles_strs property contains discount code(s) or title(s) of discount(s) as found in Shopify administration. Additionally, the discountApplications_strs property will contain the allocationMethod, targetSelection, targetType, and type values provided by the checkout_completed event. Refer to the Shopify web pixels API for specifics on these properties.
Is it possible to determine when customers modify information within fields?
Yes, certain events provided by Shopify (e.g. checkout_contact_info_submitted), will include information provided by the customer. Additionally, input_changed events will indicate where customers enter information into a field; however, the pixel prevents capture of the value entered to limit the possibility of capturing personal or sensitive information. Pixel customization is required to adjust the code in order to capture these values. The format function in the pixel accepts a list of properties that should be removed. Alter the code format(event.data.element, ['value'])) to be format(event.data.element, []) instead.
Will data layer events appear as duplicates in Fullstory after the addition of the pixel?
If instrumented events using Fullstory APIs have names exactly matching those provided by Shopify, this situation is possible. Fullstory’s Enhanced E-commerce integration, however, has similar but different naming (add_product versus Shopify’s product_added_to_cart) and will not duplicate events. If duplicate events do exist, you can either edit the pixel’s code to remove the analytics.subscribe call for the offending event or archive an existing event to prevent it from being used by Fullstory end users. See the Sending custom event data into Fullstory article for details on archiving events.
Can I capture Network errors during Checkout?
Network errors are not included in the standard events that Shopify make available to Fullstory via the pixel. As an alternative, customers could consider implementing server-side events.
What should I do if I need to see all revenue data in Fullstory?
You will need to look at implementing server-side events for Fullstory, which can be configured using Shopify’s Flow App. You will need to work with your developers to link these events to a session.
What happens if I switch from the Pixel to using the Fullstory Shopify App?
If you are on a Shopify Plus plan and you switch from the Pixel to using the Fullstory Shopify App, you will gain session replay capabilities. The App is managed by the Fullstory team, so your admins and developers will not need to make any future code, as updates will happen automatically via the app. It is worth noting that you will need to either deactivate the pixel or prevent the App from using Order Completed to avoid duplication, as both methods listen out for the same checkout_completed event. If on an Advanced or Enterprise plan, you should also double check that your revenue event or revenue property looks to be the same, in case this needs to be updated.