The Upstack JavaScript SDK provides client-side event tracking, user identification, and session management. It captures browsing behavior, resolves user identity across devices, and forwards events to your configured destinations.
Important: The correct global is window._upstack() (with underscore), not window.upstack(). Older documentation may reference the incorrect name.
Installation
The Upstack pixel is distributed via CDN, not npm. Add this snippet to your site’s <head>:
< script >
window . _upstack = window . _upstack || function () {
( window . _upsqueue = window . _upsqueue || []). push ( arguments );
};
_upstack ( 'init' , 'YOUR_PIXEL_ID' );
</ script >
< script async src = "https://prod2-cdn.upstackified.com/scripts/px/ups.min.js" ></ script >
Why this works:
The inline script defines _upstack() as a function that pushes calls to a queue
Calls made before the SDK loads are queued — no events are lost
Once the SDK loads, it processes the queue and replaces _upstack() with the real implementation
Safe to call immediately without checking load status
API Overview
Method Via Queue Via Direct Client Description init✅ (pixelId only) ✅ Initialize the pixel page✅ ✅ Track page views track✅ ✅ Track custom events identify✅ ✅ Associate user identity metric✅ ✅ Send metrics (currently disabled) reset✅ ✅ Clear identity state isKnown❌ ✅ Check if user is identified getUpstackId❌ ✅ Get Upstack ID object
Queue Commands
These methods can be called via _upstack('command', ...) before or after the SDK loads.
init(pixelId)
Initialize the Upstack pixel with your pixel ID.
function init (
pixelId : string ,
identityTraits ?: EventIdentityTraits ,
scriptSource ?: 'js' | 'shopify_js' | 'shopify_ext'
) : Promise <{ isInitialized : boolean ; isDisabled : boolean }>
Parameters:
Parameter Type Required Description pixelIdstringYes Your Upstack pixel ID from the dashboard (starts with px_) identityTraitsEventIdentityTraitsNo Pre-populate identity on init scriptSourcestringNo Script origin: 'js' (default), 'shopify_js', 'shopify_ext'
Queue Limitation: When using _upstack('init', pixelId, identityTraits, scriptSource), only pixelId is passed to the init function. The identityTraits and scriptSource parameters are dropped by the queue processor.For full init with identity traits, use the direct client after the script loads.
Examples:
// Basic initialization via queue (recommended)
_upstack ( 'init' , 'px_abc123def456' );
// Full init with identity traits (requires direct client)
// Wait for script to load first
if ( window . _upsClient ) {
await window . _upsClient . init ( 'px_abc123def456' , {
emails: [ 'user@example.com' ]
}, 'js' );
}
page(eventData?)
Track a page view. Automatically captures page URL, title, referrer, and path.
function page ( eventData ?: Record < string , unknown >) : void
Parameters:
Parameter Type Required Description eventDataobjectNo Custom properties to include with the page view
Auto-captured properties:
page_url — Current page URL
page_title — Document title
page_referrer — Referring URL
page_path — URL path
Examples:
// Basic page view
_upstack ( 'page' );
// With custom properties
_upstack ( 'page' , {
page_category: 'product' ,
product_id: 'SKU123' ,
collection: 'summer-2026'
});
track(eventName, eventData?, …)
Track a custom event. Supports 7 positional parameters plus a shorthand for useBeacon.
function track (
eventName : string ,
eventData ?: Record < string , unknown >,
eventId ?: string ,
contextOverride ?: Record < string , unknown >,
collectedAt ?: string , // ISO 8601 timestamp
collectedAtEpoch ?: number , // Unix epoch milliseconds
options ?: TrackOptions
) : void
interface TrackOptions {
useBeacon ?: boolean ; // Use navigator.sendBeacon() for page unload
}
Parameters:
Parameter Type Required Description eventNamestringYes Event name in snake_case (e.g., 'add_to_cart', 'purchase') eventDataobjectNo Event properties eventIdstringNo Unique ID for deduplication across destinations contextOverrideobjectNo Override page/session context for this event collectedAtstringNo ISO 8601 timestamp for backdated events collectedAtEpochnumberNo Unix epoch milliseconds for backdated events optionsTrackOptionsNo { useBeacon: boolean } for page unload tracking
Shorthand for useBeacon:
When the 4th argument is an object with useBeacon, it’s treated as options:
// Shorthand (recommended for useBeacon)
_upstack ( 'track' , 'lead' , { email: 'user@example.com' }, { useBeacon: true });
// Full positional form (7 parameters)
_upstack ( 'track' , 'lead' , { email: 'user@example.com' }, null , null , null , null , { useBeacon: true });
Examples:
// Basic tracking
_upstack ( 'track' , 'add_to_cart' , {
items: [{ id: 'SKU123' , name: 'Widget' , price: 29.99 , quantity: 1 }],
value: 29.99 ,
currency: 'USD'
});
// With deduplication ID (prevents duplicate events at destinations)
_upstack ( 'track' , 'purchase' , {
items: [{ id: 'SKU123' , name: 'Widget' , price: 29.99 , quantity: 1 }],
value: 29.99 ,
order_id: 'ORD-456' ,
currency: 'USD'
}, 'ORD-456' );
// Backdated event (server-side timestamp)
_upstack ( 'track' , 'server_event' , {
value: 50
}, null , null , '2026-06-01T12:00:00Z' );
// Page unload with beacon (using shorthand)
window . addEventListener ( 'visibilitychange' , () => {
if ( document . visibilityState === 'hidden' ) {
_upstack ( 'track' , 'page_exit' , {
time_on_page_seconds: Math . round (( Date . now () - pageLoadTime ) / 1000 )
}, { useBeacon: true });
}
});
identify(userId?, data?)
Associate user identity with the current session. Used for cross-device tracking and destination matching.
function identify (
userId ?: string | null ,
data ?: EventIdentityTraits
) : void
interface EventIdentityTraits {
emails ?: string []; // Array of email addresses
phones ?: string []; // Array of phone numbers (E.164 format preferred)
firstName ?: string ;
lastName ?: string ;
address ?: {
city ?: string ;
state ?: string ;
zip ?: string ;
country ?: string ;
};
}
Parameters:
Parameter Type Required Description userIdstring | nullNo Your internal user ID. Pass null for anonymous identification with traits only. dataEventIdentityTraitsNo Identity traits with emails[] and phones[] as arrays
Important: emails and phones are arrays, not single values. This supports users with multiple contact methods.
Examples:
// With userId only
_upstack ( 'identify' , 'user-456' );
// With full profile
_upstack ( 'identify' , 'user-456' , {
emails: [ 'jane@example.com' , 'jane.doe@work.com' ],
phones: [ '+15551234567' ],
firstName: 'Jane' ,
lastName: 'Doe' ,
address: {
city: 'Austin' ,
state: 'TX' ,
zip: '78701' ,
country: 'US'
}
});
// Traits only (Shopify path — userId is null)
_upstack ( 'identify' , null , {
emails: [ 'customer@example.com' ]
});
// After form submission
document . querySelector ( 'form' ). addEventListener ( 'submit' , ( e ) => {
const email = e . target . querySelector ( '[name="email"]' ). value ;
_upstack ( 'identify' , null , { emails: [ email ] });
});
metric(metricName, metricValue, metricData?, metricId?)
Send a custom metric value.
function metric (
metricName : string ,
metricValue : number ,
metricData ?: Record < string , unknown >,
metricId ?: string
) : null
Currently Disabled: The metric() method is routed through the queue but returns null — metric forwarding is disabled in the public SDK. This method exists for future use.
Parameters:
Parameter Type Required Description metricNamestringYes Metric name metricValuenumberYes Numeric value metricDataobjectNo Additional context metricIdstringNo Unique ID for deduplication
Example:
// Currently returns null — metric forwarding disabled
_upstack ( 'metric' , 'page_load_time' , 1250 , {
page: '/checkout'
});
reset()
Clear identity, session data, event listeners, and hooks. Call when a user logs out.
Example:
function handleLogout () {
_upstack ( 'reset' );
window . location . href = '/login' ;
}
Direct Client Methods
These methods are only available via window._upsClient after initialization completes. They cannot be called through the _upstack() queue.
isKnown()
Check if the current user has been identified.
function isKnown () : Promise < boolean >
Returns: Promise resolving to true if the user has been identified, false otherwise.
Direct Client Only: This method is NOT available via the _upstack() queue. You must call it directly on window._upsClient.
Example:
// After init completes
const isKnown = await window . _upsClient . isKnown ();
if ( ! isKnown ) {
showEmailCapturePopup ();
}
getUpstackId()
Retrieve the Upstack identity object for the current user.
interface UpstackId {
_upstackId ?: string ; // Persistent user ID
_upstackSid ?: string ; // Session ID
_upstackIp ?: string ; // IP address (if available)
}
function getUpstackId () : Promise < UpstackId >
Returns: Promise resolving to an UpstackId object (not a string).
Direct Client Only: This method is NOT available via the _upstack() queue. You must call it directly on window._upsClient.Return Type: Returns an object with identity fields, not a single string ID.
Example:
// After init completes
const upstackId = await window . _upsClient . getUpstackId ();
console . log ( 'Upstack ID:' , upstackId . _upstackId );
console . log ( 'Session ID:' , upstackId . _upstackSid );
// Use for server-side API calls
fetch ( '/api/track' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({
upstack_id: upstackId . _upstackId ,
event: 'server_purchase' ,
value: 99.99
})
});
Waiting for SDK Ready
When using direct client methods, ensure the SDK has loaded:
function onUpstackReady ( callback ) {
if ( window . _upsClient && window . _upsClient . _initialized ) {
callback ();
} else {
const interval = setInterval (() => {
if ( window . _upsClient && window . _upsClient . _initialized ) {
clearInterval ( interval );
callback ();
}
}, 100 );
}
}
// Usage
onUpstackReady ( async () => {
const isKnown = await window . _upsClient . isKnown ();
if ( isKnown ) {
const upstackId = await window . _upsClient . getUpstackId ();
console . log ( 'User ID:' , upstackId . _upstackId );
}
});
Common Patterns
SPA Navigation Tracking
Track page views on route changes in single-page applications:
// React Router
import { useEffect } from 'react' ;
import { useLocation } from 'react-router-dom' ;
function usePageTracking () {
const location = useLocation ();
useEffect (() => {
_upstack ( 'page' , {
page_path: location . pathname ,
page_search: location . search
});
}, [ location ]);
}
// Next.js App Router
'use client' ;
import { usePathname , useSearchParams } from 'next/navigation' ;
import { useEffect } from 'react' ;
export function Analytics () {
const pathname = usePathname ();
const searchParams = useSearchParams ();
useEffect (() => {
_upstack ( 'page' , {
page_path: pathname ,
page_search: searchParams . toString ()
});
}, [ pathname , searchParams ]);
return null ;
}
E-commerce Funnel
Track the complete customer journey:
// Product view
_upstack ( 'track' , 'view_content' , {
items: [{ id: 'SKU123' , name: 'Widget' , price: 29.99 }]
});
// Add to cart
_upstack ( 'track' , 'add_to_cart' , {
items: [{ id: 'SKU123' , name: 'Widget' , price: 29.99 , quantity: 1 }],
value: 29.99 ,
currency: 'USD'
});
// Begin checkout
_upstack ( 'track' , 'initiate_checkout' , {
items: [{ id: 'SKU123' , name: 'Widget' , price: 29.99 , quantity: 1 }],
value: 29.99 ,
currency: 'USD'
});
// Purchase (with deduplication ID)
_upstack ( 'track' , 'purchase' , {
items: [{ id: 'SKU123' , name: 'Widget' , price: 29.99 , quantity: 1 }],
value: 29.99 ,
order_id: 'ORD-456' ,
currency: 'USD'
}, 'ORD-456' );
Page Exit Tracking with Beacon
Reliably track time on page even when the user closes the tab:
let pageLoadTime = Date . now ();
window . addEventListener ( 'visibilitychange' , () => {
if ( document . visibilityState === 'hidden' ) {
const timeOnPage = Math . round (( Date . now () - pageLoadTime ) / 1000 );
_upstack ( 'track' , 'page_exit' , {
time_on_page_seconds: timeOnPage ,
page_path: window . location . pathname
}, { useBeacon: true });
}
});
Capture leads from newsletter signups:
document . querySelector ( '#newsletter-form' ). addEventListener ( 'submit' , ( e ) => {
e . preventDefault ();
const email = e . target . querySelector ( '[name="email"]' ). value ;
// Identify the user
_upstack ( 'identify' , null , { emails: [ email ] });
// Track the lead event with beacon (in case form navigates away)
_upstack ( 'track' , 'lead' , {
source: 'newsletter_signup' ,
email: email
}, { useBeacon: true });
// Submit the form
e . target . submit ();
});
TypeScript Support
Add type declarations for TypeScript projects:
declare global {
interface Window {
_upstack : ( ... args : unknown []) => void ;
_upsqueue : unknown [];
_upsClient : {
init : ( pixelId : string , identityTraits ?: EventIdentityTraits , scriptSource ?: string ) => Promise <{ isInitialized : boolean ; isDisabled : boolean }>;
page : ( eventData ?: Record < string , unknown >) => void ;
track : ( eventName : string , eventData ?: Record < string , unknown >, eventId ?: string , contextOverride ?: Record < string , unknown >, collectedAt ?: string , collectedAtEpoch ?: number , options ?: TrackOptions ) => void ;
identify : ( userId ?: string | null , data ?: EventIdentityTraits ) => void ;
metric : ( metricName : string , metricValue : number , metricData ?: Record < string , unknown >, metricId ?: string ) => null ;
reset : () => void ;
isKnown : () => Promise < boolean >;
getUpstackId : () => Promise < UpstackId >;
_initialized : boolean ;
};
}
}
interface EventIdentityTraits {
emails ?: string [];
phones ?: string [];
firstName ?: string ;
lastName ?: string ;
address ?: {
city ?: string ;
state ?: string ;
zip ?: string ;
country ?: string ;
};
}
interface TrackOptions {
useBeacon ?: boolean ;
}
interface UpstackId {
_upstackId ?: string ;
_upstackSid ?: string ;
_upstackIp ?: string ;
}
export {};
Methods NOT Available
The following methods are not implemented in the public SDK:
consent — Not implemented
group — Not implemented (stub exists)
screen — Not implemented (stub exists)
alias — Not implemented (stub exists)
Internal methods (do not call directly):
notify — Internal hook messaging
postInit — Internal post-initialization
Pixel Setup Installation guide for non-Shopify websites and SPAs.
Standard Events Complete reference for all standard events with JavaScript snippets.
Properties & Context Reference for item arrays, customer data, and auto-captured fields.
Custom Events Create events beyond the standard taxonomy for your needs.
Identity Resolution How identify() connects sessions to customer profiles.
Shopify Automatic Tracking Events tracked automatically on Shopify stores.