> For the complete documentation index, see [llms.txt](https://help.mimeeq.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.mimeeq.com/developer-guides/cart-validation-script.md).

# Cart Validation Script

Stop Shopify customers seeing blank prices or images for custom products in the cart. Learn what the script does, how it works and how to adapt it.

This script solves a timing issue in Shopify where custom product images and prices don't load immediately when items are added to the cart. Without this solution, customers might see incomplete product information (missing images, $0 prices or blank titles), which could lead to confusion or checkout errors.

{% hint style="info" %}
This code snippet is designed for the Dawn theme but can be adapted to any Shopify theme by adjusting the cart container selector.
{% endhint %}

***

## What it does

* Detects when custom products (marked with the `_mmqProduct` property) are added to the cart
* Checks if critical product data is missing (price, image, title, product ID or URL)
* Displays a user-friendly overlay with a loading message to prevent interaction with incomplete data
* Continuously polls Shopify's cart API every 6 seconds until all product information is fully loaded
* Automatically refreshes the page once complete data is available

***

## Problem it solves

Shopify's backend processing for custom products can be delayed, causing a gap between when a product is added to the cart and when its full details (especially images and pricing) become available. This script bridges that gap by:

* Preventing customers from seeing or interacting with incomplete product data
* Ensuring accurate pricing and product information before checkout
* Providing clear feedback that the system is working ("We are creating your custom product...")
* Automatically resolving the issue without requiring manual page refreshes

***

## How it works

When products are added to the Shopify cart, they receive a `_mmqProduct` property. The script checks for this property to determine if it should run:

* First, it verifies whether the cart contains products with the `_mmqProduct` property.
* If found, it checks whether these products are missing critical data — specifically price or image information (configurable via variables at the start of the script).
* When missing data is detected, the script displays an overlay on the cart page to prevent user interaction.
* It then waits for Shopify to finish processing the product data, checking at customisable intervals until the information is complete.

This ensures customers don't proceed with incomplete product information in their cart.

```mermaid
flowchart LR
    A[Cart page loads] --> B{Mimeeq product in cart?}
    B -- No --> X[Script exits]
    B -- Yes --> C{Product data missing?}
    C -- No --> X
    C -- Yes --> D[Show overlay]
    D --> E[Check cart data every 6 seconds]
    E --> F[Refresh page when data is complete]
```

### Configurable variables

You can change these variables at the start of the script:

<table><thead><tr><th width="60">#</th><th>Variable</th><th>Default</th><th>What it controls</th></tr></thead><tbody><tr><td>1</td><td><strong>checkPrice</strong></td><td>true</td><td>Treat a missing or zero price as missing data.</td></tr><tr><td>2</td><td><strong>checkImage</strong></td><td>true</td><td>Treat a missing image as missing data.</td></tr><tr><td>3</td><td><strong>waitTime</strong></td><td>6000</td><td>How often the script checks the cart again, in milliseconds.</td></tr></tbody></table>

{% hint style="success" %}
To preview the overlay without waiting for a real cart, open the browser console on the cart page and run `window.mimeeqDebugOverlay()`. Run `window.mimeeqHideOverlay()` to remove it.
{% endhint %}

***

## Code

```javascript
{% if template.name contains 'cart' %}
<script>
// Mimeeq Script for Cart Checking Variants Start
console.group('[Mimeeq Cart Debug]');
console.log('🟦 Script loaded and running');
console.log('💡 To test overlay, run: window.mimeeqDebugOverlay()');

const checkPrice = true;
const checkImage = true;
const waitTime = 6000;

const items = {{ cart.items | json }};
console.log('📦 Cart items:', items);

const isMmqProduct = items.some(i => i.properties && i.properties._mmqProduct);
const isMissingData = items.some(i => {
  const missingPrice = checkPrice && (!i.price || i.price === 0);
  const missingImage = checkImage && !i.image;
  const missingTitle = !i.product_title;
  const missingProductId = !i.product_id;
  const missingUrl = !i.url;
  const isMissing = missingPrice || missingImage || missingTitle || missingProductId || missingUrl;
  if (isMissing) console.log('🔍 Item missing data:', i);
  return isMissing;
});

console.log('🧩 isMmqProduct:', isMmqProduct);
console.log('⚠️ isMissingData:', isMissingData);

function showMimeeqOverlay(debugMode = false) {
  const cartContainer = document.querySelector('.cartitems--list');
  if (!cartContainer) {
    console.warn('⚠️ No .cartitems--list element found');
    return;
  }

  // --- Create overlay ---
  const overlay = document.createElement('div');
  overlay.id = 'mimeeq-overlay';
  Object.assign(overlay.style, {
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%',
    background: 'rgba(255, 255, 255, 0.65)', // soft white-gray blur
    backdropFilter: 'blur(10px)',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: '9999',
    pointerEvents: 'all',
    transition: 'opacity 0.3s ease',
    opacity: '0'
  });

  // --- Spinner (left of text) ---
  const spinner = document.createElement('div');
  Object.assign(spinner.style, {
    width: '22px',
    height: '22px',
    border: '3px solid rgba(0,0,0,0.1)',
    borderTop: '3px solid #ac7349',
    borderRadius: '50%',
    animation: 'mimeeq-spin 1s linear infinite',
    flexShrink: '0',
    marginRight: '12px'
  });

  // Spinner animation keyframes (add once)
  if (!document.getElementById('mimeeq-spinner-style')) {
    const styleTag = document.createElement('style');
    styleTag.id = 'mimeeq-spinner-style';
    styleTag.textContent = `
      @keyframes mimeeq-spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
      }
    `;
    document.head.appendChild(styleTag);
  }

  // --- Message box ---
  const messageBox = document.createElement('div');
  Object.assign(messageBox.style, {
    background: '#fff',
    borderRadius: '8px',
    padding: '20px 28px',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    boxShadow: '0 4px 16px rgba(0,0,0,0.12)',
    fontFamily: 'system-ui, sans-serif',
    fontSize: '16px',
    color: '#000',
    whiteSpace: 'nowrap',
    maxWidth: '600px'
  });

  // --- Message text ---
  const messageText = document.createElement('div');
  messageText.innerText =  'We are creating your custom product. The page will refresh once it’s ready.';

  messageBox.appendChild(spinner);
  messageBox.appendChild(messageText);
  overlay.appendChild(messageBox);

  // --- Attach to container ---
  cartContainer.style.position = 'relative';
  cartContainer.appendChild(overlay);

  // --- Fade in effect ---
  requestAnimationFrame(() => { overlay.style.opacity = '1'; });

  console.log(debugMode ? '🐞 Debug overlay shown' : '📍 Overlay shown');
}

function hideMimeeqOverlay() {
  const overlay = document.getElementById('mimeeq-overlay');
  if (!overlay) return;
  overlay.style.opacity = '0';
  setTimeout(() => overlay.remove(), 300);
}

window.mimeeqDebugOverlay = () => { showMimeeqOverlay(true); };
window.mimeeqHideOverlay = () => { hideMimeeqOverlay(); };

if (isMmqProduct && isMissingData) {
  console.log('🚀 Conditions met — starting cart data check loop');
  let finishCheck = false;
  showMimeeqOverlay(false);

  const getCartData = async () => {
    console.log('🔄 Checking cart data...');
    try {
      const response = await fetch('/cart.js');
      const { items } = await response.json();
      const missingData = items.some(i => {
        const missingPrice = checkPrice && (!i.price || i.price === 0);
        const missingImage = checkImage && !i.image;
        const missingTitle = !i.product_title;
        const missingProductId = !i.product_id;
        const missingUrl = !i.url;
        return missingPrice || missingImage || missingTitle || missingProductId || missingUrl;
      });
      if (!missingData) {
        finishCheck = true;
        console.log('✅ All data loaded — refreshing page...');
        window.location.reload();
      }
    } catch (error) {
      console.warn('❌ Cart refresh check failed:', error);
    }
  };

  const interval = setInterval(async () => {
    if (finishCheck) {
      clearInterval(interval);
      console.log('🛑 Interval cleared');
    } else {
      await getCartData();
    }
  }, waitTime);
} else {
  console.log('ℹ️ Conditions not met — script exited');
}

console.groupEnd();
// Mimeeq Script for Cart Checking Variants End
</script>
{% endif %}
```

***

## Related articles

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Custom Loader</strong></td><td>Show your own loading animation while the configurator initialises.</td><td><a href="/developer-guides/custom-loader.md">Custom Loader</a></td></tr><tr><td><strong>Events &#x26; Tracking</strong></td><td>Use configurator events to feed your own analytics.</td><td><a href="/developer-guides/events-and-tracking.md">Events &amp; Tracking</a></td></tr><tr><td><strong>Webhooks</strong></td><td>Send real-time Mimeeq event data to your own systems.</td><td><a href="/developer-guides/webhooks.md">Webhooks</a></td></tr></tbody></table>


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.mimeeq.com/developer-guides/cart-validation-script.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
