# Dynamische Inhalte

URL: https://docs.ablyft.com/de/developers/application-integration/dynamic-content/

> Führe Experiments auf Inhalten aus, die erst nach dem Laden der Seite erscheinen, etwa Modals, Tabs und AJAX-Inhalte.



Nicht alles, was ein Visitor sieht, ist beim Laden der Seite schon da. Modals, Cart Drawer, Tabs, Checkout-Schritte und Inhalte aus
einem API-Aufruf erscheinen später, oft ohne dass sich die URL ändert. Diese Seite zeigt, wie du ABlyft auf sie warten lässt.

Es gibt zwei getrennte Fragen:

1. **Wann soll das Experiment aktiv werden?** Gelöst mit dem *Trigger* einer [Page](https://docs.ablyft.com/de/guides/audiences-and-delivery/pages/).
2. **Wann kann mein Variation-Code ein Element ändern?** Gelöst mit Hilfsfunktionen in deinem Code.

## Die Page warten lassen: einen Trigger wählen

Jede Page hat einen **Trigger**, der festlegt, wann ABlyft das Targeting der Page prüft. Öffne **Targeting & Goals → Pages**,
bearbeite die Page und gehe zum Abschnitt **Trigger**.

| Trigger                                                 | Verwende ihn, wenn                                                                                  |
| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| **Direct (immediately when ABlyft runs)**               | der Inhalt beim Laden Teil der Seite ist (Standard für die meisten Projects)                        |
| **DOM Change (when something on the page is changing)** | die Page aktiv sein soll, sobald bestimmte Elemente existieren                                      |
| **Callback (when the callback function is called)**     | du in einem kleinen JavaScript-Stück selbst entscheidest, wann die Page startet                     |
| **API (manual activation by an API / JavaScript call)** | deine eigene Anwendung ABlyft mitteilt, wann die Page startet                                       |
| **URL Change …**                                        | sich die URL ändert, siehe [SPA navigation](https://docs.ablyft.com/de/developers/application-integration/spa-navigation/) |

### DOM Change-Trigger

Mit **DOM Change** prüft ABlyft die Page einmal beim Start und danach jedes Mal erneut, wenn sich die Seite ändert (Elemente werden hinzugefügt,
entfernt oder ihre Attribute ändern sich). Änderungen durch den eigenen Code von ABlyft werden ignoriert.

Um ihn zu nutzen, kombinierst du den Trigger mit **JavaScript rules**, die den dynamischen Inhalt beschreiben. Öffne **Advanced
Targeting** im Abschnitt **Targeting** der Page und schreibe eine Bedingung, die `true` zurückgibt, wenn der Inhalt existiert:

```js
// Page is active as soon as the cart drawer is open
return document.querySelector('.cart-drawer.is-open') !== null;
```

Die Bedingung ist erfüllt, wenn dein JavaScript `true` zurückgibt. Darin kannst du `ablyftTools` verwenden.

Zwei Optionen in **Advanced Targeting** helfen bei spät erscheinenden Inhalten:

| Option                      | Wirkung                                                                                                                                        |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| **Poll on rules**           | ABlyft prüft die Bedingung bis zu 2 Sekunden lang immer wieder, bevor es aufgibt. Nutze sie, wenn das Element kurz nach dem Trigger erscheint. |
| **Always embed in snippet** | Normalerweise nicht nötig. Aktiviere sie nur, wenn dein Setup es erfordert.                                                                    |

> **DOM Change läuft oft:** Eine geschäftige Seite ändert ihr DOM viele Male pro Sekunde, und ABlyft prüft die Page jedes Mal. Halte JavaScript rules
> kurz und schnell und vermeide darin aufwendige Operationen.

### Callback-Trigger

Mit **Callback** schreibst du die Logik selbst. Unter dem Trigger erscheint ein Feld für JavaScript. ABlyft führt deinen Code
beim Start aus (und bei jeder erneuten Ausführung, zum Beispiel nach `ablyft.reInit()`). Rufe `activate()` auf, wenn die Page aktiv sein soll. Du kannst außerdem `ablyftTools` und `page`
(ein Objekt mit der Page-`id`) verwenden.

```js
// Activate the page when the checkout step 2 is rendered
ablyftTools.waitForElement('.checkout-step-2', () => {
  activate();
});
```

Rufe `activate(false)` auf, um die Page wieder zu deaktivieren, zum Beispiel wenn ein Modal geschlossen wird:

```js
document.addEventListener('modal-opened', () => activate());
document.addEventListener('modal-closed', () => activate(false));
```

`activate()` prüft weiterhin die URL-Regeln und JavaScript rules der Page. Die Page wird nicht aktiviert, wenn diese nicht passen.

### API-Trigger

Mit **API** aktiviert dein eigener Code die Page mit einem `activatePage`-Aufruf, zum Beispiel in dem Handler, der dein Modal öffnet,
und deaktiviert sie mit `deactivatePage`. Einrichtung und Aufrufe sind in der [Page API](https://docs.ablyft.com/de/developers/reference/page-api/) beschrieben.

### Was passiert, wenn die Page deaktiviert wird

Der **Deactivation mode** der Page (**Advanced Settings → Deactivation mode**) steuert, ob Reset JS läuft und
ob die Page aktiv bleibt. Siehe [SPA navigation](https://docs.ablyft.com/de/developers/application-integration/spa-navigation/#deactivation-modes).

## Den Code warten lassen: Hilfsfunktionen

Auch auf einer aktiven Page kann ein Element noch nicht existieren. Verwende im Variation-Code die
[Tools](https://docs.ablyft.com/de/developers/reference/javascript-api/tools/), verfügbar als `ablyftTools`. Der Variation-Editor zeigt einen **Code Helper**
mit fertigen Snippets für die häufigsten Funktionen.

| Funktion                                                                                                                        | Verwende sie, um                                                                                                            |
| ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| [`waitForElement`](https://docs.ablyft.com/de/developers/reference/javascript-api/tools/#waitforelement)                                               | Code für jedes Element auszuführen, das zu einem Selektor passt, sobald es existiert, auch für später hinzugefügte Elemente |
| [`elementIsInView`](https://docs.ablyft.com/de/developers/reference/javascript-api/tools/#elementisinview)                                             | Code auszuführen, wenn ein Element in den Viewport scrollt                                                                  |
| [`domChanged`](https://docs.ablyft.com/de/developers/reference/javascript-api/tools/#domchanged)                                                       | Code bei jeder DOM-Änderung auszuführen                                                                                     |
| [`domLoaded`](https://docs.ablyft.com/de/developers/reference/javascript-api/tools/#domloaded)                                                         | Code auszuführen, wenn das DOM bereit ist                                                                                   |
| [`poll`](https://docs.ablyft.com/de/developers/reference/javascript-api/tools/#poll) / [`check`](https://docs.ablyft.com/de/developers/reference/javascript-api/tools/#check) | auf eine beliebige Bedingung zu warten, die du definierst                                                                   |

```js
// Variation JS: change a button that is rendered later
ablyftTools.waitForElement('.add-to-cart', (button) => {
  button.textContent = 'Add to basket';
});
```

`waitForElement` ruft deine Funktion einmal pro Element auf. Wird das Element von deiner Anwendung ersetzt (zum Beispiel neu gerendert),
wird auch das neue Element behandelt.

## Dynamische Daten: Audiences erneut prüfen

Audiences werden ausgewertet, wenn ein Experiment startet. Wird ein Wert erst später bekannt, zum Beispiel weil ein Cookie gesetzt oder ein
Data-Layer-Eintrag gepusht wird, teile ABlyft mit, noch einmal nachzusehen:

```js
ablyft.push({ eventType: 'reevaluateAudiences' });
```

ABlyft wertet dann die Audiences der Experiments auf aktuell aktiven Pages neu aus, die noch nicht laufen. Visitors,
die bereits von einem Experiment ausgeschlossen wurden, bleiben ausgeschlossen.

Bei Audiences, die davon abhängen, dass auf der Seite etwas passiert, musst du den Aufruf nicht selbst auslösen. Audience-Regeln
vom Typ **JavaScript Trigger** (rufe `activate()` auf, wenn die Audience passen soll) und **dataLayer Event** lösen die erneute
Prüfung automatisch aus. Siehe [Data layer events](https://docs.ablyft.com/de/developers/tracking-and-events/datalayer-events/).

## Fehlerbehebung

* **Page wird nie aktiviert:** Prüfe die JavaScript rules in der Konsole deines Browsers und aktiviere den
  [Debug-Modus](https://docs.ablyft.com/de/developers/debugging/preview-and-live-log/#debug-mode). Aktivierte Pages werden protokolliert.
* **Page wird aktiviert, aber die Änderung wird nicht angewendet:** Dein Selektor passt nicht, oder das Element erscheint, nachdem dein
  Code gelaufen ist. Umgib die Änderung mit `ablyftTools.waitForElement`.
* **Änderung verschwindet, wenn die App neu rendert:** Verwende `waitForElement` statt einer einmaligen Änderung, damit jede neue Kopie des Elements geändert wird.

## Nächste Schritte

- [SPA navigation](https://docs.ablyft.com/de/developers/application-integration/spa-navigation/): URL-Trigger und reInit().
- [Custom JavaScript](https://docs.ablyft.com/de/developers/application-integration/custom-javascript/): Wo du Experiment-Code schreibst.
- [Tools](https://docs.ablyft.com/de/developers/reference/javascript-api/tools/): Alle Hilfsfunktionen.

