Changelog

Browsonic release notes

A curated, human-readable log of notable releases. Per-version history for every package is on npm.

Last updated:

This is the public record. Every release below is cut by CI from Conventional Commits, and each published version — with its own release notes and the exact files that shipped — is on npm under the @browsonic scope. The source repository is private, so npm is where the per-version detail lives.

SDK & adapters

v3.27.0
Current — @browsonic/sdk 3.27.0

The SDK is on the 3.27.x line — five releases in the first week of September. Sessions now end (30 minutes idle, destroy(), newSession()), a consent gate that has not answered yet holds events instead of dropping them, errors carry their own data and a link to the replay moment, Web Vitals explain themselves, and fifteen tuning knobs became internal constants so a mistyped number can no longer switch error tracking off.

Added
  • errorData on every error — the Error's own properties, HTTP status / url / method, a plain-object rejection reason — and _replay { seq, offsetMs } while the replay plugin records, so an error opens at its moment in the recording.
  • Web Vitals attribution: LCP element and resource URL, INP target and phases, CLS shift source, TTFB breakdown, plus long-animation-frame breadcrumbs (3.27).
  • newSession(); captureError(error, { handled, mechanism }); networkDetail with method / url / status / duration on network failures; lifecycle breadcrumbs (hidden / visible / online / offline) (3.26–3.27).
  • Replay reports its mask policy (X-Replay-Mask) so the dashboard can explain a grey recording instead of guessing (3.24).
  • A script-tag host can turn Web Vitals on with trackWebVitals: true (3.23).
Changed
  • Fifteen settings became internal constants (flushIntervalMs, maxBatchSize, cooldownMs, maxQueueSize, …). They are still accepted, named once at init(), and ignored — none had a per-deployment right answer and each one a host got wrong took the SDK down silently (3.25).
  • Repeats inside the 60-second dedup window are counted and stamped on the next admitted occurrence as _suppressed; dropped events name their reason in the diagnostics.
  • Fewer requests: the config pull happens once an hour from a trusted cache, page views ride in batches against a current server, and event bodies are gzipped by default.
  • A built-in session / CSRF cookie-name blocklist (JSESSIONID, PHPSESSID, connect.sid, csrftoken, __Host-*, __Secure-*, …) that no configuration can widen.
  • Bundle: ~28 kB core / ~46 kB with every plugin, minified and gzipped (measured 27.66 / 46.22 kB on 3.27.0).
Notes
  • Packages are published with publishConfig.provenance: false while the repository is private; every release attaches SHA256SUMS for the tarballs instead — see the security page.
  • For every per-version diff, see the npm release history linked at the bottom of this page.
v3.23.0 – 3.26.0
Capture v2 — the event describes what happened

Four releases between 2 and 5 September that made the event self-describing: what the request was, which control the user touched, what the framework already knew, and a stack that actually reaches application code.

Added
  • 3.26 — networkDetail carries the request (method, url, status); Angular's default ErrorHandler output is recognised; errorType prefers error.name; the interaction timeline names the field; storage snapshots skip the SDK's own keys.
  • 3.25 — user interactions get their own slots in the telemetry timeline; a route that resolves to where it already was is no longer a navigation.
  • 3.24 — the replay plugin reports which rrweb masks were active, so the product can explain a grey screen.
  • 3.23 — trackWebVitals: true for script-tag hosts; the identity channel (identify) is documented.
Fixed
  • Stack capture that reaches application code: V8 caps Error.stack at stackTraceLimit (10 frames); the SDK raises it while capturing, and the raw stack string is redacted with the frame-aware rule so URLs stay readable (3.26).
  • One fault reports once from the framework adapters, the component is named, and action arguments no longer leak (3.23).
  • Three collectors stopped reporting things that did not happen; page-view collection no longer collapses a list walk into one view (3.23).
  • Published packages are loadable, tree-shake-safe and typed; stale build output no longer ships (3.23).
v3.21.0 – 3.21.2
Privacy hardening, and a Web Vitals delivery fix

A sustained pass over what can leave the browser, plus the fix for a regression worth knowing about if you are pinned to an early 3.21.x.

Added
  • sessionContext — app-defined session-level context with an explicit allowKeys egress policy. An allow list, not a deny list: forgetting to list a key over-redacts and you notice.
Fixed
  • Turkish national IDs (checksum-validated TCKN) and phone / MSISDN shapes are redacted before events leave the browser, matching the server-side scrubber instead of relying on it.
  • stack, stackFrames[] and linkedErrors[] go through redaction; symbolication is unaffected because debug ids resolve from the raw frames.
  • Nested values past the depth bound now fail closed — an over-deep object becomes [REDACTED_DEPTH_LIMIT] instead of egressing verbatim under scrubbed shallow levels.
  • Numbers reach the redaction pass at all: { msisdn: 905321110001 } used to bypass it because the value was not a string.
Notes
  • ⚠️ 3.21.0 and 3.21.1 ship no Web Vitals at all. The page-hide flush ran before the plugin enqueued its sample, so LCP / INP / CLS never left the browser and the Performance page went to dashes. Fixed in 3.21.2 — upgrade if you are on either.
v3.17.0 – 3.19.0
App Atlas: task lifecycle, screen context, cross-app hand-off

The SDK half of App Atlas. Route maps needed no integration; describing what a user was *trying to do* does, and this is that surface.

Added
  • atlas.startTask({ task }) — a no-throw handle with step / complete / abandon / fail. Open tasks auto-end as abandoned on page dismissal; flood guards cap events per session and concurrent tasks.
  • atlas.handoff.start({ intent }) / close(outcome) — journey continuity across two apps of the same organisation. The ticket travels only in the URL fragment (#bhid=), so it never reaches a server log or a Referer header.
  • Screen context on page views — a stable screen id, an archetype (list / detail / form / wizard / …) and a zone, all optional and validated silently.
  • Task lifecycle events mirror into a live Session Replay recording as rrweb custom events, so playback lines up with task state.
Fixed
  • The es2015 IIFE build no longer throws at load on engines without regex lookbehind (Safari ≤ 16.3, older Chrome/Firefox) — precisely the legacy audience that artifact exists for.
v3.13.0 – 3.16.0
Atlas umbrella flag, navigation context, route normalisation

Page-view telemetry stops being a URL list and starts being a navigation record — and turning it on becomes one flag.

Added
  • atlas: true — one init flag replaces the manualPageViews + adapter pairing. Organic tracking runs from first paint and the first templated trackPageView() from an adapter takes the channel over automatically.
  • Navigation Context — the trigger behind each navigation: the interacted element's accessible name, the trigger kind, navigation type, previous route and dwell time. [data-browsonic-mask] subtrees yield nothing.
  • Screen names via trackPageView(route, { name }) or a [data-browsonic-screen] annotation.
  • A maintained self-hosted es2015 IIFE artifact for bundler stacks that cannot parse the ES2020 dist.
Changed
  • Routes are normalised at source — /orders/order12345 collapses to /orders/order:id, so id-suffixed URLs stop minting unbounded distinct routes.
  • ⚠️ updateConfig() now refuses runtime changes to collector-snapshot keys such as captureDocumentTitle, instead of merging them as a silent no-op. The running collector never honoured them, so the old behaviour was a privacy control that lied.
  • Page-view sampling is session-consistent: a whole session is kept or dropped, replacing the per-navigation coin flip that put phantom edges in journey topology.
Fixed
  • A transient HTTP 429 no longer permanently loses the rate-limited batch.
  • Session Replay's final dismissal flush ships synchronously instead of awaiting a gzip pipe whose reads never complete in a dying page.
v3.9.0 – 3.12.0
Page-view controls and replay volume caps

Source-side control over what page-view telemetry is produced, and a ceiling on how much a replay recording can cost.

Added
  • trackPageView(route) plus manual mode, so an adapter can send route templates rather than raw URLs.
  • Source-side route controls — patterns, a normalisation hook, hash-routing support and sampling.
  • Session Replay idle / max-duration auto-stop and rrweb throttles.
Fixed
  • Error-event url / referrer go through the full URL sanitiser rather than the weaker string redactor.
v3.1.x
Source-map pipeline v0.1

End-to-end source-map upload pipeline: build-tool plugins for Vite / Webpack / Rollup, a service-side ingest endpoint, and a dashboard view for symbolicated stack frames.

Added
  • @browsonic/cli source-map upload command — drop-in build step.
  • Vite / Webpack / Rollup plugins emit and upload maps in CI.
  • Dashboard surfaces symbolicated frames inline on the event timeline.
Notes
  • Token CRUD + id-keyed list/delete deferred to v0.2.
v3.0.x
Adapter 0.2 / 0.3 milestones

Framework adapters reached parity on router instrumentation, navigation breadcrumbs and framework-specific helpers. Vue and Svelte fully completed the 0.3 milestone; Remix, Angular and Astro shipped a partial set.

Added
  • @browsonic/vue — Pinia plugin and route hierarchy breadcrumbs.
  • @browsonic/svelte — form-action capture and HTTP reporter.
  • @browsonic/nextjs, @browsonic/remix, @browsonic/astro — router instrumentation + navigation breadcrumbs.
  • @browsonic/angular — router-aware error handler.
v2.2.0
Initial public release

First public release of the SDK. Previously distributed privately as @leguides/browsonic-sdk (latest internal version 2.1.1); the public API and /v1/events wire format are unchanged.

Added
  • Apache 2.0 licence (LICENSE, NOTICE).
  • Public-facing docs: README, CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, BENCHMARKS.
  • GitHub issue and pull-request templates.
  • npm provenance via sigstore on every published version.
Changed
  • Package name: @leguides/browsonic-sdk@browsonic/sdk.
  • Registry: GitHub Packages → public npm.
  • Repository: leguides/browsonic-sdkSangaibisi/browsonic-sdk.
  • License: proprietary → Apache 2.0.

Platform

Business-logic audit
Quota ceilings, invitations, retention windows — what the product promised now holds

A same-day pass over the service and dashboard against the product's own rules. Every finding except e-mail delivery shipped to production on 5 September.

Fixed
  • Every paid plan is metered against its own monthly event ceiling. A lazy database read on the ingest path had collapsed every tenant to the Free limit; the fix is a scalar read guarded by a real-database test.
  • Invitations work for people who already have an account: accept on the invitation page with your password (and authenticator code), or sign in and open /accept-invite. Removed teammates can be invited again; the only owner of a workspace cannot leave it stranded.
  • Reads reach the full plan retention: Professional and Enterprise can look back 90 / 365 days in Issues, URLs, Events and Performance instead of 30.
  • Session Replay recordings are stamped with the plan's retention on every plan change, and the SDK is told when a workspace's replay storage is nearly full or full so it stops recording what ingest would refuse.
  • The Performance page groups by route template (/orders/:id) and its headline error rate is the whole window, not the routes on the current page.
Added
  • Settings → Alerts: notification webhook endpoints (error storms, quota alerts, security events) with a signed test delivery.
  • Atlas catalog page: the per-app task-mode switch.
  • The Free plan holds two active API keys, so a key can be rotated without revoking the only one every deployed SDK carries.
  • Refresh tokens are bound to the session that presents them (cookie-tossing defence); noise-filter rules are owner-only, audited, and their regular expressions are evaluated under a hard time budget.
Storage & data hygiene
Audit records encrypted at rest, row-level security on ingest tables

The production database audit of 4 September, applied the next day: actor e-mail and IP in the audit log are encrypted at rest, the ingest tables carry row-level security like the rest of the schema, foreign keys got their indexes, and a broken source-map object key no longer answers 500.

Changed
  • Audit log actor e-mail / IP encrypted at rest (existing rows rewritten once, idempotently).
  • Row-level security on the ingest tables; foreign-key indexes across the schema.
  • Kafka data on a named volume, ClickHouse system-log retention and memory limits, Redis credential rotation, MFA required on the platform console.
Cross-app user journey
One subscriber, every app, one timeline

Call identify() in each of your applications and Browsonic stitches a single subscriber's activity across all of them into one ordered timeline — the error in the billing app and the failed step in the self-service app become the same story instead of two unrelated incidents. Professional-tier.

Added
  • identify(subscriber) in @browsonic/sdk 3.22.0 — the SDK half.
  • Journey view in the dashboard: one identity, ordered events across every app in the organisation.
  • The SDK's atlas.handoff ticket links two apps within a single visit; identify() links them across visits.
Figma export
App Atlas → Figma, as a real design file

Export the Atlas map into Figma as five pages — the route map, a retina screenshot wall, design tokens, wireframes and flow diagrams — with Figma Styles, Variables and a DTCG token file. Re-importing is idempotent, so an export can be repeated as the app changes without duplicating pages.

Added
  • A Figma plugin fed by a single-use, TTL-bounded export ticket.
  • Styles + Variables + DTCG tokens, not just flattened images.
Notes
  • No other session-replay product exports to Figma; this is the one place your production reality and your design source of truth meet.
Atlas Task Map
Task Map — semantic flows with outcomes and completion rates

The route graph shows where users went. The Task Map shows what they were trying to do and whether they finished: named tasks with per-step completion, abandonment and failure rates, built from the SDK's task-lifecycle events. Professional-tier.

Added
  • Task definitions with steps, outcomes and completion / abandonment / failure rates.
  • Entry-source breakdown, including arrivals via a cross-app hand-off.
Alerts
Threshold alerts with webhook delivery

Alert rules on error volume and rate, delivered by email and webhook. Included from Starter upward — not gated behind an enterprise plan.

Added
  • Rule builder with thresholds and windows; email + webhook delivery.
  • Widget / noise rules so a known-loud source can be filtered without silencing everything.
Notes
  • Slack, PagerDuty and Linear are not built yet, so they are not advertised as available.
App Atlas
App Atlas — route & screenshot map

A fog-of-war map of your application, built server-side from captured page views — zero SDK changes required. It renders your real route graph and, via the screenshot worker, a thumbnail of each page. Professional-tier; it shows up as Atlas in the dashboard sidebar.

Added
  • Route graph derived on-read from page-view telemetry — no integration work.
  • Per-node screenshot thumbnails via the Atlas screenshot worker.
Session Replay
Session Replay — record, store, play back

DOM-level session recordings that play back next to the stack trace. Opt in via sessionReplayPlugin from the @browsonic/sdk/replay sub-path, registered before init(). Professional-tier, with privacy-first masking on by default (Sentry parity).

Added
  • @browsonic/sdk/replay — opt-in sessionReplayPlugin.
  • Masking on by default: maskAllText, maskAllInputs, blockAllMedia — password inputs always masked.
  • Dashboard playback plus an Admin settings page for the sample ceiling.

Release process

release-please migration
CI/CD: release-please instead of semantic-release

The SDK monorepo retired semantic-release in favour of release-please. PR-based releases, signed commits, and OSS-protection-friendly automation.

Changed
  • Release flow now opens a release PR per package; merging it publishes.
  • Conventional Commits still drive version bumps and changelog entries.
  • CI publishes via release.yml with NPM_TOKEN and provenance.

Full release history

Every published version of every @browsonic/* package has its own entry on npm: