# Gallery Integration

## Final Result :tada:

<figure><img src="/files/9HG048YDcT8MUqULqJMi" alt=""><figcaption><p>Completly integrated Viewer with different Variants</p></figcaption></figure>

## Integration Example

### Step 1:  Add the Mazing Script to the `<head>` Element

To enable the Mazing Viewer, include the following script in the `<head>` element of your HTML. This script initializes the library and prepares your website for the 3D experience.

```
<!-- MAZING -->
<script src="https://cdn.mazing.link/mzg-in.js" defer="defer"></script>
```

**Note:** The `defer` attribute ensures the script is loaded after the HTML document is parsed, optimizing page performance.

### Step 2:  Add Your Custom Script at the End of the `<body>`

Create a new script at the end of the `<body>` element. This script contains the logic to load and customize your 3D experience.

```
    ...
    
    <!-- MAZING -->
    <script>
        // YOUR SCRIPT COMES HERE!
    
    </script>

  </body>
```

{% hint style="info" %}
**Why at the End?** Adding your script at the end ensures that the HTML content is fully loaded before your logic is executed, preventing errors.
{% endhint %}

### Step 3:  Fill in Your Script Logic

In this step, you’ll add the main logic to initialize the Mazing Viewer. Copy and paste the following code into your script file or the `<script>` element you created earlier (for non-Shopify users).

```
// Wait for the mazingProjectAvailable function to become available
// Ensures the header script is fully loaded
const waitForMazingFunction = new Promise((resolve) => {
  const interval = 50; // Check every 50ms
  const checkInterval = setInterval(() => {
    if (typeof mazingProjectAvailable === 'function') {
      clearInterval(checkInterval);
      resolve();
    }
  }, interval);
});


// Main script logic
const initializeScript = async () => {
  // Wait for Mazing to be ready
  await waitForMazingFunction;

  console.log('mazing configuration is active :)');
  
  // TODO: Add your custom logic here
  
}
  
// Start the initialization
initializeScript();
```

**What’s Happening?**

* The `waitForMazingFunction` ensures that the `mazingProjectAvailable` function is fully loaded before you execute your custom script.
* Once everything is ready, the script logs `Mazing configuration is active :)` to confirm successful initialization.

{% hint style="info" %}
**Tip:** Open the browser’s developer console to verify if the message appears. If it does, the script is working correctly.
{% endhint %}

### Step 4: Get SKU and Create an iFrame

Next, you’ll use `mazingProjectAvailable()` to retrieve the `iframeSrc` for the Mazing Viewer. This function fetches the SKU (Stock Keeping Unit) of the current product and initializes the viewer.

```
const initializeScript = async () => {
  await waitForMazingFunction;

  // Get the iFrame source by calling mazingProjectAvailable
  const iframeSrc = await mazingProjectAvailable({
        customerName: 'YourMazingCustomer',
        getSKU: () => {
    
            // Extract SKU from the current product URL
            const url = window.location.href;
            const match = url.match(/\/products\/([^?]+)/);
            const currentProduct = match ? match[1] : null;

            return currentProduct;
        }
  });
  
  // TODO: Use iframeSrc to create and append the iFrame
  
}
  
initializeScript();
```

#### **What’s Happening?**

* **Retrieve the SKU:**\
  The `getSKU` function extracts the SKU from the product URL using a regular expression.\
  For example, a URL like `https://example.com/products/your-product` will return `your-product` as the SKU.
* **Generate the iFrame Source:**\
  The `mazingProjectAvailable` function uses the SKU to create the `iframeSrc`, which is needed to display the Mazing Viewer.
* **Use the iFrame Source:**\
  After generating the `iframeSrc`, you can use it to embed the viewer on your website.

Once you have the `iframeSrc`, customize and append it to your website as needed. See the [Script Integration](/mazing-world/integration-types/button-integration.md) Documentation for more details.

### Step 5: Create the iFrame Using the `iframeSrc`

Use the `iframeSrc` to dynamically generate the iFrame and embed it into your website. Here's an example script that shows how you can achieve this:

```
const initializeScript = async () => {
  await waitForMazingFunction;

  // Retrieve the iframe source using mazingProjectAvailable
  const iframeSrc = await mazingProjectAvailable({
        customerName: 'YourMazingCustomer',
        getSKU: () => {
    
            const url = window.location.href;
            const match = url.match(/\/products\/([^?]+)/);
            const currentProduct = match ? match[1] : null;

            return currentProduct;
        }
  });
  
  let iframeElement;
  
  // Create the iframe element
  iframeElement = document.createElement('iframe');
  iframeElement.style.cssText = "border: 0; height: 100%; left: 0; position: absolute;  top: 0; width: 100%; background: white; display: none; padding-left: 22px;"; // max-height: 600px;
  
  // HERE WE USE THE IFRAMESRC !
  
  iframeElement.src = iframeSrc;
  iframeElement.allow = "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; camera *; xr-spatial-tracking;";
  iframeElement.allowFullscreen = true;
  iframeElement.setAttribute('allowusermedia', '');
  iframeElement.id = 'mazing-iframe';
  
  
  /* 
  * Now you can use this iframe and add it to the desired spot. Let's say you want
  * to put the iframe in a div in your shop with an id of 'gallery-div1' :
  */
  
  // Add the iframe to the desired container
  const iframeContainer = document.getElementById('gallery-div1');
  iframeContainer.appendChild(iframe);
  
}
  
initializeScript();
```

The script dynamically creates an `iframe` element, assigning it the necessary attributes and styles to embed the Mazing Viewer seamlessly into your website.

{% hint style="info" %}
**What is an `<iframe>`?**\
An `<iframe>` is an HTML element that allows you to embed another HTML document or external content (like the Mazing Viewer) within your webpage. It's like creating a "window" to display content from a different source directly on your site.
{% endhint %}

The `display: none` style is applied by default to hide the iFrame, preventing any visual glitches or flickering when no product is available. This behavior ensures a smooth user experience but can be customized to fit your specific requirements.

By default, the example assumes that the `iframe` will be embedded into a `div` element with the ID `gallery-div1`. You can replace this ID with the appropriate container ID for your setup.

{% hint style="info" %}
If no `iframeSrc` is provided, a `500 Server Error` will appear in the console.

* **Reason:** This error occurs when no model matching the SKU is found in the Mazing World.
* **Impact:** The error is non-critical and can be safely ignored as it does not affect the feature’s functionality.
  {% endhint %}

### Step 6: Use postMessage to Switch Between Variants

Now it’s time to use the **ID/Trigger** defined for each variant. This will allow you to switch between different product variations using your own custom user interface.

<figure><img src="/files/RXcPhslZncvpOpVTiCNu" alt=""><figcaption></figcaption></figure>

For example, if you have a dropdown menu for selecting variations, you can listen for a user’s selection and send a `postMessage` to the Mazing Viewer. Let’s assume your dropdown menu has the ID `operations-dropdown`.

Here’s how you can implement this logic:

```
    // This is the select element from our example
    const operations = document.getElementById('operations-dropdown');

    // We iterate through all options and add an event listener on each option
    for(let i=0; i < operations.length; i++) {

        const operation = operations[i];
        // This is the value of the option. This will become important later on!
        const dropdownItemValue = operation.value;

        operation.addEventListener('click', () => {

            console.log('clicked variant', dropdownItemValue);
            
            // Send the postMessage to change the Variant.
            iframeElement.contentWindow.postMessage({
                type: 'SWITCH_VARIANT',
                value: {
                    trigger: dropdownItemValue
                }
            }, '*');
        });
    }
```

When an option in the dropdown is clicked, the script sends a `postMessage` to the Mazing Viewer. The `trigger` value in the message corresponds to the variant’s ID/Trigger, which you defined earlier during variant creation. See -> [Variant Operations](/mazing-world/product-guides/create-3d-configurator.md)

For instance:

* Clicking the **"All-Black"** option sends a trigger value of `"all-black"`.
* This value activates the variant with the corresponding ID/Trigger.

### Step 7 (optional): Model Loaded / Model Visibility

Sometimes you need to delay certain actions until the 3D model is fully loaded. This is because the `MODEL_3D_LOADED` event ensures that the viewer is ready to receive commands via `postMessage`. For example, if you have pre-selected variants you want to apply automatically, calling them too early may be overwritten—right after the model finishes loading, the first variant is always applied as the original state. To avoid this, wait for the `MODEL_3D_LOADED` event before sending your variant selection, and optionally add a short delay to ensure that the initial state has been set before applying your changes.

{% hint style="info" %}

* **Model Loading and Visibility**
  * PostMessage operations are sent **only after the model is fully loaded**.
  * The model starts loading once the `<iframe>` becomes visible (i.e., when `display: none` is removed).
* **Queued Operations**
  * Actions triggered by `postMessage` will execute once the model is fully loaded.
  * You can either:
    * Enable controls after loading is complete, or
    * Queue operations to run automatically after the model is ready.
      {% endhint %}

{% hint style="warning" %}
Once the 3D model has finished loading, an action is sent to notify you:<br>

<kbd>**window\.top.postMessage({**</kbd>&#x20;

&#x20; <kbd>**type: 'MODEL\_3D\_LOADED',**</kbd>&#x20;

&#x20; <kbd>**value: {**</kbd>&#x20;

&#x20;   <kbd>**model: model**</kbd>&#x20;

&#x20; <kbd>**},**</kbd>&#x20;

<kbd>**}, '\*');**</kbd>

{% endhint %}

Here's an example of how you can check for the model loading and set up your environment:

```
// Listen for the MODEL_3D_LOADED event
window.addEventListener('message', (event) => {
    if (event.data.type === 'MODEL_3D_LOADED') {
        console.log('Model loaded');

        // Enable controls or add event listeners for options
        initializeColorOptions();
    }
});

// Make the iFrame visible to start loading the model
const iframe = document.getElementById('model-iframe');
iframe.style.display = 'block'; // or any other logic to unhide the iFrame

```

## Create and Send Your Variant

**Creating the Variant:**\
This step demonstrates how to define a variant, such as "all-black," within your configuration.

<figure><img src="/files/kNEUmdCQx1l3JqMFnJ8F" alt=""><figcaption></figcaption></figure>

**Sending the PostMessage:**\
Send a `postMessage` with the trigger value *'all-black'* from your shop website to switch between product variants.

<figure><img src="/files/vLruq7WHlmRwtWyuZPM9" alt=""><figcaption></figcaption></figure>

**Congratulations!**\
You've successfully integrated your first configurator into your website! 🎉


---

# Agent Instructions: 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://mazingxr.gitbook.io/mazing-world/integration-types/gallery-integration.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.
