0
# Transport
1
2
Transport layer for sending events to Sentry with offline support and custom transport options for reliable event delivery in browser environments.
3
4
## Capabilities
5
6
### Fetch Transport
7
8
HTTP transport using the Fetch API for sending events.
9
10
```typescript { .api }
11
/**
12
* Create a fetch-based transport for sending events
13
* @param options - Transport configuration options
14
* @returns Transport instance
15
*/
16
function makeFetchTransport(options: BrowserTransportOptions): Transport;
17
```
18
19
**Usage Example:**
20
21
```typescript
22
import { makeFetchTransport } from "@sentry/browser";
23
24
const transport = makeFetchTransport({
25
url: "https://ingest.sentry.io/api/PROJECT_ID/envelope/",
26
headers: {
27
"Authorization": "Bearer YOUR_AUTH_TOKEN",
28
"X-Custom-Header": "value",
29
},
30
fetchOptions: {
31
keepalive: true,
32
timeout: 10000,
33
},
34
});
35
36
Sentry.init({
37
dsn: "YOUR_DSN",
38
transport,
39
});
40
```
41
42
### Offline Transport
43
44
Transport with offline capability and retry logic.
45
46
```typescript { .api }
47
/**
48
* Create an offline-capable transport wrapper
49
* @param createTransport - Function to create the underlying transport
50
* @returns Offline-capable transport
51
*/
52
function makeBrowserOfflineTransport(
53
createTransport: (options: BrowserTransportOptions) => Transport
54
): (options: BrowserTransportOptions) => Transport;
55
```
56
57
**Usage Example:**
58
59
```typescript
60
import { makeBrowserOfflineTransport, makeFetchTransport } from "@sentry/browser";
61
62
const offlineTransport = makeBrowserOfflineTransport(makeFetchTransport);
63
64
Sentry.init({
65
dsn: "YOUR_DSN",
66
transport: offlineTransport,
67
});
68
```
69
70
### Custom Transport
71
72
Create custom transport implementations.
73
74
```typescript { .api }
75
/**
76
* Create a custom transport
77
* @param options - Transport options
78
* @param makeRequest - Custom request function
79
* @returns Custom transport instance
80
*/
81
function createTransport(
82
options: InternalBaseTransportOptions,
83
makeRequest: RequestFunction
84
): Transport;
85
```
86
87
### Multiplexed Transport
88
89
Send events to multiple destinations.
90
91
```typescript { .api }
92
/**
93
* Create a multiplexed transport that sends to multiple destinations
94
* @param transports - Array of transport functions
95
* @returns Multiplexed transport
96
*/
97
function makeMultiplexedTransport(
98
transports: ((options: BrowserTransportOptions) => Transport)[]
99
): (options: BrowserTransportOptions) => Transport;
100
```
101
102
## Types
103
104
### Transport Options
105
106
```typescript { .api }
107
interface BrowserTransportOptions extends BaseTransportOptions {
108
/** Target URL for sending events */
109
url: string;
110
111
/** Custom headers to include with requests */
112
headers?: { [key: string]: string };
113
114
/** Fetch API options */
115
fetchOptions?: RequestInit;
116
117
/** Request timeout in milliseconds */
118
timeout?: number;
119
120
/** Enable request compression */
121
compress?: boolean;
122
}
123
124
interface BaseTransportOptions {
125
/** Buffer size for batching events */
126
bufferSize?: number;
127
128
/** Request timeout */
129
timeout?: number;
130
131
/** Transport-specific options */
132
transportOptions?: Record<string, any>;
133
}
134
```
135
136
### Transport Interface
137
138
```typescript { .api }
139
interface Transport {
140
/** Send an envelope of events */
141
send(envelope: Envelope): Promise<TransportMakeRequestResponse>;
142
143
/** Flush any pending events */
144
flush(timeout?: number): Promise<boolean>;
145
}
146
147
interface TransportMakeRequestResponse {
148
/** Response status code */
149
statusCode?: number;
150
151
/** Response headers */
152
headers?: Record<string, string | null>;
153
}
154
155
type RequestFunction = (options: {
156
body: string | Uint8Array;
157
url: string;
158
}) => Promise<TransportMakeRequestResponse>;
159
```
160
161
## Transport Configuration Examples
162
163
### Basic Fetch Transport
164
165
```typescript
166
import { makeFetchTransport } from "@sentry/browser";
167
168
Sentry.init({
169
dsn: "YOUR_DSN",
170
transport: makeFetchTransport({
171
// Custom headers for authentication or routing
172
headers: {
173
"X-Custom-Auth": "token123",
174
"X-Environment": "production",
175
},
176
177
// Fetch API options
178
fetchOptions: {
179
keepalive: true, // Keep connection alive
180
mode: "cors",
181
credentials: "omit",
182
},
183
}),
184
});
185
```
186
187
### Offline-Capable Transport
188
189
```typescript
190
import { makeBrowserOfflineTransport, makeFetchTransport } from "@sentry/browser";
191
192
const offlineTransport = makeBrowserOfflineTransport(makeFetchTransport);
193
194
Sentry.init({
195
dsn: "YOUR_DSN",
196
transport: offlineTransport,
197
198
// Configure offline behavior
199
beforeSend(event) {
200
// Add offline indicator to events
201
if (!navigator.onLine) {
202
event.tags = {
203
...event.tags,
204
sent_offline: true,
205
};
206
}
207
return event;
208
},
209
});
210
```
211
212
### Custom Transport Implementation
213
214
```typescript
215
import { createTransport } from "@sentry/browser";
216
217
const customTransport = createTransport(
218
{
219
bufferSize: 30,
220
timeout: 5000,
221
},
222
async ({ body, url }) => {
223
// Custom request logic
224
const response = await fetch(url, {
225
method: "POST",
226
body,
227
headers: {
228
"Content-Type": "application/x-sentry-envelope",
229
"X-Custom-Header": "custom-value",
230
},
231
});
232
233
// Custom response handling
234
return {
235
statusCode: response.status,
236
headers: Object.fromEntries(response.headers.entries()),
237
};
238
}
239
);
240
241
Sentry.init({
242
dsn: "YOUR_DSN",
243
transport: customTransport,
244
});
245
```
246
247
### Multiplexed Transport
248
249
```typescript
250
import {
251
makeMultiplexedTransport,
252
makeFetchTransport
253
} from "@sentry/browser";
254
255
// Send events to multiple Sentry projects
256
const multiplexedTransport = makeMultiplexedTransport([
257
// Production Sentry
258
(options) => makeFetchTransport({
259
...options,
260
url: "https://ingest.sentry.io/api/PROD_PROJECT/envelope/",
261
}),
262
263
// Development Sentry
264
(options) => makeFetchTransport({
265
...options,
266
url: "https://ingest.sentry.io/api/DEV_PROJECT/envelope/",
267
}),
268
]);
269
270
Sentry.init({
271
dsn: "YOUR_DSN",
272
transport: multiplexedTransport,
273
});
274
```
275
276
## Offline Behavior
277
278
The offline transport automatically:
279
- Detects network connectivity
280
- Queues events when offline
281
- Retries failed requests
282
- Respects browser storage limits
283
- Clears old events when storage is full
284
285
### Offline Configuration
286
287
```typescript
288
// The offline transport uses browser storage
289
// Configure limits based on your needs
290
Sentry.init({
291
dsn: "YOUR_DSN",
292
transport: makeBrowserOfflineTransport(makeFetchTransport),
293
294
// Reduce event volume for offline scenarios
295
maxBreadcrumbs: 50, // Reduce breadcrumb storage
296
beforeSend(event) {
297
// Simplify events when offline
298
if (!navigator.onLine) {
299
// Remove large context data
300
delete event.contexts?.response;
301
delete event.extra?.largeData;
302
}
303
return event;
304
},
305
});
306
```
307
308
## Error Handling
309
310
Transport errors are handled gracefully:
311
312
```typescript
313
// Transport errors don't crash the application
314
// Events are dropped or queued for retry
315
316
// Monitor transport failures
317
Sentry.addEventProcessor((event) => {
318
// Add transport health data
319
event.extra = {
320
...event.extra,
321
transport_health: {
322
online: navigator.onLine,
323
last_sent: localStorage.getItem("sentry_last_sent"),
324
},
325
};
326
return event;
327
});
328
```
329
330
## Best Practices
331
332
### Performance Optimization
333
334
```typescript
335
// Optimize transport for performance
336
Sentry.init({
337
dsn: "YOUR_DSN",
338
transport: makeFetchTransport({
339
fetchOptions: {
340
keepalive: true, // Reuse connections
341
},
342
}),
343
344
// Reduce network load
345
maxBreadcrumbs: 20,
346
beforeSend(event) {
347
// Compress large context data
348
if (event.contexts?.response?.data) {
349
event.contexts.response.data = "[Compressed]";
350
}
351
return event;
352
},
353
});
354
```
355
356
### Network Reliability
357
358
```typescript
359
// Use offline transport with custom retry logic
360
const reliableTransport = makeBrowserOfflineTransport(
361
(options) => makeFetchTransport({
362
...options,
363
fetchOptions: {
364
timeout: 15000, // Longer timeout for reliability
365
retry: 3, // Retry failed requests
366
},
367
})
368
);
369
370
Sentry.init({
371
dsn: "YOUR_DSN",
372
transport: reliableTransport,
373
});
374
```