ScaleBun
Skip to article

Install & initialize

webDeveloper

Install @scalebun/web, initialize it with your client key, and choose a delivery path — npm, a CDN script tag, or Google Tag Manager.

Updated Reviewed

Install the package#

Terminal
npm i @scalebun/web

Using a framework? Also add its adapter — see Framework adapters:

Terminal
npm i @scalebun/web-react   # or -next / -vue / -svelte / -angular

Initialize#

Only clientKey and apiBaseUrl are required, and the config object is the same everywhere. What changes per framework is where the call goes — pick yours:

src/main.tsTypeScript
import ScaleBun from '@scalebun/web';
await ScaleBun.init({  clientKey: 'skb_live_ck_…',  apiBaseUrl: 'https://api.scalebun.com/api/v1',  environment: 'production',  release: '1.4.2',});

Call trackScreen() on navigation and captureError() in your error handler — that is all an adapter does for you.

That is the whole setup. Integrations covers the rest of each adapter per framework — error-boundary props, feature-flag hooks, coachmark anchors, in-app slots, and server-side capture for Next and SvelteKit.

Client keys are prefixed so a key visibly declares its blast radius — skb_test_ck_…, skb_staging_ck_…, skb_live_ck_…. Keys issued before the prefixed scheme (scalebun_ck_…) remain valid.

Where init() runs#

RuntimeWhat happens
BrowserFull capture. This is the normal case.
SSR render pass (Node)Deterministic no-op — no network, no observers, no storage. Capture activates on the client after hydration, where your client entry calls init() again.
Edge / workerA lite lane: analytics and config send over fetch with an ephemeral identity. No DOM, so no session, replay or persistence. These runtimes handle a request and never hydrate, so this is the only capture they get.

You do not configure any of this — the SDK detects the runtime. Every framework adapter inherits the same guard.

Enabling opt-in features#

Most features are on by default. Five are off until you enable them: replay, profiler, watchdog, inbox, and inapp2 (the In-App Messaging 2.0 engine). Turn one on via features:

TypeScript
await ScaleBun.init({  clientKey,  apiBaseUrl,  features: { replay: true },  replay: { mode: 'sampled', sampleRate: 1 },});

Other delivery paths#

The same runtime ships three ways — one SDK, three delivery paths.

CDN <script> (declarative, CSP-clean)#

Configure with data-* attributes on the tag itself; no inline code required.

HTML
<script nonce="abc123"        src="https://cdn.jsdelivr.net/npm/@scalebun/web@1/dist/scalebun.min.js"        data-client-key="skb_live_ck_…"        data-api-base-url="https://api.scalebun.com/api/v1"></script>

The tag reads exactly four attributes — data-client-key, data-api-base-url, data-environment and data-autocapture. Both keys are required for the auto-init to fire. For anything else, use the loader snippet or the npm package.

Async loader snippet#

The recommended no-build path: an inline stub queues calls made before the bundle loads and replays them in order, so nothing is lost to the race. Full snippet in Plain JavaScript, CDN & GTM.

Google Tag Manager#

Import the ScaleBun custom template and set the Client key and API base URL fields. The template sets up a loader queue, queues init(), and injects the CDN bundle — so you get the same SDK without touching app code.

Configuration reference#

Common top-level options and their defaults:

OptionDefaultWhat it does
clientKeyRequired. Publishable client key.
apiBaseUrlRequired. Ingestion API base URL.
environmente.g. production, staging.
releaseVersion string, used to group errors and sessions.
autocapturetrueZero-instrumentation DOM capture.
flushIntervalMs5000How often the queue flushes.
maxBatchSize50Max items per flush.
maxQueueSize1000Max buffered items before drop.
requireConsentfalseGate all capture behind setConsent(true).
tracePropagationtrueInject W3C traceparent on same-origin requests.
tracePropagationOrigins[]Cross-origin origins to also propagate to. The server must CORS-allow the header.
sessionTimeoutMs30 minIdle time after which the next load starts a new session.
sessionMaxDurationMs24 hAbsolute cap, so a permanently-open tab cannot report an endless session.
replayCanvasfalseCapture <canvas> pixels. Opt-in — pixels cannot be masked.
replayFrameOrigins[]Cross-origin replay stitching; both sides must list each other.
signSessionLanefalseHMAC-sign session and replay batches too. The analytics lane always signs.
initialConsent'unknown'Pre-known consent from SSR or a cookie.
debugfalseVerbose SDK logging.

Nested blocks — errors, network, performance, replay, analytics, flags, watchdog, exitIntent, push, privacy, bugReportOptions — are documented on the page for each feature, and in full in the configuration reference.

Before you use a feature controller#

init() is async. Accessors like ScaleBun.inbox() and ScaleBun.coachmarks() return a no-op object when the runtime is not built yet, and every method on it silently does nothing.

TypeScript
await ScaleBun.whenReady();   // resolves once init() has SETTLEDScaleBun.inbox().mount();

It resolves on failure as well as success — if init() failed there genuinely is no SDK, and the no-op accessors are the honest answer, but your code must not hang waiting for a promise that will never resolve.

This matters most in component trees, where children mount before parents. See Integrations.

Next#

Install & initialize · Web SDK · ScaleBun