> For the complete documentation index, see [llms.txt](https://mazingxr.gitbook.io/mazing-world/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mazingxr.gitbook.io/mazing-world/de/integration-types/gallery-integration.md).

# Gallery Integration

### **Finales Ergebnis 🎉**

Vollständig integrierter **Viewer mit verschiedenen Varianten**

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

## **Integrationsbeispiel**

### **Schritt 1: Mazing-Skript in das `<head>`-Element einfügen**

Um den **Mazing Viewer** zu aktivieren, füge das folgende Skript in den **`<head>`-Bereich** deiner HTML-Datei ein:

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

**Hinweis:** Das `defer`-Attribut sorgt dafür, dass das Skript erst nach dem Parsen des HTML-Dokuments geladen wird und verbessert so die Performance.

### **Schritt 2: Eigenes Skript am Ende des `<body>` hinzufügen**

Erstelle ein neues Skript am Ende des **`<body>`-Elements**:

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

  </body>
```

{% hint style="info" %}
**Warum am Ende?**\
Damit wird sichergestellt, dass der gesamte HTML-Inhalt geladen ist, bevor dein Skript ausgeführt wird.
{% endhint %}

### **Schritt 3: Skript-Logik einfügen**

```
// 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();
```

**Was passiert hier?**

* Wartet, bis **`mazingProjectAvailable`** geladen ist
* Gibt eine Bestätigung im Console-Log aus

{% hint style="info" %}
Tipp: Prüfe die Konsole, um sicherzugehen, dass alles funktioniert.
{% endhint %}

### **Schritt 4: SKU abrufen & iFrame erstellen**

```
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();
```

### **Was passiert hier?**

#### **SKU abrufen**

Die Funktion **`getSKU`** extrahiert die **SKU** aus der Produkt-URL mithilfe eines **regulären Ausdrucks**.

Beispiel:\
Eine URL wie `https://example.com/products/your-product` gibt **`your-product`** als SKU zurück.

***

#### **iFrame-Quelle generieren**

Die Funktion **`mazingProjectAvailable`** verwendet die SKU, um die **`iframeSrc`** zu erstellen, die benötigt wird, um den **Mazing Viewer** anzuzeigen.

***

#### **iFrame-Quelle verwenden**

Nachdem die **`iframeSrc`** generiert wurde, kannst du sie verwenden, um den Viewer auf deiner Website einzubetten.

Sobald du die **`iframeSrc`** hast, kannst du sie nach Bedarf anpassen und in deine Website einfügen.\
Weitere Details findest du in der **Script Integration Dokumentation**.

### **Schritt 5: iFrame erstellen**

```
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();
```

{% hint style="info" %}
**Was ist ein `<iframe>`?**\
Ein HTML-Element, das externe Inhalte (z. B. den Mazing Viewer) in deine Seite einbettet.
{% endhint %}

👉 `display: none` verhindert visuelle Glitches beim Laden.

{% 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 %}

### **Schritt 6: Varianten wechseln mit postMessage**

Jetzt ist es an der Zeit, die für jede Variante definierte **ID / den Trigger** zu verwenden.\
Damit kannst du über deine eigene **Benutzeroberfläche** zwischen verschiedenen Produktvarianten wechseln.

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

Wenn du zum Beispiel ein **Dropdown-Menü** zur Auswahl von Varianten hast, kannst du auf die Auswahl des Nutzers reagieren und eine **postMessage** an den **Mazing Viewer** senden.

Angenommen, dein Dropdown-Menü hat die ID **`operations-dropdown`**.

So kannst du diese Logik implementieren:

```
    // 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
                }
            }, '*');
        });
    }
```

Wenn eine Option im Dropdown angeklickt wird, sendet das Skript eine **postMessage** an den **Mazing Viewer**.

Der **Trigger-Wert** in der Nachricht entspricht der **ID / dem Trigger** der Variante, die du zuvor bei der Variantenerstellung definiert hast.\
Siehe → **Variant Operations**

Zum Beispiel:

Wenn die Option **„All-Black“** angeklickt wird, wird der Trigger-Wert **`all-black`** gesendet.

Dieser Wert aktiviert die Variante mit der entsprechenden **ID / dem entsprechenden Trigger**.

***

### **Schritt 7 (optional): Modell geladen / Modell-Sichtbarkeit**

Manchmal musst du bestimmte Aktionen verzögern, bis das **3D-Modell vollständig geladen** ist.

Das liegt daran, dass das Event **`MODEL_3D_LOADED`** sicherstellt, dass der Viewer bereit ist, Befehle über **postMessage** zu empfangen.

Wenn du beispielsweise vorausgewählte Varianten automatisch anwenden möchtest, kann ein zu früher Aufruf überschrieben werden – direkt nachdem das Modell fertig geladen ist, wird nämlich immer die erste Variante als ursprünglicher Zustand angewendet.

Um das zu vermeiden, solltest du auf das Event **`MODEL_3D_LOADED`** warten, bevor du deine Variantenauswahl sendest. Optional kannst du zusätzlich eine kurze Verzögerung einbauen, um sicherzustellen, dass der Ausgangszustand gesetzt wurde, bevor deine Änderungen angewendet werden.

{% hint style="info" %}

* **Modell-Laden und Sichtbarkeit**

  **postMessage-Operationen** werden erst gesendet, nachdem das **Modell vollständig geladen** ist.

  Das Modell beginnt erst zu laden, sobald das **`<iframe>` sichtbar wird** (also wenn `display: none` entfernt wird).
* **Warteschlange (Queued Operations)**

  Aktionen, die über **postMessage** ausgelöst werden, werden erst ausgeführt, wenn das Modell vollständig geladen ist.

  Du kannst entweder:

  * die **Steuerelemente erst nach dem Laden aktivieren**, oder
  * Aktionen **vorab in eine Warteschlange legen**, sodass sie automatisch ausgeführt werden, sobald das Modell bereit ist.
    {% endhint %}

{% hint style="warning" %}
Sobald das **3D-Modell vollständig geladen** ist, wird eine Aktion ausgelöst, um dich darüber zu informieren:

<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 %}

Hier ist ein Beispiel, wie du überprüfen kannst, ob das Modell geladen wurde, und deine Umgebung entsprechend vorbereitest:

```
// 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

```

### **Variante erstellen und senden**

#### **Variante erstellen**

Dieser Schritt zeigt, wie du eine Variante (z. B. **„all-black“**) innerhalb deiner Konfiguration definierst.

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

#### **postMessage senden**

Sende eine **postMessage** mit dem Trigger-Wert **`all-black`** von deiner Shop-Website, um zwischen Produktvarianten zu wechseln.

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

### 🎉 **Glückwunsch!**

Du hast erfolgreich deinen ersten **Konfigurator** in deine Website integriert!
