Integrate into Shopify Themes built with Liquid
This guide will walk you through Purple Dot's Platform integration into any Shopify store built with Liquid Templates. If you are using our Shopify App, please seeInstalling our Shopify App instead. See Purple Dot Overview for the comparison of our Shopify App vs. Platform integrations.
This will allow you to turn the Purple Dot integration on and off without any code changes.
Clone your currently live theme to make a new preview theme
In
config/settings_schema.json
add the following{ "name": "Purple Dot", "settings": [ { "type": "checkbox", "id": "use_purpledot", "label": "Turn on Purple Dot integration" } ] }
In
config/settings_data.json
add the following"use_purpledot": true,
In the preview theme create a new snippet and name it
purple-dot.liquid
In
layout/theme.liquid
find the closing</head>
tag and place the following code just before it{% if settings.use_purpledot %} {% render 'purple-dot' %} {% endif %}
If your theme still uses
checkout.liquid
find the closing</head>
tag and place the following code just before it{% if settings.use_purpledot %} {% render 'purple-dot' %} {% endif %} <script type="text/javascript"> window.PurpleDotConfig.checkoutLineItems = [ {% for line_item in checkout.line_items %} { preorder_state: '{{ line_item.variant.metafields['purple-dot'].preorder_state }}' }, {% endfor %} ]; </script> {% comment %} Purple Dot has support for Checkout Extensibility, please reach out to support@getpurpledot.com after making the switch to update your Purple Dot integration. {% endcomment %}
We will use purple-dot.liquid
as the place where all other Purple Dot related code lives. It is being rendered from the header as it is required to run on every single page in your Shopify store for Purple Dot to function correctly.
Paste the following snippet into purple-dot.liquid
<script>
window.PurpleDotConfig = {
shopifyCart: {{ cart | json }},
shopifyCartString: {{ cart | json | json }},
shopifyCartSignature: {{ cart | json | hmac_sha256: 'SHARED_SECRET' | json }},
prefillEmail: '{{ customer.email }}',
prefillShippingAddress: {{ customer.default_address | json }},
};
</script>
<script src="https://www.purpledotprice.com/api/v1/init.js?apiKey=PUBLIC_API_KEY"></script>
Replace SHARED_SECRET
and PUBLIC_API_KEY
with the public API key and shared secret of your Purple Dot store, which can be found at the bottom of the Integration settings page in the Merchant Portal.
Purple Dot offers 3 different methods for shoppers to buy pre-order products
Combined Cart (the default)
Separate Cart
Express
If you want to use a non-default checkout method, please create a new script
tag before init.js
that will use window.PurpleDotConfig
to specify this:
To use Separate Cart
<script> window.PurpleDotConfig = { checkoutMethod: 'SEPARATE_CART', }; </script> <script src="https://www.purpledotprice.com/api/v1/init.js?apiKey={{settings.purpledot_api_key}}"></script>
To use Express
<script> window.PurpleDotConfig = { checkoutMethod: 'EXPRESS', }; </script> <script src="https://www.purpledotprice.com/api/v1/init.js?apiKey={{settings.purpledot_api_key}}"></script>
If you do not know which checkout method you would like to integrate, contact us for more information.
Each checkout method may require some specifics to work with your store's theme.
No extra configuration is necessary
No extra configuration is necessary
Configure the cart placement
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;
},
},
};
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:
// 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;
},
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.
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',
},
},
};
Modify existing PDP/PLP page behaviour
We support a number of customisations to Product Detail Pages (PDP) and Product Listing Pages (PLP) that may be required.
Out of the box, when the shopper selects a variant that is on pre-order through Purple Dot, we will hide the following on every PDP because we do not support them in our checkouts:
Shopify payment buttons
Klarna messaging
Klaviyo notify me buttons
as well as others
If you would like to hide some elements on PLPs or PDPs, simply add a pdp.hide
or plp.hide
attribute with an array of selectors to instruct Purple Dot to hide these if the selected variant will be on pre-order
If you would like to show some elements on PDPs, create them in your theme with display:none
and then add a pdp.show
attribute with an array of selectors to instruct Purple Dot to display these if the selected variant will be on pre-order.
window.PurpleDotConfig = {
...
pdp: {
hide: ['<SELECTOR>'],
show: ['<SELECTOR>'],
},
plp: {
hide: ['<SELECTOR>'],
},
};
To modify the quick view/add components on a PLP for any product that is on pre-order
window.PurpleDotConfig = {
...
plp: {
quickAdd: {
// Optional selector that targets the title element within a collection item
title: '',
// Optional string that will be used in place of the existing text
newTitle: '',
// Optional selector for a size selector element which Purple Dot will
// transform to link through to the PDP
sizeSelector: '',
// Class used to disable the size selector if the variant is sold out.
// Purple Dot will remove this if the variant is available for pre-order
disabledClass: '',
// Useful if you need to remove some attributes from some elements
removeAttributes: [{
selector: '',
attributes: [''],
}],
},
},
};
Automatically apply discount
The provided discount will be applied to every checkout involving a line item on preorder.
window.PurpleDotConfig = {
...,
discountCode: <discount code>,
};
Enable pre-order stock notification
Purple Dot will email the subscribed shoppers when the product is back on pre-order. Please note: this feature is only supported by EXPRESS
and SEPARATE_CART
checkout methods.
window.PurpleDotConfig = {
...
enableNotifyMe: true,
};
Tracking pre-orders
The Purple Dot SDK can automatically forward events to various product analytics, ad and order tracking platforms. You can activate these integrations from the Integration settings page in the Merchant Portal. See Pre-order tracking for more information about these integrations.
Restrict Purple Dot to some markets
Some merchants handle multiple markets with one Shopify store, with checkout handled by another service like Global-E. Purple Dot does not currently support integrating with other checkout providers and so in these cases you can hide Purple Dot in markets you do not wish to offer pre-orders in.
With Global-E
window.PurpleDotConfig = {
...,
enableWaitlists: () => {
// Show Purple Dot to UK shoppers only
return new Promise((resolve, reject) => {
const interval = setInterval(() => {
try {
let waitlistsEnabled;
if (window.GLBE_PARAMS && window.GLBE_PARAMS.countryCode) {
waitlistsEnabled = window.GLBE_PARAMS.countryCode === 'GB';
} else if (window.GlobalE && window.GlobalE.Country) {
waitlistsEnabled = window.GlobalE.Country === 'GB';
}
if (waitlistsEnabled !== undefined) {
clearInterval(interval);
resolve(waitlistsEnabled);
}
} catch (err) {
clearInterval(interval);
reject(err);
}
}, 100);
setTimeout(reject, 10000);
});
},
};
With Shopify
window.PurpleDotConfig = {
...,
enableWaitlists: () => {
return new Promise((resolve, reject) => {
fetch('/browsing_context_suggestions.json')
.then(response => response.json())
.then(data => {
if (data?.detected_values?.country?.handle) {
resolve(data.detected_values.country.handle === 'US');
} else {
resolve(true);
}
})
.catch(error => {
reject(error);
});
});
},
};
Localise the Pre-order button
Currently we support English, Spanish, German and Dutch.
The correct locale will be automatically detected in most cases but if you wish to override it you can set it yourself.
window.PurpleDotConfig = {
...,
locale: 'es-ES',
};
You can also provide your own copy if you like.
window.PurpleDotConfig = {
...,
translations: {
'es-ES': {
addToCart: 'Añadir a la cesta',
preorderCTA: 'Resérvalo',
}
}
};
Styling
You may find that you need to style some components on a page differently when a waitlisted variant is selected. In this case, you can add the styles
param to your PurpleDotConfig.pdp
.
A good example of this would be when our 'Waitlist powered by' content is being added incorrectly to the PDP. Our code adds the waitlist content underneath the 'Pre-order' button (in the DOM), but if the button is in a flex container with flex-direction: row
, the waitlist info will be added to the side of the button.
We can solve this using CSS, which will only be applied if the selected variant is on pre-order, and will be removed when the selected variant is not on preorder. We can also specify multiple style rules, if needed, and change values based on screen size, e.g. mobile screens.
window.PurpleDotConfig = {
...
// 'styles' must be inside 'pdp', not 'plp'
pdp: {
styles: {
preorder: [
{
selector: '.product__buy-buttons',
style: 'flex-wrap: wrap'
},
{
media: 'only screen and (max-width: 600px)',
selector: '.product__add',
style: 'width: 100% !important'
},
{
media: 'only screen and (min-width: 600px)',
selector: '.product__add',
style: 'width: 50% !important'
},
]
}
}
};
The self-service portal allows your customers to see their pre-order history and cancel pre-orders before they are fulfilled. We recommend hosting the self-service 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 can be placed on a Shopify page by editing the page's HTML:
<purple-dot-self-service />
Please refer to Test the Platform Integration.
Publish the preview theme
Set up Waitlists in your Purple Dot Merchant Portal
Last updated