Custom Add to Cart Integration
Last updated: July 30, 2026
This guide explains how to use your own Add to Cart button instead of Customily's built-in one. This is useful when you need full control over the checkout flow or want to integrate the add-to-cart action into your platform's native UI.
How It Works
When using Customily's built-in Add to Cart button, the iframe automatically performs three operations and sends the result to the parent page via postMessage.
If you want to use your own button, you'll need to hide Customily's button and call these operations yourself using the Customily engraver window object.
The three operations are:
Generate the production file request — reserves a URL for the production-ready file.
Generate a preview thumbnail (optional) — uploads a preview image and returns a CDN URL.
Create a cart record (optional) — saves the personalization data on Customily's server so you can view the cart details from Customily's Orders dashboard.
Keep in mind
Only generating the production file request is required. Creating a preview thumbnail and cart record is optional, but recommended for a better shopper experience and easier order fulfillment.
Implementation
Generate the Production File Request
Call generatePFRPostOrder() on the engraver to create the production file request:
const exportedFiles = await window.engraver.generatePFRPostOrder('');
// Store the url(s) — you'll need them to call item/generate after checkout
const productionFileUrls = exportedFiles.map(f => f.url);Returns:Â an array of production file URLs (one per template side):
[
{ "url": "https://cdn.customily.com/ExportFile/..." },
{ "url": "https://cdn.customily.com/ExportFile/..." } // if the template has multiple sides
]Note
The url is a placeholder — the actual file won't be available until you call the item/generate endpoint after checkout.
Generate the Preview Thumbnail (Optional)
Call generatePreviewImage() to upload a preview and get a CDN URL:
const preview = await window.engraver.generatePreviewImage({
shop: 'yourstandalonestore.com'
});Returns:
{
"filename": "c611faa2-...",
"previewUrl": "https://cdn.customily.com/shopify/assetFiles/previews/yourstandalonestore.com/c611faa2-....jpeg",
"thumbnailUrl": "https://cdn.customily.com/..."
}previewUrl— a 1000 × 1000 high-quality image, ideal for sending to shoppers via email so they can see how their personalization looks.thumbnailUrl— a smaller image, better suited for displaying the item in the shopping cart.
Create the Cart Record (Optional)
Creating a cart record stores the personalization data on Customily's server so you can view it later from the Orders dashboard (đź“„ Viewing Orders in Customily)
Post the personalization data to Customily's cart endpoint:
const response = await fetch('https://sh.customily.com/api/standalone/cart?shop=yourstandalonestore.com', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
productId: window.engraver.currentProduct.id,
quantity: 1,
orderId: '10001', // your platform's order ID (optional)
sessionId: window.engraver.getSessionId(),
previewUrl: preview.previewUrl,
exportedFiles: exportedFiles,
options: [
{ name: "Name", value: "John", type: "Text Input" },
{ name: "Date", value: "June 15, 2025", type: "Text Input" },
{ name: "Font", value: "Script", type: "Dropdown" },
{ name: "Photo", value: window.engraver.getElementsUrls('image', 1)[0], type: "Image Upload" }
]
})
});
const cartItem = await response.json();
// cartItem.id is the personalizationGUIDPopulate the
optionsarray with the shopper's selections. Each entry should contain aname,value, andtype.Providing an
orderIdis optional. If supplied, you can later retrieve every personalization item associated with that order.
Complete Example
The following example combines all three operations into a complete custom Add to Cart implementation.
async function customilyAddToCart(shop, quantity, options, orderId) {
// 1. Generate production file request
const exportedFiles = await window.engraver.generatePFRPostOrder('');
// 2. Generate preview thumbnail
const preview = await window.engraver.generatePreviewImage({ shop });
// 3. Wait for any pending file uploads to complete.
// When a shopper uploads an image or vector, Customily immediately starts uploading
// the file in the background. For large files, it's possible the shopper clicks
// "Add to Cart" before the upload finishes. Calling waitFilesUpload() ensures all
// pending uploads are complete before proceeding, so no files are missing from the order.
await window.engraver.waitFilesUpload();
// 4. Create cart record
const response = await fetch(`https://sh.customily.com/api/standalone/cart?shop=${shop}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
productId: window.engraver.currentProduct.id,
quantity: quantity,
orderId: orderId,
sessionId: window.engraver.getSessionId(),
previewUrl: preview.previewUrl,
exportedFiles: exportedFiles,
options: options
})
});
const cartItem = await response.json();
return {
personalizationGUID: cartItem.id,
previewUrl: preview.previewUrl,
exportedFiles: exportedFiles
};
}
// Usage
document.getElementById('my-add-to-cart-btn').addEventListener('click', async () => {
// Collect the shopper's selections from your form
const options = [
{ name: "Name", value: document.getElementById('name-input').value, type: "Text Input" },
{ name: "Date", value: document.getElementById('date-input').value, type: "Text Input" },
{ name: "Font", value: document.getElementById('font-select').value, type: "Dropdown" },
{ name: "Photo", value: window.engraver.getElementsUrls('image', 1)[0], type: "Image Upload" }
];
const result = await customilyAddToCart('yourstandalonestore.com', 1, options, '10001');
console.log('Added to cart:', result.personalizationGUID);
console.log('Preview:', result.previewUrl);
// Add to your platform's cart here...
});Accessing Personalization Data After Checkout
After the order is placed, you'll need access to the shopper's personalization details and production file URLs during fulfillment.
If you stored the complete personalization payload when the item was added to the cart, you'll already have everything you need.
If you only stored the personalizationGUID or orderId, see Retrieving Personalization Details & Production Files to learn how to retrieve the personalization data later.
Relevant JavaScript Methods
The following window.engraver methods and properties are relevant to the add-to-cart flow:
Method | Returns | Description |
|---|---|---|
|
| Generates the production file request (one entry per template side) |
|
| Uploads preview image, returns CDN URLs |
|
| Waits for pending image/vector uploads to complete |
|
| Gets Customily-hosted URLs for shopper uploaded images ( |
|
| The current template ID |