Overview
Arktic works entirely through a JavaScript embed on the storefront and a server-side rollup pipeline. Here is the full data flow from visitor arrival to a result in the dashboard.Visitor identification
Every visitor to your store gets a visitor ID (spt_vid cookie) on their first page view. This is a randomly generated 128-bit token:
Max-Age: 31536000(1 year)Path: /SameSite: LaxSecureon HTTPS
Experiment config delivery
Experiment configuration (which experiments are running, which variants exist, traffic weights) is stored in a Shopify shop metafield and injected into the page by the theme app extension at Liquid render time:Visitor bucketing
Step 1: Traffic allocation check
Before a visitor is assigned to any variant, they are first checked against the experiment’s traffic allocation percentage. This controls what fraction of all visitors enter the experiment:Step 2: Variant assignment
For visitors who pass the allocation check, their variant is determined by a second hash:- Bucket 0-49 → Control
- Bucket 50-99 → Variant B
- Bucket 0-32 → Control
- Bucket 33-65 → Variant B
- Bucket 66-99 → Variant C
FNV-1a hashing
The hash function is FNV-1a 32-bit. It is fast, deterministic, and produces well-distributed values. The same input always produces the same output, which guarantees that the same visitor always gets the same variant even across different page loads and devices (as long as the cookie is present).Assignment persistence
Once a visitor is assigned, their assignments are stored in thespt_asgn cookie as a JSON object:
- The
spt_asgncookie is cleared - The visitor uses a different browser or device (separate cookie jar)
- The experiment is not in the stored assignments (new experiment, or first visit after experiment started)
Variant application
After assignment, the JS applies the variant experience before revealing the page. The method varies by experiment type:| Type | How it is applied |
|---|---|
| Theme | ?preview_theme_id=<id> appended to URL, page reloads with alternate theme |
| URL Redirect | window.location.replace(destinationUrl) — replaces history entry |
| Template | ?view=<suffix> appended to URL — Shopify loads alternate template |
| Section content | HTML injected into the Variant Content block container before page is revealed |
| Price (Plus) | Price elements in DOM updated; cart attribute spt_asgn written for Cart Transform |
| Price (non-Plus) | URL redirect to duplicate product page |
<html> element gets a class spt-loading during assignment, which your theme can use to hide content until assignment is complete. After assignment, it switches to spt-ready.
Event tracking
Three types of storefront events are tracked:PAGE_VIEW
Fires on every page load (afterDOMContentLoaded). Sends:
visitorIdfrom thespt_vidcookie- Current assignments from the
spt_asgncookie - Current page URL
- Device type (based on
window.innerWidth) - Timestamp
ADD_TO_CART
Detected by three methods simultaneously to ensure nothing is missed:- Form submit - intercepts any form submission to
/cart/add - Cart events - listens for
cart:addanditems-addedcustom DOM events (fired by many themes) - Button click - monitors clicks on elements matching standard ATC button selectors
INITIATE_CHECKOUT
Fires when a visitor begins the checkout process. Detected by:- Form submit to
/checkout - Click on checkout button selectors (cart drawer, cart page)
PURCHASE
Not fired by the JS. Purchases are attributed server-side via Shopify’sorders/paid webhook. The webhook reads the spt_vid and spt_asgn values from the order’s cart attributes (written to the cart as hidden properties on every page load) and creates an Order record in the database.
This approach is more reliable than client-side purchase tracking because it fires even when the visitor closes the browser tab before your confirmation page loads.
Order attribution
The JS writes two cart attributes on every page load:note_attributes. When the orders/paid webhook fires, Arktic reads these values and creates an attribution record linking the order to the correct experiment and variant.
Buy It Now buttons are handled separately. Since BIN bypasses the cart, the JS injects hidden <input> fields into product forms with name="properties[spt_asgn]" — these become line item properties on the order and are read during attribution.
Consent handling
Arktic respects Shopify’s Customer Privacy API. Before sending any analytics events (PAGE_VIEW, ADD_TO_CART, etc.), the embed checks:Results rollup
Raw events in the database are aggregated into experiment results by a rollup job that runs every hour. The rollup computes per-variant:- Sessions (unique page views)
- Add to cart events
- Checkout initiations
- Orders and revenue
- Conversion rate (CVR)
- Revenue per visitor
- Average order value
- Statistical significance (p-value via two-proportion z-test)
- Lift vs control