Pixel-Installation
Installiere den Adverfly-Tracking-Pixel auf deiner Website
Der Adverfly-Pixel ist ein JavaScript-Snippet, das Nutzer-Interaktionen auf deiner Website trackt. Er erfasst Pageviews, Events und Conversions und füttert deine Analytics.
Schnellstart
Füge den folgenden Code in den <head>-Bereich deiner Website ein:
<script>
window.adverfly = window.adverfly || [];
function advPxl() {
var args = [false];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
adverfly.push(args);
}
advPxl("init", DEINE_WORKSPACE_ID);
window.adverfly.store_currency = "EUR";
window.adverfly.store_timezone = "Europe/Berlin";
var script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.src = "https://sos-de-fra-1.exo.io/adv/advv2.01.js";
document.getElementsByTagName("head")[0].appendChild(script);
</script>
Ersetze DEINE_WORKSPACE_ID durch deine Workspace-ID aus dem Adverfly-Dashboard.
Konfiguration
| Parameter | Type | Required | Description |
|---|---|---|---|
workspace_id | number | Required | Deine Adverfly-Workspace-ID |
store_currency | string | Required | Die Basiswährung deines Shops (z. B. EUR, USD) |
store_timezone | string | Required | Die Zeitzone deines Shops (z. B. Europe/Berlin) |
Währungsumrechnung
Die store_currency-Einstellung ist wichtig für genaue Umsatz-Tracking. Wenn eine Transaktion in einer anderen Währung eingeht (z. B. zahlt ein Kunde in USD), rechnet Adverfly diese automatisch zum aktuellen Wechselkurs in deine Shop-Währung um.
Beispiel: Deine Shop-Währung ist EUR. Ein Kunde zahlt 129 USD. Adverfly rechnet das in deinen Reports auf ~119 € um.
Zeitzone
Die store_timezone stellt sicher, dass alle Events und Conversions in deiner lokalen Zeit erfasst werden — das macht deine Reports einfacher zu lesen und auszuwerten.
Events tracken
Custom-Events mit dem Adverfly-Pixel tracken
Sobald der Pixel installiert ist, kannst du Custom-Events tracken, um Nutzer-Interaktionen zu erfassen.
Grundlegendes Event-Tracking
Verwende die advPxl-Funktion, um Events zu tracken:
// Add to Cart
advPxl("event", "add_to_cart");
// Initiated Checkout
advPxl("event", "initiated_checkout");
Standard-Events
| Code | Description |
|---|---|
pageview | Nutzer sieht eine Seite (wird automatisch beim Init getrackt) |
add_to_cart | Nutzer legt ein Produkt in den Warenkorb |
initiated_checkout | Nutzer startet den Checkout |
Autocapture
Das v3-Pixel kann Nutzer-Interaktionen automatisch erfassen — Klicks, Form-Submits, Input-Änderungen, Rage-Clicks und Copy/Cut-Aktionen — ohne manuelle advPxl-Aufrufe. Standardmäßig deaktiviert: aktiviere es pro Workspace mit window.adverfly.activate_autocapture = true vor dem init.
window.adverfly = window.adverfly || [];
window.adverfly.activate_autocapture = true;
advPxl("init", 8397799);
Erfasste Events
| Code | Description |
|---|---|
$click | Wird bei Klicks ausgelöst. Das Ziel wird auf das nächstgelegene interaktive Eltern-Element aufgelöst (a, button, input, select, textarea, label, form oder role=button|link|menuitem). |
$submit | Wird bei Form-Submits ausgelöst. Enthält Action und Methode des Formulars. |
$change | Wird bei <select>-Änderungen sowie Checkbox-/Radio-Toggles ausgelöst. Werte von Text-Inputs werden NIEMALS erfasst. |
$rageclick | Wird ausgelöst, wenn dasselbe Element innerhalb 1 Sekunde 3+ mal geklickt wird. |
$copy | Wird ausgelöst, wenn ein Nutzer Inhalt kopiert. Es werden ausschließlich Metadaten erfasst — niemals der kopierte Text selbst. |
$cut | Wird ausgelöst, wenn ein Nutzer Inhalt ausschneidet. Nur Metadaten werden erfasst. |
Privacy
Autocapture ist so designt, dass keine sensiblen Daten geleakt werden. Folgendes wird clientseitig erzwungen, bevor etwas gesendet wird:
- Niemals erfasste Input-Typen:
password,hidden,file. - Über Name/Autocomplete blockierte Felder: Kreditkarte (
cc-*,card-num,card-no), CVC/CVV, Ablaufdatum, SSN, Sozialversicherung, Passwort, API-Keys, Auth-Tokens, Einmal-Codes. - Werte von Freitext-Inputs werden nie gelesen:
<input type="text|email|tel|...">und<textarea>werden nie erfasst. Nur<select>-Optionen sowie Checkbox-/Radio-Status. - Text-Scrubbing: Jeder Token in sichtbarem Text, der wie eine Kreditkartennummer, SSN oder eine Folge von 13+ Ziffern aussieht, wird vor dem Senden entfernt. Das Ergebnis wird auf 200 Zeichen gekürzt.
- Opt-out-Selektoren: Elemente (und Kinder) mit Klasse
adv-no-captureoder Attributdata-adv-no-capturewerden komplett übersprungen.
Elemente ausschließen
Ein bestimmtes Element (und alle Kinder) ausschließen:
<!-- via Klasse -->
<div class="adv-no-capture">
<input type="text" name="internal-note" />
</div>
<!-- via Attribut -->
<section data-adv-no-capture>
<button>Interne Aktion</button>
</section>
Konfiguration
Feinsteuerung via window.adverfly.autocapture_config (vor init setzen):
| Code | Description |
|---|---|
url_allowlist | Array aus Strings (Substring-Match) oder RegExp. Wenn gesetzt, läuft Autocapture nur auf URLs, die mindestens einem Eintrag entsprechen. |
url_ignorelist | Array aus Strings oder RegExp. Autocapture wird auf passenden URLs übersprungen. |
element_allowlist | Array kleingeschriebener Tag-Namen. Nur Elemente mit diesen Tags werden erfasst. |
css_selector_allowlist | Array von CSS-Selektoren. Nur passende Elemente werden erfasst. |
window.adverfly = window.adverfly || [];
window.adverfly.autocapture_config = {
url_ignorelist: [/\/admin/, "/debug"],
css_selector_allowlist: [".track-me", "[data-adv-track]"],
};
advPxl("init", 8397799);
Rate-Limiting
Eingebaute Limits schützen deine Seite und dein Event-Kontingent:
- Global: max. 30 Autocapture-Events pro Sekunde.
- Pro Element: mindestens 500 ms zwischen Events am selben Element.
- Rage-Click: 1 s Cooldown pro Element nach einem
$rageclick.
Google Tag Manager
Adverfly via Google Tag Manager installieren
Du kannst den Adverfly-Pixel über Google Tag Manager installieren — leichter zu pflegen.
Installations-Schritte
- Öffne deinen GTM-Container
- Erstelle ein neues Tag
- Wähle Custom HTML
- Füge folgenden Code ein:
<script>
window.adverfly = window.adverfly || [];
function advPxl() {
var args = [false];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
adverfly.push(args);
}
advPxl("init", DEINE_WORKSPACE_ID);
window.adverfly.store_currency = "EUR";
window.adverfly.store_timezone = "Europe/Berlin";
var script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.src = "https://sos-de-fra-1.exo.io/adv/advv2.01.js";
document.getElementsByTagName("head")[0].appendChild(script);
</script>
- Setze den Trigger auf All Pages
- Speichern und veröffentlichen
Konfiguration
| Code | Description |
|---|---|
store_currency | Basiswährung deines Shops. Transaktionen in anderen Währungen werden automatisch umgerechnet. |
store_timezone | Zeitzone deines Shops für genaue Event-Zeitstempel in Reports. |
Conversions via Data Layer tracken
Wenn du den Data Layer für E-Commerce-Events nutzt:
<script>
// Dieses Tag sollte auf der Bestätigungs-Seite feuern
advPxl("conversion", "purchase", {
transaction_id: {{DL - Transaction ID}},
transaction_gross_revenue: {{DL - Revenue}} * 100,
transaction_currency: {{DL - Currency}}
});
</script>
Custom-Events tracken
Lege weitere Tags für eigene Events an:
<script>
// Add-to-Cart-Tag — Trigger auf add_to_cart-Event
advPxl("event", "add_to_cart");
</script>
<script>
// Initiated-Checkout-Tag — Trigger auf Checkout-Start
advPxl("event", "initiated_checkout");
</script>
Empfohlene Trigger
| Code | Description |
|---|---|
Base Pixel | All Pages |
Purchase Conversion | purchase-Event / Thank-you-Page |
Add to Cart | add_to_cart-Event |
Initiated Checkout | initiated_checkout-Event |
Shopify-Integration
Adverfly in deinem Shopify-Store installieren
Adverfly integriert sich nativ über Shopifys Customer-Events-API für genaues Tracking. Wenn du zusätzlich Personalisierungs-Widgets (Popups, Banner, Countdowns, Toasts) auf deinem Storefront ausspielen willst, ist ein zweiter winziger Schritt nötig — siehe „Optional: Widgets aktivieren" unten auf der Seite.
Installations-Schritte
- Gehe zum Shopify-Admin
- Navigiere zu Settings → Customer events
- Klicke auf Add custom pixel
- Nenne ihn „Adverfly“
- Füge folgenden Code ein:
const script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.src = "https://sos-de-fra-1.exo.io/adv/script-shopify.js";
document.getElementsByTagName("script")[0].parentNode.appendChild(script);
window.adverfly_web_pixel = true;
window.adverfly_init = init;
window.adverfly_browser = browser;
window.adverfly_settings = api.settings;
window.adverfly = window.adverfly || [];
window.advPxl = function () {
adverfly.push([false, ...arguments]);
};
analytics.subscribe("all_events", (event) => {
window.adverfly.push(["all_shopify_events", event]);
advPxl("init", DEINE_WORKSPACE_ID);
window.adverfly.store_currency = "EUR";
window.adverfly.store_timezone = "Europe/Berlin";
if (event.name === "page_viewed") {
advPxl("check", "vikeys", event);
}
});
Ersetze DEINE_WORKSPACE_ID mit deiner Workspace-ID und setze Währung sowie Zeitzone deines Shops.
Konfiguration
| Code | Description |
|---|---|
store_currency | Basiswährung deines Shops. Transaktionen in anderen Währungen werden automatisch umgerechnet. |
store_timezone | Zeitzone deines Shops für genaue Event-Zeitstempel in Reports. |
Getrackte Events
Die Shopify-Integration trackt automatisch alle Standard-E-Commerce-Events:
| Code | Description |
|---|---|
page_viewed → pageview | Shopify-page_viewed-Event, in Adverfly als pageview erfasst |
product_added_to_cart → add_to_cart | Shopify-Add-to-Cart-Event, in Adverfly als add_to_cart erfasst |
checkout_started → initiated_checkout | Shopify-Checkout-Start, in Adverfly als initiated_checkout erfasst |
checkout_completed → purchase | Shopify-Purchase-Event, in Adverfly als purchase-Conversion erfasst |
Optional: Widgets aktivieren
Der Shopify-Web-Pixel oben läuft in einer Sandbox und kann zwar Events tracken, aber kein UI im Storefront rendern. Um Adverfly-Personalisierungs-Widgets (Popups, Banner, Countdowns, Toasts) zu aktivieren, ergänzt du ein zweites kleines Snippet in deinem Theme — gleiches Muster wie Google Analytics oder jedes andere Tag.
- Gehe in deinem Shopify-Admin auf Online Store → Themes → ⋯ → Edit code
- Öffne
layout/theme.liquid - Füge das Folgende direkt vor
</head>ein:
<script async src="https://cdn.adverfly.com/preset-pixel-adv.js"></script>
<script>
window.adverfly = window.adverfly || [];
window.adverfly.activate_widgets = true;
advPxl("init", YOUR_WORKSPACE_ID);
</script>
Der Theme-Pixel erkennt automatisch dass er auf Shopify läuft und feuert keine Pageview-/Vikey-Events — dafür ist der Web-Pixel oben zuständig. Der Theme-Pixel existiert nur, um Widgets im Storefront-DOM zu rendern. Keine doppelten Events.
Wer nur Tracking will (keine Widgets), kann diesen Abschnitt überspringen. Der Web-Pixel deckt Tracking allein ab.
Personalization SDK
Headless JS-SDK — Adverfly-Widgets mit eigenen Komponenten rendern
Das @adverfly/sdk JavaScript-Paket holt für jeden Besucher die passende Variante und du renderst sie wie du willst — eigene React/Vue/Svelte-Komponenten, server-gerenderte HTML, sogar Mobile-Apps.
Der Standard-Pixel funktioniert weiterhin als No-Code-Lösung. Das SDK ist für:
- Pixelgenaue Brand-Kontrolle — kein iframe, keine CSS-Overrides
- Server-Side / Edge — Cloudflare Workers, Vercel Edge, Next.js Server Components
- Custom UI — Inline-Blocks, Mobile Screens, alles jenseits von Popup/Banner/Toast/Countdown
- Strikte Typen — dein
config-Shape wird zum TypeScript-Generic
Installation
Drei Wege, gleicher Code — wähle was zu deinem Stack passt.
Vanilla <script> (kein Build-Schritt)
<script src="https://cdn.jsdelivr.net/npm/@adverfly/sdk/dist/adverfly.iife.js"></script>
<script>
const adv = new Adverfly({ workspaceId: 188334 });
/* `Adverfly` ist jetzt eine globale Klasse — kein Module-System nötig. */
</script>
In Production die Version pinnen: @adverfly/sdk@0.1.0/dist/adverfly.iife.js.
ES-Module im Browser
<script type="module">
import { Adverfly } from "https://cdn.jsdelivr.net/npm/@adverfly/sdk/dist/index.mjs";
const adv = new Adverfly({ workspaceId: 188334 });
</script>
npm (Build-Pipelines, Node, SSR)
npm install @adverfly/sdk
import { Adverfly } from "@adverfly/sdk";
Funktioniert in Browsern und Node 18+. Keine Peer-Dependencies. Bundle ~6 KB minified im IIFE-Build, ~12 KB als ESM-Build.
Quick Start
import { Adverfly } from "@adverfly/sdk";
const adv = new Adverfly({ workspaceId: 188334 });
await adv.identify({ email: "user@example.com" });
adv.setContext({
cart_value: 49.9,
last_viewed_creatives: ["sku_a", "sku_b"],
});
const variant = await adv.personalize({ trigger: "exit_intent" });
if (variant) {
zeigeMeinPopup({
title: variant.config.title,
copy: variant.config.copy,
onCtaClick: () => adv.click(variant.id),
onDismiss: () => adv.dismiss(variant.id),
});
await adv.trackImpression(variant.id);
}
Konstruktor
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | number | Required | Deine Adverfly-Workspace-ID. |
apiUrl | string | Optional | Override für Self-Hosted oder Staging. Default: https://b.adverfly.com. |
customerId | string | Optional | Vor-identifizieren ohne identify() aufzurufen. |
debug | boolean | Optional | Decisions + Events in console.log spiegeln, getaggt mit [adverfly]. |
manualIdentity | boolean | Optional | Auto-Anonymous-ID deaktivieren (für SSR / wenn du Identität selbst verwaltest). |
Identität
await adv.identify({
email: "user@example.com", // SHA-256 gehasht (lowercase) — nie roh übertragen
transactionId: "order_123", // optional, für Post-Purchase-Trigger
});
Identität zurücksetzen (z. B. bei Logout):
adv.reset();
Personalize
const variant = await adv.personalize<MyConfigShape>({
trigger: "exit_intent",
surface: "widget", // optional, default: "widget"
context: { device_battery_low: true }, // wird oben auf den Session-Context gemerged
});
// { id, config, reason } | null
Stark typisierter Config:
interface PopupConfig {
title: string;
copy: string;
cta?: string;
cta_url?: string;
image_url?: string;
}
const variant = await adv.personalize<PopupConfig>({ trigger: "exit_intent" });
if (variant) {
console.log(variant.config.title); // typisiert!
}
Tracking
Alle Tracking-Events landen in ClickHouse pixel_events — gleiche Tabelle wie der Standard-Pixel, joinbar via customer_id (gehasht) für Conversion-Attribution.
| Code | Description |
|---|---|
trackImpression(variantId) | Widget wurde gerendert. |
click(variantId, props?) | User klickte CTA. props kann cta_url enthalten. |
dismiss(variantId) | User hat manuell geschlossen. |
autoDismissed(variantId, reason?) | Timer abgelaufen (Countdown, Toast). |
success(variantId, props?) | Goal erreicht. Wenn props.email gesetzt, automatisch gehasht vor Versand. |
Events
Subscriben für Analytics, Debugging oder Custom-Render-Hooks.
const off = adv.on("decision", ({ trigger, variant }) => {
console.log(`[${trigger}] →`, variant?.id ?? "no match");
});
/* Returns Unsubscribe-Funktion */
off();
Verfügbare Events: decision, impression, click, dismiss, auto_dismissed, success, error.
Server-Side / Edge
Funktioniert überall wo fetch + crypto.subtle existieren (Node 18+, Bun, Cloudflare Workers, Vercel Edge).
/* Cloudflare Worker — server-render einen personalisierten Hero-Block */
export default {
async fetch(request: Request) {
const adv = new Adverfly({
workspaceId: 188334,
manualIdentity: true, // wir verwalten Identität selbst
});
await adv.identify({ customerId: getCookieUserId(request) });
const variant = await adv.personalize({
trigger: "ssr_hero",
context: { country: request.cf?.country },
});
return new Response(renderHero(variant?.config), {
headers: { "content-type": "text/html" },
});
},
};
Privacy
- Emails werden clientseitig gehasht (SHA-256, lowercase + getrimmt) bevor irgendein Network-Call passiert.
- Keine Cookies vom SDK gesetzt. Anonymous-IDs in
localStorage; Opt-out viamanualIdentity: true. - CORS-clean. POST + JSON, keine Preflight-Überraschungen.
Siehe auch
- Widgets — die No-Code-Pixel-Variante
- Tracking-Events — Basis-Event-Schema
Heat Maps & Session Replays
Enable click/scroll capture and session recording in the tracking pixel
The v4 tracking pixel can capture on-page interactions for the Heat Maps app and record full sessions for the Session Replays app. Both are off by default and enabled per site with one flag each in your pixel snippet.
Heat Maps
<script>
window.adverfly = window.adverfly || [];
advPxl("init", YOUR_WORKSPACE_ID);
window.adverfly.activate_heatmap = true;
</script>
What gets captured:
- Clicks — position (relative to document size, so all viewports aggregate correctly), the clicked element's selector, and up to 60 characters of its text.
- Scroll depth — one max-depth summary per pageview.
Events are batched client-side and sent through the regular beacon endpoint. SPA route changes (pushState / popstate) are handled automatically.
Session Replays
<script>
window.adverfly = window.adverfly || [];
advPxl("init", YOUR_WORKSPACE_ID);
window.adverfly.activate_session_replay = true;
/* Optional tuning */
window.adverfly.replay_config = {
sample_rate: 0.25, /* record 25% of sessions (default 1) */
mask_selectors: [".account-menu"], /* extra elements whose text is masked */
max_duration_s: 1800, /* hard stop per session (default 30 min) */
};
</script>
The recorder is built on rrweb — the open-source engine behind most session-replay products. It is lazy-loaded only when recording actually starts, takes a DOM snapshot, then streams mutations, mouse movement, clicks, scrolls, and viewport changes in chunks to api.adverfly.com/replays/v1.
Privacy guarantees (always on)
- Input, textarea, and select values are masked in the browser — real values never leave the page. Password and credit-card fields are fully redacted.
- Elements with
class="adv-no-capture"ordata-adv-no-captureare dropped entirely from the recording. - Elements with
class="adv-mask"ordata-adv-maskkeep their layout but have all text masked. script,iframe,canvas,video, andaudioelements are replaced by sized placeholders.- If a supported consent tool (Cookiebot, OneTrust, Usercentrics, TCF) reports consent as denied, the recorder does not start.
Recording both apps reuses the same session key, so heatmap data and replays line up per session.