Shopify
Integrate Rybbit with your Shopify store to capture events, track conversions, and analyze user behavior.
Shopify
Rybbit can be integrated with your Shopify store to capture events, track conversions, and analyze user behavior.
How to Add Rybbit to Shopify
Retrieve Your Tracking Script
Navigate to your Rybbit dashboard to obtain your code snippet.
<script
src="https://app.rybbit.io/api/script.js"
data-site-id="YOUR_SITE_ID"
defer
></script>Add the Snippet to Your Shopify Store
- In Shopify, go to Online Store > Themes.
- Find your current theme, click the three dots (...) button next to Customize, and select Edit code.
- Open
theme.liquidin the Layout folder. - Just before the closing
</head>tag, insert your snippet. - Save the file to apply the changes to your live store.
Note: If you are editing a theme you purchased or one that receives updates, be aware that theme updates might overwrite your changes, requiring you to re-add the snippet. While Shopify doesn't have a formal "child theme" system like WordPress, some developers use theme duplication or version control as a workaround. For most users, re-adding the snippet after an update is the simplest approach if this occurs.
Tracking E-commerce Events
To get the most out of Rybbit with Shopify, you should track key e-commerce events. This typically involves adding small Liquid and JavaScript snippets to your theme files.
Always back up your theme before making code changes. If you are not comfortable editing theme code, consider hiring a Shopify expert. The following snippets are examples and might need adjustments based on your specific theme structure and Shopify version.
1. View Product (view_item)
Track when a user views a single product page.
Edit product.liquid (or your theme's main product template file, often found in templates/product.liquid or sections/main-product.liquid or similar):
Add the following script towards the end of the file, or within a relevant product information block:
{% raw %}{% comment %} Add to product.liquid or main product section {% endcomment %}
<script type="text/javascript">
if (typeof window.rybbit !== 'undefined' && {{ product | json }}) {
const rybbitProduct = {{ product | json }};
const rybbitCurrentVariant = {{ product.selected_or_first_available_variant | json }};
window.rybbit.event('view_item', {
item_id: rybbitCurrentVariant.sku || rybbitCurrentVariant.id,
item_name: rybbitProduct.title,
item_variant: rybbitCurrentVariant.title === 'Default Title' ? null : rybbitCurrentVariant.title,
price: parseFloat(rybbitCurrentVariant.price) / 100, // Price is in cents
currency: {{ cart.currency.iso_code | json }}
});
}
</script>{% endraw %}2. Add to Cart (add_to_cart)
Tracking "add to cart" events can be complex due to themes using AJAX for cart updates. Here's a common approach by attaching an event listener to your "Add to Cart" button.
Identify your "Add to Cart" button/form in product.liquid or your product form section.
You'll need to add a script that listens for clicks or form submissions. This example assumes your "Add to Cart" button has an ID like add-to-cart-button or is part of a form with a specific class or ID. You may need to adjust the selector.
{% raw %}{% comment %} Add near your product form or Add to Cart button in product.liquid/product form section {% endcomment %}
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
const addToCartForm = document.querySelector('form[action="/cart/add"]'); // Common selector for product forms
const addToCartButton = document.getElementById('add-to-cart-button') || addToCartForm?.querySelector('[type="submit"]');
const trackAddToCart = function() {
if (typeof window.rybbit !== 'undefined' && {{ product | json }}) {
const rybbitProduct = {{ product | json }};
const rybbitCurrentVariant = {{ product.selected_or_first_available_variant | json }};
let quantity = 1;
const quantityInput = addToCartForm?.querySelector('[name="quantity"], input[type="number"]'); // Common quantity input selectors
if (quantityInput && quantityInput.value) {
quantity = parseInt(quantityInput.value, 10);
}
window.rybbit.event('add_to_cart', {
item_id: rybbitCurrentVariant.sku || rybbitCurrentVariant.id,
item_name: rybbitProduct.title,
item_variant: rybbitCurrentVariant.title === 'Default Title' ? null : rybbitCurrentVariant.title,
price: parseFloat(rybbitCurrentVariant.price) / 100,
currency: {{ cart.currency.iso_code | json }},
quantity: quantity > 0 ? quantity : 1
});
}
};
if (addToCartButton) {
addToCartButton.addEventListener('click', function(event) {
// Delay slightly to allow form submission/validation if needed, or track on form submit
// For themes with AJAX add to cart, this might need to hook into the theme's specific JS events.
setTimeout(trackAddToCart, 100); // Basic click tracking
});
} else if (addToCartForm) {
addToCartForm.addEventListener('submit', function(event) {
trackAddToCart(); // Track on form submission
});
}
});
</script>{% endraw %}For themes with AJAX "Add to Cart" functionality (where the page doesn't reload), you might need to listen for custom JavaScript events fired by your theme after an item is successfully added to the cart, or observe changes to the cart. This can be theme-specific.
3. Begin Checkout (begin_checkout)
Shopify's checkout process is on a separate domain (checkout.shopify.com), and direct script injection into the checkout pages (beyond the "Order status" page) is limited for most plans. However, Rybbit's script, if loaded on your main store, should persist session information.
A common way to track "begin_checkout" is by tracking clicks on checkout buttons.
Edit cart.liquid (or your theme's main cart template, often templates/cart.liquid or sections/main-cart-items.liquid):
Find your "Checkout" button and add an ID to it if it doesn't have one (e.g., id="checkout-button"). Then add this script:
{% raw %}{% comment %} Add to cart.liquid, near the checkout button logic {% endcomment %}
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
const checkoutButton = document.getElementById('checkout-button') || document.querySelector('[name="checkout"], form[action$="/checkout"] [type="submit"]'); // Common selectors
if (checkoutButton && typeof window.rybbit !== 'undefined' && {{ cart | json }}) {
checkoutButton.addEventListener('click', function() {
const rybbitCart = {{ cart | json }};
let items = [];
rybbitCart.items.forEach(function(item) {
items.push({
item_id: item.sku || item.variant_id,
item_name: item.product_title,
item_variant: item.variant_title === 'Default Title' ? null : item.variant_title,
price: parseFloat(item.final_price) / 100,
quantity: item.quantity
});
});
window.rybbit.event('begin_checkout', {
currency: rybbitCart.currency,
value: parseFloat(rybbitCart.total_price) / 100,
items: items
});
});
}
});
</script>{% endraw %}Rybbit limits an event's properties to 2048 characters once serialized to
JSON, and events that exceed the limit are rejected (not truncated). A full
per-item items array can blow past this on large carts. For carts with many
line items, send a compact payload — trimmed item fields (e.g. id, quantity,
price only) or just the aggregate value, currency, and transaction_id.
4. Purchase (purchase)
Track completed purchases on the Shopify "Thank You" / order status page.
The old Order status page > Additional scripts field has been deprecated. As
of August 28, 2025 it is view-only (Shopify Plus migration deadline), non-Plus
stores must migrate by August 26, 2026, and automatic upgrades that began in
January 2026 remove any remaining checkout.liquid / Additional-scripts
customizations. The supported path for tracking purchases is now
Checkout Extensibility
via a custom web pixel.
Custom web pixels run in a sandboxed environment, so they cannot access
window.rybbit on the storefront. Instead, subscribe to the standard
checkout_completed event and send the purchase directly to Rybbit's tracking
endpoint with fetch.
1. Create a custom pixel:
- In your Shopify Admin, go to Settings > Customer events.
- Click Add custom pixel, give it a name (e.g.
Rybbit), and click Add pixel.
2. Add the pixel code:
- Paste the following into the code editor, replacing
YOUR_SITE_IDwith your Site ID, then Save and Connect the pixel.
analytics.subscribe("checkout_completed", (event) => {
const checkout = event.data.checkout;
// Keep the payload small — Rybbit rejects event properties over 2048 chars
// (serialized JSON). Send compact per-item data for large carts.
const items = (checkout.lineItems || []).map((li) => ({
id: li.variant?.sku || li.variant?.id,
qty: li.quantity,
price: li.variant?.price?.amount,
}));
fetch("https://app.rybbit.io/api/track", {
method: "POST",
headers: { "Content-Type": "application/json" },
keepalive: true,
body: JSON.stringify({
type: "custom_event",
site_id: "YOUR_SITE_ID",
event_name: "purchase",
// `properties` must be a JSON string (max 2048 chars).
properties: JSON.stringify({
transaction_id: checkout.order?.id || checkout.token,
value: checkout.totalPrice?.amount,
currency: checkout.currencyCode,
items: items,
}),
}),
});
});Explanation:
analytics.subscribe("checkout_completed", ...)fires once when an order is successfully placed, so purchases are tracked without editingcheckout.liquid.- The pixel POSTs a
custom_eventstraight to Rybbit's/api/trackendpoint because the sandbox has no access to the storefront'swindow.rybbit. propertiesis sent as a JSON string and must stay under 2048 characters — see the note above about trimming large carts.
Important Considerations
- Theme Differences: Shopify themes can vary significantly. You may need to adjust Liquid object paths (e.g.,
product.selected_or_first_available_variantvs.current_variant) and JavaScript selectors based on your specific theme's structure. - Currency Conversion: Prices in Shopify Liquid objects are often in cents. Ensure you divide by 100 to get the decimal value for Rybbit.
- AJAX Carts: If your theme uses an AJAX cart (drawer or pop-up cart that updates without page reload), tracking
add_to_cartaccurately requires hooking into your theme's specific JavaScript events or using MutationObserver to detect cart changes. The providedadd_to_cartexample is a basic starting point. - Shopify Customer Events: For more robust server-side or client-side event tracking, especially for
add_to_cartandbegin_checkoutwithout relying on DOM manipulation, explore Shopify Customer Events. This allows you to subscribe to events like "product added to cart" or "checkout started" and send data to Rybbit via a custom pixel or by triggering client-side JavaScript. This is a more advanced but often more reliable method. - Testing: Thoroughly test each event in your Rybbit dashboard after implementation. Use your browser's developer console to check for JavaScript errors.