Standalone modal iframe integration

Last updated: June 16, 2026

Integrate Customily into any ecommerce platform using a modal iframe. In this approach, the entire personalization experience, including the live preview and option set form, runs inside a single iframe hosted by Customily. This is the recommended integration method for most custom ecommerce platforms.


How it works

This integration consists of three steps:

  1. The shopper clicks a Customize button on your product page.

  2. A modal opens displaying the full Customily personalization experience inside an iframe.

  3. When the shopper clicks Add to Cart, the personalization data is sent back to your platform.

Step 1: Product Page with a Customize Button

The merchant's product page includes a Customize button. This is a regular HTML button — Customily does not inject anything into the page automatically.

customize now button.png

Step 2: Shopper Clicks "Customize" — Modal Opens with Customily Iframe

When the shopper clicks the button, a modal opens containing the full Customily personalization experience inside an iframe. The iframe renders both the live product preview (canvas) and the option set form (text inputs, dropdowns, image uploads, etc.) — no additional scripts or setup required on the host page. The shopper interacts with the Customily UI — typing text, choosing fonts, uploading images, etc. The live preview updates in real time.

iframe modal.png

Step 3: Shopper Clicks "Add to Cart" — Personalization Data Sent to Parent Page

When the shopper clicks "Add to Cart", Customily sends the personalization details to the parent page via postMessage, including a CDN-hosted thumbnail of the personalized product. The parent page can store this data along with the rest of the order details in their platform's cart.

add to cart.png

Implementation

Now that you've seen how the integration works, the next step is to implement it on your storefront. This involves creating a personalization link for each product, capturing the personalization data when the shopper adds the item to the cart, and generating the production files after checkout.

Create the Customily Personalization Link

The Customily personalization link is used as the src of the iframe. It has the following format:

https://preview-2.customily.com/productViewer?template={TEMPLATE_ID}&set={OPTION_SET_ID}&shop={STORE_URL}

Parameter

Description

template

The template GUID from Customily

set

The option set GUID from Customily

shop

Your store identifier (e.g. standalone.customily.com)

For example:

https://preview-2.customily.com/productViewer?template=0313370a-e3d1-4b88-8640-f1027a78235d&set=53b7ddcc-880d-4303-a495-0338e1388ca2&shop=standalone.customily.com

You can create this URL in the Customily dashboard as shown here

Pro tip

Add a "Customily Link" field to your admin product details page. This is the way to connect a product from your e-commerce platform to a personalization link on Customily — non-technical team members can simply copy-paste the link from the Customily dashboard without touching code.

Capture Personalization Data

When the shopper clicks "Add to Cart" inside the iframe, Customily sends a postMessage to the parent window with the personalization payload. Listen for this message and use the data to add the item to your platform's cart:

window.addEventListener('message', (event) => {
const data = event.data;

// Check that this is a Customily add-to-cart event
if (data?.action !== 'add-to-cart') return;

// data contains:
// - personalizationGUID: unique ID for this personalization
// - previewUrl: CDN URL of the personalized preview image
// - exportedFiles: array of production file URLs
// - options: array of { name, value, type } objects — the options selected by the shopper
// - quantity: number of items

console.log('Personalization GUID:', data.personalizationGUID);
console.log('Preview image:', data.previewUrl);
console.log('Options:', data.options);

// Add the item to your platform's cart. You'll need to pass at least the personalizationGUID
addItemToYourCart({
productId: 'your-platform-product-id',
personalizationId: data.personalizationGUID,
});

// Close the modal
document.getElementById('customily-modal').style.display = 'none';});

Note

You can add more attributes to your cart item such as exportedFilesoptions, etc. This may save you an API call later. But make sure you hide them from the shopper as it may be confusing for them to see all that info in their cart.

Pro tip 

Use the previewUrl as the cart item thumbnail. This helps shoppers confirm that the personalized product they created is the one they added to the cart.

Generate Production Files After Checkout

The URLs in the exportedFiles array from the postMessage payload are placeholders — the actual production file won't be available at those URLs until you explicitly trigger generation. If you try to open the URL before calling the generate endpoint, you'll see this:

file not found.png

This is by design: since Customily charges per production file generated and there's no way to know whether a shopper will actually complete checkout, production files are only created on demand to avoid unnecessary costs for items that are added to the cart but never purchased.

You should call this endpoint after the shopper has checked out (i.e., after payment is confirmed), not when the item is added to the cart.

Call the /standalone/item/generate endpoint with the production file URL and a JWT token for authentication:

POST https://sh.customily.com/api/standalone/item/generate
Authorization: Bearer <JWT_TOKEN>

Request body:

{
    "url": "https://cdn.customily.com/ExportFile/customilyUser/330afd39-6ef1-4b9c-8893-6ef2033d4791.png",
    "shop": "standalone.customily.com"
}

Field

Type

Required

Description

url

string

Yes

The production file URL from exportedFiles[].url

shop

string

Yes

Your store identifier

order

string

No

Optional order reference from your platform

Response: 200 OK — "File generated successfully"

Important

The url must be hosted on a *.customily.com domain.

See Authentication for how to obtain the JWT token.


Complete example

<!DOCTYPE html><html lang="en"><head>
    <title>Product Page</title>
    <style>
        .modal {
            display: none;
            position: fixed;
            top: 0; left: 0;
            width: 100%; height: 100%;
            background: rgba(0, 0, 0, 0.7);
            z-index: 9999;
            justify-content: center;
            align-items: center;
        }
        .modal.active { display: flex; }
        .modal-content {
            position: relative;
            background: #fff;
            border-radius: 8px;
            width: 90%;
            max-width: 1200px;
            height: 85vh;
            overflow: hidden;
        }
        #customily-iframe {
            width: 100%;
            height: 100%;
            border: none;
        }
        .modal-close {
            position: absolute;
            top: 10px;
            right: 10px;
            z-index: 10;
            background: #fff;
            border: 1px solid #ccc;
            border-radius: 50%;
            width: 32px;
            height: 32px;
            cursor: pointer;
            font-size: 16px;
        }
        #customize-btn {
            background-color: #4CAF50;
            color: #fff;
            border: none;
            padding: 12px 24px;
            font-size: 16px;
            cursor: pointer;
            border-radius: 4px;
        }
        #customize-btn:hover {
            background-color: #45a049;
        }
    </style></head><body>

    <!-- Product Page -->
    <h1>Personalized Heart Map Canvas</h1>
    <p>Celebrate a special place with a custom heart-shaped map canvas. Choose your location, add your names and a meaningful date — the perfect gift for anniversaries, weddings, or any occasion worth remembering.</p>
    <img src="https://raw.githubusercontent.com/Customily/Documentation/main/standalone/images/product-image.png" id="product-image" style="display: block; margin-bottom: 16px;" />
    <button id="customize-btn">Customize</button>

    <!-- Customily Modal -->
    <div id="customily-modal" class="modal">
        <div class="modal-content">
            <button class="modal-close" id="modal-close">X</button>
            <iframe id="customily-iframe"></iframe>
        </div>
    </div>

    <script>
        // --- Configuration ---
        // Paste the Customily personalization link for this product
        const CUSTOMILY_LINK = 'https://preview-2.customily.com/productViewer?template=0313370a-e3d1-4b88-8640-f1027a78235d&set=53b7ddcc-880d-4303-a495-0338e1388ca2&shop=standalone.customily.com';

        // Open modal on click
        document.getElementById('customize-btn').addEventListener('click', () => {
            document.getElementById('customily-iframe').src = CUSTOMILY_LINK;
            document.getElementById('customily-modal').classList.add('active');
        });

        // Close modal
        document.getElementById('modal-close').addEventListener('click', () => {
            document.getElementById('customily-modal').classList.remove('active');
            document.getElementById('customily-iframe').src = '';
        });

        // Listen for personalization data from the Customily iframe
        window.addEventListener('message', (event) => {
            const data = event.data;
            if (data?.action !== 'add-to-cart') return;

            console.log('Personalization complete:', data);

            // data.previewUrl          → use as the cart thumbnail image
            // data.personalizationGUID → store to retrieve details later
            // data.options             → array of options selected by the shopper
            // data.quantity            → number of items

            // Close modal
            document.getElementById('customily-modal').classList.remove('active');
            document.getElementById('customily-iframe').src = '';

            // Add to your platform's cart here...
        });
    </script>

</body></html>

Accessing Personalization Data After Checkout

When fulfilling an order, you'll need access to the shopper's personalization details, including their selected options, preview image, and production files.

  • If you stored the full postMessage payload (including optionspreviewUrl, and exportedFiles), when the item was added to the cart, you'll already have everything you need and won't need to make additional API calls.

  • If you only stored the personalizationGUID, you can retrieve the complete personalization details later using the Customily API.

    See Retrieving Personalization Details & Production Files for details.

Advanced Integration Options

You may also want to explore these advanced integration options:

  • Using your own "Add to Cart" button: If you prefer to handle the add-to-cart flow yourself instead of using Customily's built-in button see Custom Add to Cart Integration for details.

  • Embedding just the option set form: If you want to integrate the live preview directly into your product page and use the iframe only for the option set form, see Options-Only Mode Integration for details.

  • Customizing the iframe appearance: If you want to match the look and feel of the Customily iframe to your store's branding, see Change Options Styles with CSS for how to change colors, fonts, layout, and button styles.