Stagepass

Loader and data-stagepass

Add the loader, tag your assets and use the sp runtime API.

loader 2.3.0cli 2.2.1macOS

Add the loader

Add the loader to Project Settings, Custom Code, Head Code in Webflow and publish once. Use the major pin @2.

Head Code
<script src="https://cdn.jsdelivr.net/npm/@stagepass/loader@2/dist/loader.min.js"></script>

Options go on the loader tag itself:

Head Code
<script
  src="https://cdn.jsdelivr.net/npm/@stagepass/loader@2/dist/loader.min.js"
  data-stagepass-version="2026-11-01"
  data-stagepass-session-hours="24"
></script>

Tag scripts and stylesheets

Replace src or href with data attributes. Without a session, the loader writes the production URL back, so visitors get the same files as before.

Webflow embed
<script
  data-src="https://cdn.example.com/app.min.js"
  data-stagepass="true"
  data-stagepass-path="js/app.js"
></script>
Webflow embed
<link
  rel="stylesheet"
  data-href="https://cdn.example.com/styles.css"
  data-stagepass="true"
  data-stagepass-path="css/styles.css"
>

During a session the loader builds https://<domain>/<path>?_cb=<timestamp>. Scripts get defer unless you set async or defer yourself, and they run in document order.

Attribute reference

AttributeWhereWhat it does
data-stagepassAssetMarks a script or link rel="stylesheet" for Stagepass. Any value counts, use "true" for clarity.
data-srcScriptProduction URL of the script. Loaded for everyone without a session.
data-hrefStylesheetProduction URL of the stylesheet.
data-stagepass-pathAssetPath to the file in your linked folder. Optional. Without it, the file name from the production URL is used.
data-stagepass-vAssetAppends ?v=<value> to the production URL for cache busting. Wins over the loader version.
data-stagepass-versionLoader tagAppends ?v=<value> to every tagged production URL. Bump it when you deploy.
data-stagepass-session-hoursLoader tagSession lifetime in hours. Default 12.
data-stagepass-mute-consoleLoader tagWith "true", mutes the browser console in production while no session is active. Off by default.
data-stagepass-staging-hostsLoader tagComma separated host names that count as staging, in addition to *.webflow.io. Used by sp.env() and sp.vars.env. Optional.
data-stagepass-aliasLoader tagAn extra global name for the API, for example "spx". It must be a valid identifier and is only set when that global is free. Optional.
Head Code
<script
  src="https://cdn.jsdelivr.net/npm/@stagepass/loader@2/dist/loader.min.js"
  data-stagepass-staging-hosts="staging.example.com,preview.example.com"
  data-stagepass-alias="spx"
></script>

Modes and sessions

ParameterResult
?stagepass=my-project.spLocal mode. Tagged files load from your .sp domain.
?stagepass=localhost:5173Local mode against a dev server on localhost with that port.
?stagepass=debugDebug mode. Stagepass logs, but no files are swapped.
?stagepass=off, 0 or falseEnds the session. Same as End session in the session card.

The loader removes the parameter from the address bar and stores the session in localStorage under stagepass_domain, with an expiry. Values other than debug, localhost, localhost:<port> or a valid name ending in .sp are rejected and clear the session.

Global Variables (sp.vars)

Access runtime information via sp.vars (preferred), or stagepass.vars / window.stagepass.vars:

JavaScript
sp.vars.isLocal     // boolean - true if Stagepass active or localhost
sp.vars.env         // 'local' | 'staging' | 'production'
sp.vars.domain      // string - Current domain (local or production)
sp.vars.timestamp   // number - Session start time (for cache-busting)
sp.vars.version     // string - Loader version
sp.vars.client      // object - Client runtime info (theme/browser/os/device/viewport/locale/capabilities)

Flat helpers

Short helpers on sp for the most common checks. sp.vars keeps working as before.

JavaScript
sp.env()                 // 'local' | 'staging' | 'production'
                         // local = active swap session to a .sp domain
                         // staging = *.webflow.io or data-stagepass-staging-hosts
sp.is('staging')         // boolean
sp.can('localStorage')   // also: sessionStorage, cookies, serviceWorker
sp.client('theme')       // or sp.client() for the whole object
const off = sp.on('theme', (t) => {})  // also: 'session'; returns unsubscribe
off()
sp.use('my-module', '2.1.0', (api) => { /* register */ })
HelperWhat it does
sp.env()The current environment: local during a swap session, staging on *.webflow.io or a staging host, otherwise production.
sp.is(env)true when sp.env() matches.
sp.can(feature)Checks localStorage, sessionStorage, cookies or serviceWorker.
sp.client(key)One part of sp.vars.client, or the whole object without a key.
sp.on(event, fn)Listens to theme or session changes. Returns a function that removes the listener.
sp.use(name, version, fn)Registers a module with its version. The loader checks the major version.

Client Runtime Info (sp.vars.client)

The loader exposes technical client/runtime data:

JavaScript
sp.vars.client.theme.preferred   // 'light' | 'dark' | 'no-preference'
sp.vars.client.theme.current     // 'light' | 'dark' | 'unknown' (auto-updated)
sp.vars.client.browser.family    // 'chrome' | 'safari' | 'firefox' | 'edge' | 'opera' | 'unknown'
sp.vars.client.browser.major     // number | null
sp.vars.client.os.family         // 'macos' | 'windows' | 'ios' | 'android' | 'linux' | 'unknown'
sp.vars.client.device.type       // 'mobile' | 'tablet' | 'desktop' | 'unknown'
sp.vars.client.device.touch      // boolean
sp.vars.client.viewport.width    // number (auto-updated on resize)
sp.vars.client.viewport.height   // number (auto-updated on resize)
sp.vars.client.viewport.dpr      // number (auto-updated on resize)
sp.vars.client.locale.language   // string (e.g. 'de-DE')
sp.vars.client.locale.timezone   // string | null
sp.vars.client.capabilities.cookiesEnabled // boolean
sp.vars.client.capabilities.localStorage   // boolean
sp.vars.client.capabilities.sessionStorage // boolean

Notes:

  • Browser/OS/device detection is heuristic (best effort).
  • client values are runtime data, not analytics consent/tracking signals.
  • theme.current and viewport.* are refreshed while the page is running.

Local URL helper (sp.resolveLocalUrl)

The loader exposes a single place to build local asset URLs (used by modules and by custom code):

JavaScript
// Returns local URL when a Stagepass session is active, otherwise ''
sp.resolveLocalUrl('js/app.js');   // e.g. 'https://my-project.sp/js/app.js?_cb=1234567890'
sp.resolveLocalUrl('/lib.js');     // leading slash is normalized

Logging API

Stagepass provides a structured logging API that wraps the browser console when a Stagepass session is active:

JavaScript
// Preferred API
sp.log('Hello from Stagepass');          // info / log
sp.log('warn', 'Something looks off');   // warn level
sp.log('error', 'Something went wrong'); // error level

sp.warn('This is a warning');
sp.error('This is an error');

sp.log automatically prefixes messages with a timestamp and (if available) the calling file and line, e.g. [🎫 11:58:02 | app.js:830]. Logging is only active when a Stagepass session is enabled; otherwise the helper functions are effectively no-ops. During a session the flag counts these warnings and errors together with console.warn, console.error, uncaught errors and failed resources. See Flag states. The deprecated globals splog / spwarn / sperror were removed in v2.

In debug mode the loader warns when several tagged files share the same local file name.

TypeScript types

The loader package ships complete declarations for sp and window.stagepass in global.d.ts, with JSDoc, examples and typed sp.on(...) events. Add the package to your tsconfig.json:

tsconfig.json
{ "compilerOptions": { "types": ["@stagepass/loader"] } }

For module types, see Modules.

Profiles for coding agents

Projects created or upgraded with stagepass new or stagepass upgrade get the sp reference in AGENTS.md automatically, generated from the modules the site loads. See CLI. For projects without the CLI, use one of the following canonical profiles in your project-level AGENTS.md so AI coding agents know exactly which Stagepass runtime APIs are available.

Canonical profile files

How to use

  1. Copy the relevant file content into your project AGENTS.md.
  2. Keep only one active profile per project to avoid ambiguous API assumptions.
  3. If your tooling supports remote include/import in AGENTS files, you can reference the raw GitHub URL instead of copy-paste.