Scope API
The “scope” is the ambient context every captureException /
captureMessage snapshots onto the event it ships. Sentori does
not expose a Hub or Scope class — scope is module-scoped state
and the functions below mutate it directly.
import sentori from '@goliapkg/sentori-react-native'
sentori.setUser({ id: 'usr_42', linkBy: { email: 'a@b.com' } })sentori.setTag('plan', 'pro')sentori.addBreadcrumb({ type: 'nav', message: '/dashboard' })setUser
Section titled “setUser”type User = { id?: string name?: string anonymous?: boolean linkBy?: Record<string, string>}
function setUser(user: User | null): voidIdentifies the current user. Pass null to clear (e.g. on
logout). id and name are stored raw — host’s choice whether
to put real PII there. linkBy is the identity layer:
each value is normalised + SubtleCrypto SHA-256 hashed on the
device; only the hash leaves the SDK.
Common shapes:
// Anonymous user with a stable client id.sentori.setUser({ id: anonymousDeviceId, anonymous: true })
// Identified user with a cross-project lookup key.sentori.setUser({ id: 'usr_42', name: 'Lihao', linkBy: { email: user.email },})
// Logout — clear the scope.sentori.setUser(null)Well-known linkBy types
Section titled “Well-known linkBy types”The SDK applies type-specific normalisation before hashing so the same identity hashes to the same fingerprint regardless of casing / formatting:
| Key | Normalisation |
|---|---|
email | Lowercase + trim. |
phone | Strip non-digits, prefix +. (E.164 internalisation; passes any input format.) |
username | Lowercase + trim. |
googleSub / appleSub / metaSub | Trim only — sub claims are opaque. |
| Custom | Pass-through (host responsible for stability). |
setTag / setTags
Section titled “setTag / setTags”function setTag(key: string, value: string): voidfunction setTags(record: Record<string, string>): voidfunction clearTags(): voidTags are scope-level key/value strings that ride along on every subsequent event. They’re indexed server-side for filtering + grouping; keep cardinality reasonable.
sentori.setTag('plan', 'pro')sentori.setTags({ feature: 'maps', rollout: 'wave-3' })addBreadcrumb
Section titled “addBreadcrumb”type BreadcrumbType = 'custom' | 'log' | 'nav' | 'net' | 'track' | 'user'
type BreadcrumbInput = { message?: string type?: BreadcrumbType level?: MessageLevel data?: Record<string, unknown>}
function addBreadcrumb(crumb: BreadcrumbInput): voidfunction getBreadcrumbs(): Breadcrumb[]function clearBreadcrumbs(): voidBreadcrumbs are a ring buffer of recent steps. The current snapshot is sealed onto every captured event so the dashboard renders a “leading up to” timeline.
Default ring capacity: 100. Buffer is FIFO — the oldest drops as new ones land.
sentori.addBreadcrumb({ type: 'nav', message: '/dashboard',})
sentori.addBreadcrumb({ type: 'user', message: 'tapped "Refresh"', data: { source: 'header-button' },})
sentori.addBreadcrumb({ type: 'net', message: 'GET /api/profile 200', data: { method: 'GET', status: 200, durationMs: 142 },})type axis is one of six well-known values; pick the closest fit.
Custom data lives on data, not on a parallel “category” axis
(Sentry’s category+type overlap collapsed into one).
Auto breadcrumbs
Section titled “Auto breadcrumbs”When the relevant init.capture.* flag is on, these breadcrumbs
fire automatically:
| Source | Type | Trigger |
|---|---|---|
init.capture.network | net | every fetch / xhr round-trip |
init.capture.sessions | user | app active/background transition |
useTraceNavigation | nav | react-navigation route change |
sentori.track() w/ trackAutoBreadcrumb: true | track | every track() call |
Host code can layer custom ones on top via addBreadcrumb.
Why no withScope(fn) or configureScope(fn) (in native API)
Section titled “Why no withScope(fn) or configureScope(fn) (in native API)”Sentry’s Hub / Scope abstraction is internal plumbing that
leaked into the public API. We hide it: setTag(k, v) /
addBreadcrumb({...}) mutate the current (only) scope directly.
The Sentry-compat sub-package
(@goliapkg/sentori-react-native/compat) does expose
Sentry.withScope(fn => fn.setTag(...)) for code an LLM has been
trained on — see Sentry compat. The
withScope-style push/pop is implemented internally by the
compat layer.
Related
Section titled “Related”api/init—identity: true|falsetoggle for the linkBy layerapi/capture— what scope feeds intoprivacy/identity—linkByaudit