0
# Context and Scope Management
1
2
User context, tags, and extra data management system for organizing and enriching Sentry events with relevant information. The scope system provides isolated contexts for different parts of your application.
3
4
## Capabilities
5
6
### User Context
7
8
Set and manage user information that will be attached to all events.
9
10
```typescript { .api }
11
/**
12
* Set user information for all subsequent events
13
* @param user - User information object
14
*/
15
function setUser(user: User | null): void;
16
```
17
18
**Usage Examples:**
19
20
```typescript
21
import { setUser } from "@sentry/browser";
22
23
// Basic user information
24
setUser({
25
id: "12345",
26
email: "user@example.com",
27
username: "johndoe",
28
});
29
30
// Extended user information
31
setUser({
32
id: "12345",
33
email: "user@example.com",
34
username: "johndoe",
35
ip_address: "192.168.1.1",
36
subscription: "premium",
37
first_login: "2023-01-15",
38
});
39
40
// Clear user information
41
setUser(null);
42
```
43
44
### Tags
45
46
Set tags for categorizing and filtering events in Sentry.
47
48
```typescript { .api }
49
/**
50
* Set a single tag that will be attached to all subsequent events
51
* @param key - Tag key
52
* @param value - Tag value (must be primitive)
53
*/
54
function setTag(key: string, value: Primitive): void;
55
56
/**
57
* Set multiple tags at once
58
* @param tags - Object containing key-value pairs of tags
59
*/
60
function setTags(tags: { [key: string]: Primitive }): void;
61
```
62
63
**Usage Examples:**
64
65
```typescript
66
import { setTag, setTags } from "@sentry/browser";
67
68
// Single tag
69
setTag("environment", "production");
70
setTag("feature_flag", "new_ui_enabled");
71
72
// Multiple tags
73
setTags({
74
component: "checkout",
75
user_type: "premium",
76
ab_test: "variant_b",
77
version: "1.2.3",
78
});
79
```
80
81
### Extra Data
82
83
Set additional arbitrary data to be attached to events.
84
85
```typescript { .api }
86
/**
87
* Set extra data that will be attached to all subsequent events
88
* @param key - Extra data key
89
* @param extra - Extra data value (can be any type)
90
*/
91
function setExtra(key: string, extra: Extra): void;
92
93
/**
94
* Set multiple extra data values at once
95
* @param extras - Object containing key-value pairs of extra data
96
*/
97
function setExtras(extras: { [key: string]: Extra }): void;
98
```
99
100
**Usage Examples:**
101
102
```typescript
103
import { setExtra, setExtras } from "@sentry/browser";
104
105
// Single extra data
106
setExtra("last_action", "clicked_checkout_button");
107
setExtra("cart_items", ["item1", "item2", "item3"]);
108
109
// Complex extra data
110
setExtras({
111
user_preferences: {
112
theme: "dark",
113
language: "en",
114
notifications: true,
115
},
116
session_info: {
117
start_time: new Date().toISOString(),
118
page_views: 5,
119
time_spent: 1200000,
120
},
121
debug_info: {
122
build_number: "1.2.3-456",
123
feature_flags: ["flag1", "flag2"],
124
},
125
});
126
```
127
128
### Context Data
129
130
Set structured context data for specific domains.
131
132
```typescript { .api }
133
/**
134
* Set context data under a specific key
135
* @param key - Context namespace key
136
* @param context - Context data object
137
*/
138
function setContext(key: string, context: Context | null): void;
139
```
140
141
**Usage Examples:**
142
143
```typescript
144
import { setContext } from "@sentry/browser";
145
146
// Device context
147
setContext("device", {
148
name: "iPhone 12",
149
family: "iOS",
150
model: "iPhone13,1",
151
memory_size: 6442450944,
152
storage_size: 128000000000,
153
});
154
155
// Application context
156
setContext("app", {
157
name: "My App",
158
version: "1.2.3",
159
build: "456",
160
theme: "dark",
161
});
162
163
// Business context
164
setContext("business", {
165
plan: "premium",
166
account_type: "enterprise",
167
region: "us-west-2",
168
});
169
170
// Clear context
171
setContext("device", null);
172
```
173
174
### Scope Management
175
176
Create isolated scopes for temporary context changes.
177
178
```typescript { .api }
179
/**
180
* Execute callback with a temporary scope containing isolated context
181
* @param callback - Function to execute with the new scope
182
*/
183
function withScope(callback: (scope: Scope) => void): void;
184
185
/**
186
* Execute callback with a temporary isolation scope
187
* @param callback - Function to execute with the new isolation scope
188
*/
189
function withIsolationScope(callback: (scope: Scope) => void): void;
190
```
191
192
**Usage Examples:**
193
194
```typescript
195
import { withScope, captureException, captureMessage } from "@sentry/browser";
196
197
// Temporary context for specific operation
198
withScope((scope) => {
199
scope.setTag("operation", "payment_processing");
200
scope.setExtra("payment_method", "credit_card");
201
scope.setLevel("warning");
202
203
try {
204
processPayment();
205
} catch (error) {
206
// This exception will include the temporary context
207
captureException(error);
208
}
209
});
210
211
// Context isolation for different features
212
function handleUserAction(action: string) {
213
withScope((scope) => {
214
scope.setTag("user_action", action);
215
scope.setExtra("timestamp", Date.now());
216
217
captureMessage(`User performed action: ${action}`, "info");
218
});
219
}
220
```
221
222
### Scope Access
223
224
Access current scopes for reading or modifying context.
225
226
```typescript { .api }
227
/**
228
* Get the current scope for the current context
229
* @returns Current scope instance
230
*/
231
function getCurrentScope(): Scope;
232
233
/**
234
* Get the isolation scope (shared across async operations)
235
* @returns Isolation scope instance
236
*/
237
function getIsolationScope(): Scope;
238
239
/**
240
* Get the global scope (shared across entire application)
241
* @returns Global scope instance
242
*/
243
function getGlobalScope(): Scope;
244
```
245
246
**Usage Examples:**
247
248
```typescript
249
import { getCurrentScope, getIsolationScope } from "@sentry/browser";
250
251
// Read current context
252
const currentScope = getCurrentScope();
253
const currentUser = currentScope.getUser();
254
const currentTags = currentScope.getTags();
255
256
// Modify current scope
257
const scope = getCurrentScope();
258
scope.setTag("modified_at", Date.now().toString());
259
260
// Access isolation scope
261
const isolationScope = getIsolationScope();
262
isolationScope.setContext("feature", { name: "new_feature", enabled: true });
263
```
264
265
### Breadcrumbs
266
267
Add breadcrumb trail information to track user actions leading up to events.
268
269
```typescript { .api }
270
/**
271
* Add a breadcrumb to the current scope
272
* @param breadcrumb - Breadcrumb information
273
* @param hint - Additional hint information for processing
274
*/
275
function addBreadcrumb(breadcrumb: Breadcrumb, hint?: BreadcrumbHint): void;
276
```
277
278
**Usage Examples:**
279
280
```typescript
281
import { addBreadcrumb } from "@sentry/browser";
282
283
// Navigation breadcrumb
284
addBreadcrumb({
285
message: "User navigated to checkout page",
286
category: "navigation",
287
level: "info",
288
data: {
289
from: "/cart",
290
to: "/checkout",
291
},
292
});
293
294
// User interaction breadcrumb
295
addBreadcrumb({
296
message: "Button clicked",
297
category: "ui.click",
298
level: "info",
299
data: {
300
button_id: "submit-order",
301
component: "CheckoutForm",
302
},
303
});
304
305
// HTTP request breadcrumb
306
addBreadcrumb({
307
message: "API request",
308
category: "http",
309
level: "info",
310
data: {
311
url: "/api/orders",
312
method: "POST",
313
status_code: 201,
314
},
315
});
316
317
// Custom breadcrumb with timestamp
318
addBreadcrumb({
319
message: "Custom business event",
320
category: "business",
321
level: "debug",
322
timestamp: Date.now() / 1000,
323
data: {
324
action: "discount_applied",
325
discount_code: "SAVE20",
326
original_price: 100,
327
discounted_price: 80,
328
},
329
});
330
```
331
332
## Types
333
334
### User Information
335
336
```typescript { .api }
337
interface User {
338
/** Unique user identifier */
339
id?: string;
340
341
/** User's username */
342
username?: string;
343
344
/** User's email address */
345
email?: string;
346
347
/** User's IP address */
348
ip_address?: string;
349
350
/** User's subscription level */
351
subscription?: string;
352
353
/** Additional user properties */
354
[key: string]: any;
355
}
356
```
357
358
### Scope Interface
359
360
```typescript { .api }
361
interface Scope {
362
/** Set user information */
363
setUser(user: User | null): this;
364
365
/** Get current user information */
366
getUser(): User | undefined;
367
368
/** Set a tag */
369
setTag(key: string, value: Primitive): this;
370
371
/** Set multiple tags */
372
setTags(tags: { [key: string]: Primitive }): this;
373
374
/** Get current tags */
375
getTags(): { [key: string]: Primitive };
376
377
/** Set extra data */
378
setExtra(key: string, extra: Extra): this;
379
380
/** Set multiple extra data values */
381
setExtras(extras: { [key: string]: Extra }): this;
382
383
/** Get current extra data */
384
getExtras(): { [key: string]: Extra };
385
386
/** Set context data */
387
setContext(key: string, context: Context | null): this;
388
389
/** Get context data */
390
getContext(key: string): Context | undefined;
391
392
/** Set severity level */
393
setLevel(level: SeverityLevel): this;
394
395
/** Get current severity level */
396
getLevel(): SeverityLevel | undefined;
397
398
/** Set fingerprint */
399
setFingerprint(fingerprint: string[]): this;
400
401
/** Get current fingerprint */
402
getFingerprint(): string[] | undefined;
403
404
/** Add breadcrumb */
405
addBreadcrumb(breadcrumb: Breadcrumb, maxBreadcrumbs?: number): this;
406
407
/** Get last breadcrumb */
408
getLastBreadcrumb(): Breadcrumb | undefined;
409
410
/** Clear the scope */
411
clear(): this;
412
413
/** Add event processor to this scope */
414
addEventProcessor(callback: EventProcessor): this;
415
}
416
```
417
418
### Breadcrumb Structure
419
420
```typescript { .api }
421
interface Breadcrumb {
422
/** Breadcrumb type (e.g., "navigation", "http", "user") */
423
type?: string;
424
425
/** Severity level */
426
level?: SeverityLevel;
427
428
/** Associated event ID */
429
event_id?: string;
430
431
/** Breadcrumb category for grouping */
432
category?: string;
433
434
/** Human-readable message */
435
message?: string;
436
437
/** Additional data */
438
data?: any;
439
440
/** Timestamp when breadcrumb was created */
441
timestamp?: number;
442
}
443
444
interface BreadcrumbHint {
445
/** Input data that created this breadcrumb */
446
input?: any;
447
448
/** Additional hint data */
449
[key: string]: any;
450
}
451
```
452
453
### Primitive Types
454
455
```typescript { .api }
456
type Primitive = number | string | boolean | bigint | symbol | null | undefined;
457
type Context = Record<string, any>;
458
type Extra = any;
459
```
460
461
## Context Inheritance
462
463
Sentry uses a hierarchical scope system:
464
465
1. **Global Scope**: Shared across the entire application
466
2. **Isolation Scope**: Shared across async operations but isolated between concurrent operations
467
3. **Current Scope**: Specific to the current execution context
468
469
Context is inherited from higher-level scopes and can be overridden at lower levels:
470
471
```typescript
472
import { setUser, setTag, withScope, captureMessage } from "@sentry/browser";
473
474
// Global context - applies to all events
475
setUser({ id: "12345" });
476
setTag("app_version", "1.0.0");
477
478
withScope((scope) => {
479
// This scope inherits global context but can override it
480
scope.setTag("feature", "checkout"); // Adds to global tags
481
scope.setUser({ id: "12345", email: "user@example.com" }); // Extends global user
482
483
captureMessage("Checkout started"); // Includes both global and scope context
484
});
485
```
486
487
## Best Practices
488
489
### Context Organization
490
491
Use different context types appropriately:
492
- **Tags**: For filtering and grouping (strings, numbers, booleans only)
493
- **Extra**: For debugging information (any data type)
494
- **Context**: For structured domain-specific data
495
- **User**: For user identification and properties
496
497
### Scope Usage
498
499
Use `withScope` for temporary context that should not affect other events:
500
501
```typescript
502
// Good: Isolated context for specific operation
503
withScope((scope) => {
504
scope.setTag("operation", "file_upload");
505
processFileUpload();
506
});
507
508
// Avoid: Global context that affects all subsequent events
509
setTag("operation", "file_upload"); // This affects ALL future events
510
```
511
512
### Breadcrumb Strategy
513
514
Add meaningful breadcrumbs that help debug issues:
515
516
```typescript
517
// Good: Actionable breadcrumbs
518
addBreadcrumb({
519
message: "User clicked submit button",
520
category: "ui.click",
521
data: { form_id: "payment-form", validation_errors: 0 },
522
});
523
524
// Less useful: Vague breadcrumbs
525
addBreadcrumb({
526
message: "Something happened",
527
category: "debug",
528
});
529
```