# Tools

URL: https://docs.ablyft.com/de/developers/reference/javascript-api/tools/

> Hilfsfunktionen, die über ablyft.getTools() verfügbar sind.



Das Tools-Objekt wird von `ablyft.getTools()` und `ablyft.get('tools')` zurückgegeben. Im JavaScript von Experiments und Variations
steht es als `ablyftTools` zur Verfügung.

```js
const tools = ablyft.getTools();
// In experiment / variation JavaScript:
ablyftTools.waitForElement('.hero', (el) => { /* ... */ });
```

| Gruppe                                     | Funktionen                                                                                                    |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| [Cookies](#cookies)                        | `setCookie`, `getCookie`, `removeCookie`                                                                      |
| [URLs](#urls)                              | `parseUrl`, `getRootDomain`, `getUrlParameter`, `buildRedirectUrl`, `redirect`, `getSetBucketingUrlExtension` |
| [Warten & Beobachten](#waiting--observing) | `poll`, `check`, `domLoaded`, `domChanged`, `waitForElement`, `elementIsInView`, `urlChanged`                 |
| [Data Layer](#data-layer)                  | `checkForDataLayerEntry`, `watchDataLayerEntry`                                                               |
| [Ressourcen laden](#loading-resources)     | `loadExternalCss`, `loadExternalJs`                                                                           |
| [Shopify](#shopify)                        | `shopifyPreviewTheme`, `shopifySwitchTemplate`                                                                |
| [Editor extensions](#editor-extensions)    | `applyEditorExtension`, `resetEditorExtension`                                                                |
| [Hilfsfunktionen](#utilities)              | `hash`, `generateRandomId`, `pickProperties`, `getNestedValue`                                                |

## Cookies

### setCookie

`setCookie(name, value, days?, ignoreDomain?)`

Setzt einen Cookie (`SameSite=Lax`, `Path=/`). `days` ist standardmäßig die maximale Cookie-Lebensdauer des Projects. Sofern `ignoreDomain` nicht `true` ist, wird der Cookie auf der Root-Domain (oder der benutzerdefinierten Cookie-Domain des Projects) gesetzt.

```js
tools.setCookie('my_cookie', 'yes', 30); // 30 days, root domain
tools.setCookie('my_host_cookie', '1', 7, true); // current host only
```

### getCookie

`getCookie(name)` gibt den Wert oder `null` zurück.

```js
const value = tools.getCookie('my_cookie');
```

### removeCookie

`removeCookie(name)` entfernt den Cookie auf dem aktuellen Host und auf der Root-Domain.

```js
tools.removeCookie('my_cookie');
```

## URLs

### parseUrl

`parseUrl(url?)` zerlegt eine URL (Standard: aktuelle Seite) in `protocol`, `host`, `hostname`, `port`, `pathname`, `search`, `hash`, `domain`, `tld` und `subdomain`.

```js
const url = tools.parseUrl('https://shop.example.co.uk/cart?x=1');
// url.subdomain === 'shop', url.domain === 'example', url.tld === 'co.uk'
```

### getRootDomain

`getRootDomain()` gibt die Cookie-Domain zurück, z. B. `.example.com` (oder die benutzerdefinierte Cookie-Domain des Projects).

```js
const rootDomain = tools.getRootDomain();
```

### getUrlParameter

`getUrlParameter(name, url?)` gibt den Parameterwert zurück, einen leeren String, wenn der Parameter keinen Wert hat, oder `null`, wenn er fehlt.

```js
const source = tools.getUrlParameter('utm_source');
const other = tools.getUrlParameter('id', 'https://example.com/?id=42');
```

### buildRedirectUrl

`buildRedirectUrl(url, keepQueryParameters?)` gibt die endgültige Redirect-URL zurück (Standard `keepQueryParameters = true`). Bei `true` werden die aktuellen Query-Parameter und der Hash in das Ziel übernommen (Parameter des Ziels haben Vorrang). Liegt das Ziel auf einer anderen Domain, wird die aktuelle Variation-Zuweisung als URL-Parameter angehängt.

```js
const target = tools.buildRedirectUrl('/landing-b/');
```

### redirect

`redirect(url, keepQueryParameters?, preventLoops?)`

Leitet den Visitor um (mit `location.replace`) und blendet die Seite währenddessen aus. Gibt `false` zurück, wenn der Redirect übersprungen wurde.

| Parameter             | Standard | Beschreibung                                                                                                                           |
| --------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `keepQueryParameters` | `true`   | Aktuelle Query-Parameter in das Ziel übernehmen                                                                                        |
| `preventLoops`        | `5`      | Mindestanzahl Sekunden zwischen zwei Redirects in einer Session. Eine Ganzzahl legt die Sekunden fest, `false` deaktiviert den Schutz. |

```js
tools.redirect('/landing-b/');
tools.redirect('https://example.com/new/', false); // do not keep query parameters
tools.redirect('/landing-b/', true, false); // no loop protection
```

### getSetBucketingUrlExtension

`getSetBucketingUrlExtension()` gibt die Variation-Zuweisung des Visitors im Format des Bucketing-URL-Parameters zurück (z. B. `["12345678_98765432"]`), oder `null`, wenn es keine gibt. Nutze es, um die Zuweisung manuell an eine andere Domain zu übergeben.

```js
const extension = tools.getSetBucketingUrlExtension();
```

## Warten & Beobachten

### poll

`poll(pollingFn, callbackFn, callbackFnOnFail?, timeoutMs?, timeoutAfterDomReadyMs?)`

Ruft `pollingFn` alle 10 ms auf, bis sie genau `true` zurückgibt, und ruft dann `callbackFn` auf. Gelingt das nicht innerhalb von `timeoutMs` (Standard `10000`) oder `timeoutAfterDomReadyMs` (Standard `2000`) nach DOM-Ready, wird `callbackFnOnFail` aufgerufen.

```js
tools.poll(
  () => window.myLibrary !== undefined,
  () => console.log('library ready'),
  () => console.log('library not found'),
);
```

### check

`check(checkFn, callbackFn, callbackFnOnFail?)` wertet `checkFn` einmal aus. Gibt sie genau `true` zurück, wird `callbackFn` aufgerufen, andernfalls `callbackFnOnFail`.

```js
tools.check(
  () => document.body.classList.contains('checkout'),
  () => console.log('on checkout'),
);
```

### domLoaded

`domLoaded(callbackFn)` ruft die Funktion auf, sobald das DOM interaktiv ist (sofort, wenn es das bereits ist).

```js
tools.domLoaded(() => console.log('DOM ready'));
```

### domChanged

`domChanged(callbackFn)` ruft die Funktion bei jeder DOM-Änderung auf (Children, Subtree, Attribute). Änderungen durch ABlyft selbst werden ignoriert.

```js
tools.domChanged(() => console.log('The page changed'));
```

### waitForElement

`waitForElement(selector, fn, additionalData?)`

Ruft `fn(element, additionalData)` für jedes Element auf, das `selector` entspricht, sobald es im DOM existiert (einmal pro Element). `this` ist ebenfalls das Element.

```js
tools.waitForElement('.product-title', (el) => {
  el.textContent = 'New title';
});
```

### elementIsInView

`elementIsInView(selector, fn, persistentObserving?)`

Ruft `fn(element)` auf, wenn ein passendes Element in den Viewport scrollt. Bei `persistentObserving = true` bleiben Elemente weiter beobachtet. Später hinzugefügte Elemente werden miterfasst.

```js
tools.elementIsInView('.reviews', (el) => {
  console.log('reviews are visible', el);
});
```

### urlChanged

`urlChanged(mode, callbackFn)`

Ruft die Funktion auf, wenn sich die URL ändert. `mode` ist `'polling'` (vergleicht die URL alle 10 ms) oder `'history'` (hängt sich in `pushState`, `replaceState` und `popstate` ein).

```js
tools.urlChanged('polling', () => console.log('URL is now', location.href));
tools.urlChanged('history', () => console.log('history navigation'));
```

## Data Layer

### checkForDataLayerEntry

`checkForDataLayerEntry(entrySpecs, callbackFn)`

Wartet (bis zu einer Stunde), bis ein Eintrag in `window.dataLayer` allen `[key, value]`-Paaren exakt entspricht, und ruft dann `callbackFn` auf.

```js
tools.checkForDataLayerEntry(
  [['event', 'purchase'], ['currency', 'EUR']],
  () => console.log('purchase event found'),
);
```

### watchDataLayerEntry

`watchDataLayerEntry(eventName, callback)`

Ruft `callback(entry)` für den neuesten vorhandenen Data-Layer-Eintrag mit `event === eventName` und für jeden zukünftigen auf. Gibt eine Funktion zurück, die das Beobachten beendet. Die Erkennungsmethode (`intercept` oder `polling`) wird in den Snippet-Einstellungen des Projects festgelegt. Fehler innerhalb des Callbacks werden abgefangen und protokolliert.

```js
const stop = tools.watchDataLayerEntry('add_to_cart', (entry) => {
  console.log('Item added', entry);
});

// later, if no longer needed
stop();
```

## Ressourcen laden

### loadExternalCss

`loadExternalCss(url)` hängt einen Stylesheet-Link an `<head>` an.

```js
tools.loadExternalCss('https://example.com/extra.css');
```

### loadExternalJs

`loadExternalJs(url, callbackFn)` hängt ein Script an `<head>` an und ruft `callbackFn` auf, wenn es geladen wurde.

```js
tools.loadExternalJs('https://example.com/lib.js', () => console.log('loaded'));
```

## Shopify

Zur Verwendung in Shopify-Theme- und Template-Variations, siehe [Shopify Variations](https://docs.ablyft.com/de/guides/experiments/shopify-variations/).

### shopifyPreviewTheme

`shopifyPreviewTheme(themeId)` wartet auf das `Shopify`-Objekt und leitet, falls das aktuelle Theme abweicht, auf die Preview des angegebenen Themes um.

```js
tools.shopifyPreviewTheme(123456789);
```

### shopifySwitchTemplate

`shopifySwitchTemplate(templateName)` leitet auf `?view=<templateName>` um, wenn die Seite noch keinen `view`-Parameter hat.

```js
tools.shopifySwitchTemplate('landing-b');
```

## Editor extensions

Wird von Variations verwendet, die mit dem Visual Editor und seinen Extensions erstellt wurden. Die Extension muss im Project existieren.

### applyEditorExtension

`applyEditorExtension(variationId, selector, extensionId, extensionData, instance?)`

Rendert eine Extension in die Variation und gibt die Instance-ID zurück (wird generiert, wenn sie fehlt). Unbekannte Extensions werden als Fehler protokolliert.

```js
const instance = tools.applyEditorExtension(12345678, 'body', '1', {
  headline: 'Inserted by an extension',
});
```

### resetEditorExtension

`resetEditorExtension(variationId, extensionId, instance)` entfernt das CSS der Extension und führt ihren Reset-Code aus.

```js
tools.resetEditorExtension(12345678, '1', instance);
```

## Hilfsfunktionen

### hash

`hash(string)` gibt einen kurzen hexadezimalen Hash eines Strings zurück.

```js
const id = tools.hash('user@example.com');
```

### generateRandomId

`generateRandomId()` gibt eine zufällige alphanumerische ID mit 10 Zeichen zurück.

```js
const id = tools.generateRandomId();
```

### pickProperties

`pickProperties(object, keys)` gibt ein neues Objekt zurück, das nur die aufgelisteten Keys enthält (die auf dem Objekt existieren).

```js
const small = tools.pickProperties({ a: 1, b: 2, c: 3 }, ['a', 'c']); // { a: 1, c: 3 }
```

### getNestedValue

`getNestedValue(object, path)` liest einen verschachtelten Wert über einen Punkt-Pfad und gibt `undefined` zurück, wenn ein Teil fehlt.

```js
const coupon = tools.getNestedValue({ ecommerce: { coupon: 'SUMMER' } }, 'ecommerce.coupon');
```

