Shopify Meta Pixel Generator
Meta Pixel as a Shopify custom pixel, with event IDs so Conversions API events don't get double-counted.
Your details
Paste into Settings > Customer events > Add custom pixel
// Meta Pixel custom pixel for Shopify (Web Pixels API).
// Paste into Settings > Customer events > Add custom pixel, save, then click Connect.
const PIXEL_ID = '1234567890123456';
// Meta's standard base code, adapted to run inside Shopify's pixel sandbox.
!function(f,b,e,v,n,t,tag){if(f.fbq)return;n=f.fbq=function(){n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;
tag=b.getElementsByTagName(e)[0];tag.parentNode.insertBefore(t,tag)}(window,document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', PIXEL_ID);
fbq('track', 'PageView');
const plainId = (id) => (id == null ? undefined : String(id).split('/').pop());
const money = (m) => (m && m.amount != null ? Number(m.amount) : 0);
const round = (x) => Math.round(x * 100) / 100;
function itemOf(variant, quantity) {
variant = variant || {};
const product = variant.product || {};
const variantTitle = variant.untranslatedTitle || variant.title;
return {
id: variant.sku || plainId(variant.id),
name: product.untranslatedTitle || product.title || variant.title,
variant: variantTitle && variantTitle !== 'Default Title' ? variantTitle : undefined,
price: money(variant.price),
quantity: quantity || 1,
};
}
function checkoutItems(checkout) {
return (checkout.lineItems || []).map((line) => {
const quantity = line.quantity || 1;
const unit = money(line.variant && line.variant.price);
const allocated = (line.discountAllocations || []).reduce((sum, d) => sum + money(d.amount), 0);
const price = round(Math.max(0, unit * quantity - allocated) / quantity);
return Object.assign(itemOf(line.variant, quantity), { price });
});
}
const itemsValue = (items) => round(items.reduce((sum, item) => sum + item.price * item.quantity, 0));
/* ---------- Events ---------- */
analytics.subscribe('product_viewed', (event) => {
const variant = event.data.productVariant;
const item = itemOf(variant, 1);
fbq('track', 'ViewContent', { content_ids: [item.id], content_type: 'product', content_name: item.name, value: item.price, currency: variant.price.currencyCode }, { eventID: 'view_' + item.id + '_' + Date.now() });
});
analytics.subscribe('product_added_to_cart', (event) => {
const line = event.data.cartLine;
if (!line) return;
const item = itemOf(line.merchandise, line.quantity);
fbq('track', 'AddToCart', { content_ids: [item.id], content_type: 'product', value: money(line.cost.totalAmount), currency: line.cost.totalAmount.currencyCode }, { eventID: 'cart_' + item.id + '_' + Date.now() });
});
analytics.subscribe('checkout_started', (event) => {
const checkout = event.data.checkout;
const items = checkoutItems(checkout);
fbq('track', 'InitiateCheckout', { content_ids: items.map((i) => i.id), value: itemsValue(items), currency: checkout.currencyCode, num_items: items.reduce((sum, i) => sum + i.quantity, 0) }, { eventID: checkout.token });
});
analytics.subscribe('checkout_completed', (event) => {
const checkout = event.data.checkout;
const order = checkout.order || {};
const items = checkoutItems(checkout);
const transactionId = plainId(order.id) || checkout.token;
fbq('track', 'Purchase', { content_ids: items.map((i) => i.id), content_type: 'product', value: itemsValue(items), currency: checkout.currencyCode, num_items: items.reduce((sum, i) => sum + i.quantity, 0) }, { eventID: transactionId });
});
To add it: Shopify admin > Settings > Customer events > Add custom pixel. Name it "Meta Pixel", paste the code, Save, then click Connect. Shopify only runs custom pixels after the shopper accepts Marketing/Analytics where consent is required; check that under Customer privacy > Permission.
Remove the Meta/Facebook Pixel channel under Settings > Apps and sales channels if it's also installed, and any Meta pixel base code pasted into theme.liquid. Two copies double-count every event, including purchases.
The event IDs above only dedupe against a Conversions API event you send server-side with the matching eventID (view_<id>_<timestamp>, cart_<id>_<timestamp>, the checkout token, or the order ID for Purchase). If you don't run Conversions API, dedupe has nothing to match and is harmless to leave on.
What it sends
The pixel loads Meta's standard fbq loader inside Shopify's custom pixel sandbox, then fires ViewContent, AddToCart, InitiateCheckout and Purchase from Shopify's checkout events, mapped to Meta's expected fields (content_ids, value, currency).
Turn on event IDs and each browser event carries an eventID: view_<id>_<timestamp> for views, the cart line ID for adds to cart, the checkout token for InitiateCheckout, and the order ID for Purchase. If you also send the same order through Meta's Conversions API server-side with a matching event ID, Meta counts it once instead of twice.
Installing it
- 01
Get your Pixel ID
Meta Events Manager > Data sources > your pixel > Settings.
- 02
Generate and paste the code
Settings > Customer events > Add custom pixel in Shopify admin, then Save and Connect.
- 03
Remove any other Meta pixel
Check Settings > Apps and sales channels for a Facebook & Instagram channel already sending events, and any Meta pixel base code in theme.liquid. Two live copies double-count Purchase.
Questions people ask
Do I still need the Facebook & Instagram sales channel app?
Not for pixel tracking if you use this custom pixel instead: run one or the other, not both, or Purchase gets counted twice.
What does the event ID actually do without Conversions API?
Nothing by itself: it's a no-op unless a matching server-side event with the same ID also reaches Meta. It's harmless to leave on either way.
Will this track Advantage+ shopping campaigns correctly?
It sends Meta's standard ecommerce events with value and currency, which is what Meta's automated campaign types read. It doesn't set up Advantage+ catalog feeds, which is a separate configuration.
Does consent apply here?
Yes: Shopify only runs custom pixels once the shopper accepts Marketing/Analytics where consent is required, under Customer privacy > Permission in admin.
Related tools
Last reviewed 30 September 2026.
Sources: Shopify: Web Pixels API standard events · Shopify: checkout_completed event · Shopify: Pixel privacy (customerPrivacy) · Shopify: Web Pixels browser API · Shopify Help Center: Create custom pixel code · Shopify Help Center: Manage custom pixels · Meta: Get started with Meta Pixel · Meta: Deduplicate Pixel and Conversions API events
