> For the complete documentation index, see [llms.txt](https://docs.getpurpledot.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.getpurpledot.com/docs/shopify-stores/integrate-purple-dot-with-your-storefront/integrate-into-shopify-themes-built-with-liquid.md).

# Integrate into Shopify Themes built with Liquid

#### [1. Enable Purple Dot in your theme](#id-1.-enable-purple-dot-in-your-theme)

Having completed [Install our app](/docs/shopify-stores/install-our-app.md)

1. Navigate to a theme where you wish to test Purple Dot
2. Click "Edit theme", then "App embeds" on the sidebar of the theme code editor
3. Search for "Purple Dot"
4. Provide the "Purple Dot API Key" and "Purple Dot Shared Secret" values that you can find at the bottom of the Integrations page in our [Merchant Portal](https://www.purpledotprice.com/merchant-portal)
5. Enable the embed and save the theme

#### [2. Add the Shopper Portal](#id-6.-add-the-shopper-portal)

The shopper portal allows your customers to see their pre-order history and cancel pre-orders before they are fulfilled.&#x20;

We recommend hosting the shopper portal iframe on a new page - e.g. `/pages/manage-pre-orders` - that is linked from your support pages, similar to how a returns portal would be.

The title of the page should be **Manage Pre-orders.**

The following snippet should be placed on a Shopify page by editing the page's HTML:

```
<purple-dot-self-service />
```

#### [**3. Configure Separate Cart (optional)**](#id-3.-configure-separate-cart-optional)

If your preferred checkout method is to use a separate cart, there is some additional configuration required to place the separate cart icon and enable the variant selectors on liquid theme:

1. **Configure the cart placement**

```js
window.PurpleDotConfig = {
  ...
  cart: {
    // Icon styles
    fill: '#000000',
    strokeWidth: '1.5px',
    matchFill: '.icon--cart',
    width: '22px',
    height: '22px',
    // Function to place the cart element onto the page
    placeElement: (cartElement, cartLink) => {
      const cartLinkContainer = cartLink.parentElement;
      const pdCartContainer = cartLinkContainer.cloneNode();
      // Adjust these next two lines to your DOM, if necessary
      pdCartContainer.appendChild(cartElement);
      cartLinkContainer.insertAdjacentElement('beforebegin', pdCartContainer);
      // Returns the container element
      return pdCartContainer;
    },
  },
};
```

{% hint style="info" %}
**Unexpected DOM structure?**

Sometimes, you may find empty elements with padding/margin etc., if the theme you're working on is different to the one assumed in our previous example. If this is the case, you can set up a mutation observer on an ancestor of the cart icon like so:
{% endhint %}

```js
// Function to place the cart element onto the page
placeElement: (cartElement, cartLink) => {
  const cartLinkContainer = cartLink.parentElement;
  const pdCartContainer = cartLinkContainer.cloneNode();
  const nav = document.querySelector('nav.Header__SecondaryNav');
  // Define observer callback
  const observer = new MutationObserver(() => {
    const iframe = document.querySelector('iframe.purple-dot-frame');
    if (iframe.style.display === "none") {
      pdCartContainer.style.display = "none";
    } else {
      // May need to adjust this line to suit your theme
      pdCartContainer.style.display = "inline-block";
    }
  });
  // Adjust these next two lines to your DOM, if necessary
  pdCartContainer.appendChild(cartElement);
  cartLinkContainer.insertAdjacentElement('beforebegin', pdCartContainer);
  // Set up observer:
  // IMPORTANT: 'attributes' must be true, as iframe.style.display will change
  observer.observe(nav, { attributes: true, childList: true, subtree: true });
  // Returns the container element
  return pdCartContainer;
},
```

2. **Configure variant selectors on a PDP**

Sometimes, a PDP will have variant selectors that show the variant as sold out, even though the variant is available for preorder. In this case, we can target these elements, and remove a 'disabled' class (or similar) from them in order to 'enable' them.

There are two ways of selecting elements (depending on whether or not they are inside an ATC form), but you must always provide a class to remove.

```js
window.PurpleDotConfig = {
  ...
  pdp: {
    variantSelector: {
      // CSS selector to be queried for inside the ATC form
      selector: '.some-selector',
      // Find variant selector elements that are outside the ATC form
      find: () => document.querySelectorAll('.another-selector'),
      // Class to remove to enable the variant
      disabledClass: 'disabled',
    },
  },
};
```

<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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.getpurpledot.com/docs/shopify-stores/integrate-purple-dot-with-your-storefront/integrate-into-shopify-themes-built-with-liquid.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.
