# How to set-up Shopify Custom Pixel App

The Custom pixel is one of the two options we have built to help you integrate AB Tasty in your Shopify workflows. It specifically ensures transactional hits during checkout through Shopify's checkout extensibility. However, you'll still need to inject the AB Tasty tag manually on other pages of your site to capture full user interactions. To learn more about the two options and decide which one you should use, please refer to the [AB Tasty integration with Shopify](/account/tag-integration/implement-ab-tasty-tag/ab-tasty-integration-with-shopify.md) article.

**To use the extension**\
you must be an AB Tasty customer.\
To complete the installation, you will need your AB Tasty identifier (the ID of your tag).\
Your store must use Shopify Hydrogen or another Headless Framework\
This application works as a standalone

&#x20;

**Installation steps**

1. Log In Shopify
2. Navigate to [Your store > Settings > Customer events](https://admin.shopify.com/store/YOURSTORE/settings/customer_events).
3. Copy and adapt the provided code snippet (see example below)
4. To retrieve your AB Tasty identifier, access the [Generic tag page](broken://pages/4VmVflMHsS6fKknDOgxf)
5. Copy your AB Tasty account identifier in REPLACE\_WITH\_YOURABTASTY\_IDENTIFIER section.
6. Complete the creation of the custom pixel

### Code snippet for Custom Pixel example: <a href="#h_01jt16cs6p0wfw5fk98spsmbmg" id="h_01jt16cs6p0wfw5fk98spsmbmg"></a>

```
// REQUIRED
const ABTASTY_IDENTIFIER = "REPLACE_WITH_YOURABTASTY_IDENTIFIER";

// OPTIONAL
const FEATURE_EXP_ENVIRONMENT_ID = "REPLACE_WITH_YOURFLAGSHIP_IDENTIFIER"; // see more https://www.abtasty.com/feature-experimentation/

// Load AB Tasty tag
(function (i, s, o, g, r, a, m) {
i.abtiming = 1 * new Date();
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
console.log("ABTASTY: loading tag with identifier:", ABTASTY_IDENTIFIER);
})(window, document, "script", `//try.abtasty.com/${ABTASTY_IDENTIFIER}.js`);

const visitorId = document.cookie.match(/FLAGSHIP_VISITOR_ID=([^;]+)/i)?.[1];

analytics.subscribe("checkout_completed", async (event) => {
const {
order,
lineItems,
transactions,
currencyCode,
discountApplications,
totalPrice,
shippingLine,
totalTax,
delivery,
} = event.data.checkout;

const discountCodes = discountApplications.filter(
({ type }) => type === "DISCOUNT_CODE",
);

const transactionId = order?.id ?? Math.random().toString(36).substring(7);
const payment = transactions[0];
const paymentMethod = payment?.paymentMethod?.name ?? payment?.gateway ?? "";

const shipping = delivery?.selectedDeliveryOptions[0];
const shippingMethod =
shipping?.title ?? shipping?.description ?? shipping?.type ?? "";

const transactionPayload = {
ta: "Purchase",
tid: transactionId,
tr: totalPrice?.amount ?? 0,
tt: totalTax.amount,
tc: currencyCode ?? "",
tcc: discountCodes.map(({ title }) => title).join(", "),
icn: lineItems.reduce((acc, item) => acc + item.quantity, 0),
ts: shippingLine?.price.amount,
pm: paymentMethod,
sm: shippingMethod,
};

await waitFor(() => typeof window.abtasty !== "undefined");

const itemPayloads = lineItems.map((lineItem) => ({
tid: transactionId,
in: lineItem.variant?.title || lineItem.variant?.product.title,
ip:
(lineItem?.finalLinePrice?.amount ?? lineItem.variant?.price?.amount) /
lineItem.quantity,
iq: lineItem.quantity,
ic: lineItem.variant?.sku || lineItem.variant?.product.id,
iv: lineItem.variant?.product.type ?? undefined,
}));

window.abtasty.send("transaction", transactionPayload);
itemPayloads.forEach((itemPayload) =>
window.abtasty.send("item", itemPayload),
);

if (FEATURE_EXP_ENVIRONMENT_ID && visitorId) {
const common = {
ds: "app",
cid: FEATURE_EXP_ENVIRONMENT_ID,
vid: visitorId,
};

window.abtasty.send("transaction", {
...transactionPayload,
...common,
});

itemPayloads.forEach((itemPayload) =>
window.abtasty.send("item", { ...itemPayload, ...common }),
);
}
});

const waitFor = (condition) => {
const TIMEOUT = 5000;

return new Promise((resolve, reject) => {
const startTime = Date.now();

function checkCondition() {
// Check if the condition is met
if (condition()) {
resolve();
return;
}

// Check if timeout has been reached
if (Date.now() - startTime > TIMEOUT) {
reject(new Error("Timeout waiting for condition"));
return;
}

// If not met, try again after a short delay
setTimeout(checkCondition, 100);
}

// Start checking
checkCondition();
});
};

if (FEATURE_EXP_ENVIRONMENT_ID && !visitorId) {
console.log(
"ABTASTY: No visitor id found. Make sure you have the FLAGSHIP_VISITOR_ID cookie",
);
}

```

**Injecting the AB Tasty Tag on Other Pages:**

To ensure comprehensive tracking across your store, it's essential to inject the AB Tasty tag on pages outside of the checkout process. Here's how you can do it:​

1. **Using the `theme.liquid` File for Global Scripts:**
   * From your Shopify admin, navigate to `Online Store > Themes > Actions > Edit Code`.
   * Open the `theme.liquid` file located in the `Layout` folder.
   * Insert your script tag just before the closing `</head>` tag for scripts that need to load early, or before the closing `</body>` tag for scripts that can load later.\
     \
     For example:​

     `<!-- For scripts in the Assets folder -->`\
     `<script src="{{ 'your-script.js' | asset_url }}" defer></script>`

     `<!-- For external scripts -->`\
     `<script src="https://example.com/your-script.js" defer></script>`


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.abtasty.com/account/tag-integration/implement-ab-tasty-tag/ab-tasty-integration-with-shopify/how-to-set-up-shopify-custom-pixel-app.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
