Skip to main content
Page Events is a flow graph attached to a page. You connect triggers, conditions and actions, and the platform runs them — some before the HTML is sent, some in the visitor’s browser after load. It is what powers whitelisting, dynamic content, component split tests, exit popups, merchant switching and video CTAs. Open it from Pages → (your page) → Manage Page Events.

Node reference

Every node type, its fields, and its wiring constraints

The graph model

Nodes, connections, entry views, and how it is stored

Server vs browser

Which nodes run before the page is sent, and which run after

Patterns

Worked examples and troubleshooting

The graph model

A page’s events are a directed graph of nodes. Every node has:
  • a type (data.type) — the real identity of the node, e.g. script_rule, dynamic_container, component_split_test
  • a node code (data.node_code) — a short stable identifier used by analytics and split-test reporting
  • input and output pinsinput_1, output_1, output_2… Connections are stored on both ends, so a link appears in the source node’s outputs.output_N.connections and in the target’s inputs.input_M.connections.
  • a position on the canvas (pos_x, pos_y)

Reading a branch

Outputs are ordered, and the order is the meaning:
  • Output 1 — the first pin. For a condition node this is the true / Yes branch.
  • Output 2 — the second pin. For a condition node this is the false / No branch.
Every node except Sequence follows one connection per output. If you need two actions on the same branch, either chain them (most actions have an output that continues the flow) or use a Sequence node and add an output per action.

Entry views

Every flow starts from an entry node (the node labelled Loaded). A page may have several. Each entry node appears as a View in the left rail of the builder. You can name it (pencil icon), reorder the list by dragging, and each view remembers its own camera position on the canvas. The order is saved as entry_views_order.
Views are a canvas organisation feature, not a routing feature. At render time the platform collects the children of every entry node and runs them all — it does not choose one view. entry_views_order affects the builder only. If two views must be mutually exclusive, put the choice behind a condition.

Global page events

Alongside per-page events, a brand has one Global Page Events graph — open it with Manage Global Page Events in the builder toolbar. Global events are merged into every page’s flow and are ordered ahead of the page’s own events. Use them for brand-wide concerns (cloaking, IP rules, universal tagging) instead of copying the same nodes onto every page.

Where it is stored

Page events are loaded and saved through:
Use global in place of the page ID for the brand-wide graph. Save is POST only — there is no PUT, and these are session-authenticated app endpoints, not public API-key endpoints. The response body is the builder’s export:
When a page has no events yet, GET .../events returns 200 with an empty body — not {} and not 404. Handle that case if you are reading the endpoint programmatically.
On save, the platform compiles the graph into a flattened execution tree, assigns node_codes where missing, and creates or updates the split-test records referenced by any split_test / component_split_test node.

Server vs browser

Each node declares where it can run. The platform splits your graph into a server pass and a browser payload. How the split is decided: a branch is sent to the browser if it — or anything below it — is a browser-only node. Certain nodes are pinned to the server even when they have browser children (script_rule, page_variant, product_check, cloaking_house, is_whitelisted, url_redirect, set_variable, set_checkout_bumps, block_request, split_test, execute_automation). When such a node picks a branch that belongs to the browser, the server hands that branch over to the browser payload and stops there.
Order matters and it is one-directional. Server → browser works (script_ruleclient_script). Browser → server does not (exit_intentscript_rule). Put every server-side decision before the first browser node on a path.
Browser events are serialised into the page as window.page_events and executed by the funnel runtime script. Save your flow and reload the page to pick up changes.

Node catalogue

The full list — purpose, fields, inputs/outputs and constraints for every node — lives in the Page Events Node Reference. Quick orientation:
Loaded (entry) · Router · Sequence · Stop Next Events Execution
Script Rule · Query Parameter Condition · Is Customer · Has Purchased Any Upsell · Referred By Affiliate · Is From Country / State / EU / Timezone · Is Using VPN/Proxy · Is Whitelisted? · Has Tag · Cloaking.house · Product Check (+ Match Product / Match All)All of these compile to a script and take the true branch on Output 1.
On Exit Intent · On Form Success · On Add To Cart · CTA: On Shown · When scrolled to · Scroll Check · Element In View · If Showed CTA · If Added To Cart · Video: Is muted / On Pause / On Goal Reached / Progress Check
Dynamic Content · Load Another Page · Redirect to Page · Redirect to URL · Show Popup · Show / Hide Element · Show / Hide Video CTA · Wait Seconds · Execute Javascript on Client
Tag User · Whitelist visitor · Mark visitor as NOT whitelisted · Set Merchant · Clear Merchant · Set Checkout Page · Set Checkout Bumps · Set Variable · Execute Automation on Customer · Block Request
Component Split Test · Split Test · Traffic Distribution · ComponentSee Split Testing for the full wiring.
Nodes are filtered by permission. If a node is missing from Add Node, your role probably lacks its permission — for example split-test nodes need split_tests.create / split_tests.update, and Set Checkout Bumps only appears on pages flagged as checkout pages.

Common patterns

Whitelisting from a URL parameter

  1. LoadedQuery Parameter Condition (vtID, operator is not empty)
  2. Output 1 → Whitelist visitor (0 minutes = permanent)
  3. Output 2 → leave empty, or route to compliant content

Blocking traffic outside a country

  1. LoadedIs From Country with US selected
  2. Output 1 (true) → leave empty
  3. Output 2 (false) → Block Request with your message
Attach Block Request to the specific output of the condition. Dropping it directly under the entry node blocks every visitor.

Merchant by traffic source

  1. LoadedQuery Parameter Condition (source is partner1) → Output 1 → Set Merchant
  2. Output 2 → a second Query Parameter Condition (source is partner2) → Output 1 → Set Merchant
  3. Output 2 → nothing; the domain default applies
Use Clear Merchant to explicitly return to the domain default.

Video: pause, then show the CTA

  1. Video: On PauseVideo: Progress Check (30%)
  2. Output 1 → Wait Seconds (2) → Show Video CTA (with Scroll to CTA if you want the page to jump)
  3. Output 2 → nothing

Swapping content for one affiliate

  1. LoadedReferred By Affiliate (pick the affiliate)
  2. Output 1 → Dynamic Content → container pricing, component affiliate-pricing
  3. Output 2 → nothing; the container’s default content renders
See Dynamic Content.

Best practices

  • Prefer the purpose-built condition over a Script Rule. Is From Country, Is Using VPN/Proxy, Query Parameter Condition and friends are readable at a glance and self-documenting. Save Script Rule for logic they cannot express.
  • Combine instead of nesting. One Is From Country with three countries beats three chained nodes. If a chain would be three levels deep, write one Script Rule.
  • Put server decisions first. Everything that routes, cloaks or selects content should run before the first browser node.
  • Name your split tests and variants. Those names are what you read in analytics later.
  • Use views to keep the canvas readable, not to separate behaviour — every view runs.
Use Rearrange in the toolbar to auto-layout the canvas, then save. Camera position is stored per view, so each one reopens where you left it.

Troubleshooting

Save the flow and reload the page — browser nodes are shipped with the HTML, so an unsaved change is not live. Then check that the branch is actually reachable: a node wired to nothing, or attached below a condition whose other branch is being taken, will not run.
Check which output you attached to. Output 1 is true, Output 2 is false. This trips people up most often with Block Request and Load Another Page.
Every node except Sequence allows one connection per output. Add a Sequence node and give it an output per action, or chain the actions.
The builder enforces parent restrictions. Component only attaches to Traffic Distribution; Traffic Distribution only to a split-test node; Video: Is muted only below On Exit Intent; Product Check: Match Product/All only below Product Check. See wiring rules.
A Component Split Test ends its branch after swapping the container. Wire follow-up work before it, not after it.
Open the Debug WindowPage Events tab. It shows each Script Rule’s result, execution time, console output and the full data it received. Remember that parameter names and values are case-sensitive.
The container list is read from the page itself. On builder pages the container must be a Split Test Container / Dynamic Container block with its name trait filled in; on coded pages the tag must be written as <split-test id="…" name="…"> with id immediately before name. Click the reload icon next to the dropdown after saving the page.

Node Reference

Script Rule

Query Parameters

Dynamic Content

Split Testing

Sequence Nodes

Exit Popups

Window API

Page Variants

Debug Window