Skip to content

Events

Every popup stage records four event types as the visitor interacts with it. Events are recorded server-side as an append-only log; nothing is updated after insertion. Per-stage opt-out and retention rules let you control storage growth and respect privacy preferences.

The stage mounted on the page and the visitor saw it. Recorded once per show — if a popup with frequency = always shows 5 times across 5 page loads, you’ll see 5 impression rows.

The visitor clicked a CTA inside the stage. “CTA” is broad: any button-layer click, or any layer with Click action enabled (URL / Close / Scroll-to-selector). Clicking the close X is not a CTA click — see close below.

The visitor closed the popup via the X button or the overlay click. Recorded once per dismissal.

The visitor clicked the Don’t show again button. This is the strongest dismissal signal — it tells you the visitor explicitly opted out of seeing this popup ever again, not just for this visit. Distinguish from close for funnel analysis.

Each event carries:

ColumnSourceNotes
iduuidPrimary key.
popup_idstage idFK to p2lab_stage.
event_typeimpression / cta_click / close / permanent_dismiss
sales_channel_idserver contextFK to sales_channel.
customer_idserver contextNullable. Set only for logged-in visitors.
page_typeclient payloadE.g. product, category.
request_urlclient payloadFull request path.
created_atserverUTC, no updated_at (append-only).

No PII beyond customer ID (when logged in). No IP address, no user-agent string, no session ID. The plugin owns the entry-points so you can audit exactly what’s stored.

The storefront JS plugin sends events via POST /p2lab-stage/track:

{
"popupId": "<uuid>",
"eventType": "impression",
"pageType": "product",
"requestUrl": "/product/spring-jacket"
}

The endpoint:

  1. Validates popupId + eventType (returns 400 if missing).
  2. Checks the stage’s statsEnabled flag — if off, silently no-ops (defensive backstop; the client already skips most calls for disabled stages).
  3. Records the event.
  4. On impression, also updates the visitor’s per-session shown-popup counter (used by the maxPerSession cap).

Each stage has a Track statistics toggle in the Overview tab → Statistics card. Help text: “Track impressions, CTA clicks, closes and dismissals for this stage.”

When off:

  • The storefront JS still tries to call /p2lab-stage/track for backwards-compatibility, but the controller silently no-ops on statsEnabled = false.
  • No events are recorded for this stage.
  • The Stats tab of the stage’s detail page shows zeros (or whatever was recorded before the toggle was flipped).

Use this for stages where you don’t care about metrics (a permanent test stage, an internal-only stage) or where retention rules would create more rows than you want to store.

Each stage has a Retention (days) field on the Overview tab (default 90, 0 = forever). Events older than this are pruned by a scheduled cleanup task.

When set to 0, events are kept forever — useful for compliance audits, but the table grows unbounded. Set explicitly if you need a hard ceiling.

Retention is per-stage so you can keep a long history for the campaigns you care about and aggressively prune the ones you don’t.

The admin Stats tab fetches aggregated counts via POST /api/_action/p2lab-stage/stats:

Payload:

{
"popupId": "<uuid>",
"dateFrom": "2026-04-01",
"dateTo": "2026-04-30"
}

Response: aggregated event counts per type + a time-bucketed series for the chart.

Date range is optional; omit both for “all time”.

  • Customer ID is recorded only for logged-in visitors. Anonymous visitors leave a row with customer_id = NULL.
  • No IP, no UA, no session ID — by design.
  • PHP session is used for frequency suppression, not analytics — see Storefront → GDPR & storage.
  • If you need to comply with GDPR right-to-erasure, the customer_id foreign key cascades on deletion: deleting the customer removes their event rows (or sets them to NULL, depending on how Shopware’s customer-delete pipeline is configured).