@dynatrace/rum-javascript-sdk 1.331.18 → 1.333.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,405 @@
1
+ ---
2
+ title: RUM JavaScript SDK Overview
3
+ ---
4
+ # @dynatrace/rum-javascript-sdk
5
+
6
+ A JavaScript API for interacting with the Dynatrace Real User Monitoring (RUM) JavaScript. This package provides both synchronous and asynchronous wrappers for the Dynatrace RUM API, along with TypeScript support and testing utilities.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install @dynatrace/rum-javascript-sdk
12
+ ```
13
+
14
+ ## Overview
15
+
16
+ This package provides two main API approaches for interacting with the Dynatrace RUM JavaScript, as well as types and a Playwright testing framework:
17
+
18
+ - **Synchronous API**: Safe wrapper functions that gracefully handle cases where the RUM JavaScript is not available
19
+ - **Asynchronous API**: Promise-based functions that wait for the RUM JavaScript to become available
20
+ - **User Actions API**: Manual control over user action creation and lifecycle (see [User Actions API](./4-useractions.md))
21
+ - **TypeScript Support**: Comprehensive type definitions for all RUM API functions
22
+ - **Testing Framework**: Playwright-based utilities for testing RUM integration
23
+
24
+ ## Quick Start
25
+
26
+ ### Synchronous API (Recommended for most use cases)
27
+
28
+ ```typescript
29
+ import { sendEvent, identifyUser } from '@dynatrace/rum-javascript-sdk/api';
30
+
31
+ // Send a custom event - safely handles cases where RUM JavaScript is not loaded
32
+ sendEvent({
33
+ 'event_properties.component_name': 'UserProfile',
34
+ 'event_properties.action': 'view'
35
+ });
36
+
37
+ // Identify the current user
38
+ identifyUser('user@example.com');
39
+ ```
40
+
41
+ ### Asynchronous API (When you need to ensure RUM JavaScript is available)
42
+
43
+ ```typescript
44
+ import { sendEvent, identifyUser } from '@dynatrace/rum-javascript-sdk/api/promises';
45
+
46
+ try {
47
+ // Wait for RUM JavaScript to be available (with 10s timeout by default)
48
+ await sendEvent({
49
+ 'event_properties.component_name': 'UserProfile',
50
+ 'event_properties.action': 'view'
51
+ });
52
+
53
+ await identifyUser('user@example.com');
54
+ } catch (error) {
55
+ console.error('RUM JavaScript not available:', error);
56
+ }
57
+ ```
58
+
59
+ ## API Reference
60
+
61
+ ### Synchronous API (`@dynatrace/rum-javascript-sdk/api`)
62
+
63
+ The synchronous API provides safe wrapper functions that gracefully handle cases where the Dynatrace RUM JavaScript is not available. These functions will execute as no-ops if the JavaScript is not loaded, making them safe to use in any environment.
64
+
65
+ #### `sendEvent(fields, eventContext?): void`
66
+
67
+ Sends a custom event to Dynatrace RUM.
68
+
69
+ **Parameters:**
70
+ - `fields: ApiCreatedEventPropertiesEvent` - Event properties object. Must be serializable JSON with properties prefixed with `event_properties.`, plus optional `duration` and `start_time` properties.
71
+ - `eventContext?: unknown` - Optional context for event modification callbacks.
72
+
73
+ **Example:**
74
+ ```typescript
75
+ import { sendEvent } from '@dynatrace/rum-javascript-sdk/api';
76
+
77
+ sendEvent({
78
+ 'event_properties.page_name': 'checkout',
79
+ 'event_properties.step': 'payment',
80
+ 'event_properties.amount': 99.99,
81
+ 'duration': 1500,
82
+ 'start_time': Date.now()
83
+ });
84
+ ```
85
+
86
+ #### `addEventModifier(eventModifier): Unsubscriber | undefined`
87
+
88
+ Registers a function to modify events before they are sent to Dynatrace.
89
+
90
+ **Parameters:**
91
+ - `eventModifier: (jsonEvent: Readonly<JSONEvent>, eventContext?: EventContext) => JSONEvent | null` - Function that receives an event and returns a modified version or null to cancel the event.
92
+
93
+ **Returns:**
94
+ - `Unsubscriber | undefined` - Function to remove the modifier, or undefined if the RUM JavaScript is not available.
95
+
96
+ **Example:**
97
+ ```typescript
98
+ import { addEventModifier } from '@dynatrace/rum-javascript-sdk/api';
99
+
100
+ const unsubscribe = addEventModifier((event, context) => {
101
+ // Add user context to all events
102
+ return {
103
+ ...event,
104
+ 'event_properties.user_tier': 'premium'
105
+ };
106
+ });
107
+
108
+ // Later, remove the modifier
109
+ unsubscribe?.();
110
+ ```
111
+
112
+ #### `runHealthCheck(config?): Promise<unknown[] | undefined> | undefined`
113
+
114
+ Runs a health check on the RUM JavaScript to diagnose potential issues.
115
+
116
+ **Parameters:**
117
+ - `config?: HealthCheckConfig` - Optional configuration object:
118
+ - `logVerbose?: boolean` - Include verbose information in the health check
119
+ - `returnDiagnosticData?: boolean` - Return diagnostic data as array instead of just logging
120
+ - `runDetailedOverrideCheck?: boolean` - Log additional information about overridden native APIs
121
+
122
+ **Returns:**
123
+ - `Promise<unknown[] | undefined> | undefined` - Promise resolving to diagnostic data (if requested), or undefined if the RUM JavaScript is not available.
124
+
125
+ **Example:**
126
+ ```typescript
127
+ import { runHealthCheck } from '@dynatrace/rum-javascript-sdk/api';
128
+
129
+ const diagnostics = await runHealthCheck({
130
+ logVerbose: true,
131
+ returnDiagnosticData: true
132
+ });
133
+
134
+ if (diagnostics) {
135
+ console.log('RUM Health Check Results:', diagnostics);
136
+ }
137
+ ```
138
+
139
+ #### `identifyUser(value): void`
140
+
141
+ Associates the current session with a specific user identifier.
142
+
143
+ **Parameters:**
144
+ - `value: string` - User identifier (name, email, user ID, etc.)
145
+
146
+ **Example:**
147
+ ```typescript
148
+ import { identifyUser } from '@dynatrace/rum-javascript-sdk/api';
149
+
150
+ // Identify user after login
151
+ identifyUser('john.doe@example.com');
152
+ ```
153
+
154
+ #### `sendSessionPropertyEvent(fields): void`
155
+
156
+ Sends session-level properties that will be attached to all subsequent events in the session.
157
+
158
+ **Parameters:**
159
+ - `fields: ApiCreatedSessionPropertiesEvent` - Session properties object. All keys must be prefixed with `session_properties.` and follow naming conventions (lowercase, numbers, underscores, dots).
160
+
161
+ **Example:**
162
+ ```typescript
163
+ import { sendSessionPropertyEvent } from '@dynatrace/rum-javascript-sdk/api';
164
+
165
+ sendSessionPropertyEvent({
166
+ 'session_properties.user_type': 'premium',
167
+ 'session_properties.subscription_tier': 'gold',
168
+ 'session_properties.region': 'us_east'
169
+ });
170
+ ```
171
+
172
+ #### `sendExceptionEvent(error, fields?): void`
173
+
174
+ Sends an exception event. Marks the exception event with `characteristics.is_api_reported` and `error.source` = `api` to make it clear on DQL side where errors are coming from.
175
+ Only available if the Errors module is enabled.
176
+
177
+ **Parameters:**
178
+
179
+ - `error: Error` - The error object to report. Must be an instance of the standard JavaScript `Error` class.
180
+ - `fields: ApiCreatedEventPropertiesEvent` - Optional Event properties object. Must be serializable JSON with properties prefixed with `event_properties.`, plus optional `duration` and `start_time` properties.
181
+
182
+ **Example:**
183
+ ```typescript
184
+ import { sendExceptionEvent } from '@dynatrace/rum-javascript-sdk/api';
185
+
186
+ const yourError = new Error("Your Error Message");
187
+
188
+ sendExceptionEvent(yourError);
189
+ ```
190
+ ```typescript
191
+ import { sendExceptionEvent } from '@dynatrace/rum-javascript-sdk/api';
192
+
193
+ const yourError = new Error("Your Error Message");
194
+
195
+ sendExceptionEvent(yourError, { "event_properties.component": "myExampleComponent" });
196
+ ```
197
+
198
+ ### Asynchronous API (`@dynatrace/rum-javascript-sdk/promises`)
199
+
200
+ The asynchronous API provides Promise-based functions that wait for the Dynatrace RUM JavaScript to become available. These functions will throw a `DynatraceError` if the RUM JavaScript is not available within the specified timeout. This is useful for scenarios where you don't want to
201
+ enable the RUM JavaScript before the user gives their consent.
202
+
203
+ #### `sendEvent(fields, eventContext?, timeout?): Promise<void>`
204
+
205
+ Async wrapper for sending custom events, with automatic waiting for RUM JavaScript availability.
206
+
207
+ **Parameters:**
208
+ - `fields: ApiCreatedEventPropertiesEvent` - Event properties object
209
+ - `eventContext?: unknown` - Optional context for event modification callbacks
210
+ - `timeout?: number` - Timeout in milliseconds to wait for RUM JavaScript (default: 10,000)
211
+
212
+ **Throws:**
213
+ - `DynatraceError` - If RUM JavaScript is not available within timeout
214
+
215
+ **Example:**
216
+ ```typescript
217
+ import { sendEvent } from '@dynatrace/rum-javascript-sdk/api/promises';
218
+
219
+ try {
220
+ await sendEvent({
221
+ 'event_properties.conversion': 'purchase',
222
+ 'event_properties.value': 149.99
223
+ }, undefined, 15000); // 15 second timeout
224
+ } catch (error) {
225
+ console.error('Failed to send event:', error.message);
226
+ }
227
+ ```
228
+
229
+ #### `addEventModifier(eventModifier, timeout?): Promise<Unsubscriber>`
230
+
231
+ Async wrapper for registering event modifiers, with automatic waiting for RUM JavaScript availability.
232
+
233
+ **Parameters:**
234
+ - `eventModifier: (jsonEvent: Readonly<JSONEvent>, eventContext?: EventContext) => JSONEvent | null` - Event modifier function
235
+ - `timeout?: number` - Timeout in milliseconds to wait for RUM JavaScript (default: 10,000)
236
+
237
+ **Returns:**
238
+ - `Promise<Unsubscriber>` - Promise resolving to unsubscriber function
239
+
240
+ **Example:**
241
+ ```typescript
242
+ import { addEventModifier } from '@dynatrace/rum-javascript-sdk/api/promises';
243
+
244
+ const unsubscribe = await addEventModifier((event) => ({
245
+ ...event,
246
+ 'event_properties.environment': 'production'
247
+ }));
248
+ ```
249
+
250
+ #### `runHealthCheck(config?, timeout?): Promise<unknown[] | undefined>`
251
+
252
+ Async wrapper for running health checks, with automatic waiting for RUM JavaScript availability.
253
+
254
+ **Parameters:**
255
+ - `config?: HealthCheckConfig` - Optional health check configuration
256
+ - `timeout?: number` - Timeout in milliseconds to wait for RUM JavaScript (default: 10,000)
257
+
258
+ **Returns:**
259
+ - `Promise<unknown[] | undefined>` - Promise resolving to diagnostic data
260
+
261
+ #### `identifyUser(value, timeout?): Promise<void>`
262
+
263
+ Async wrapper for user identification, with automatic waiting for RUM JavaScript availability.
264
+
265
+ **Parameters:**
266
+ - `value: string` - User identifier
267
+ - `timeout?: number` - Timeout in milliseconds to wait for RUM JavaScript (default: 10,000)
268
+
269
+ #### `sendSessionPropertyEvent(fields, timeout?): Promise<void>`
270
+
271
+ Async wrapper for sending session properties, with automatic waiting for RUM JavaScript availability.
272
+
273
+ **Parameters:**
274
+ - `fields: ApiCreatedSessionPropertiesEvent` - Session properties object
275
+ - `timeout?: number` - Timeout in milliseconds to wait for RUM JavaScript (default: 10,000)
276
+
277
+ #### `sendExceptionEvent(error, fields?): void`
278
+
279
+ Async wrapper for sending an exception event, with automatic waiting for RUM JavaScript availability.
280
+ Marks the exception event with `characteristics.is_api_reported` and `error.source` = `api` to make it clear on DQL side where errors are coming from.
281
+ Only available if the Errors module is enabled.
282
+
283
+ **Parameters:**
284
+
285
+ - `error: Error` - The error object to report. Must be an instance of the standard JavaScript `Error` class.
286
+ - `fields: ApiCreatedEventPropertiesEvent` - Optional Event properties object. Must be serializable JSON with properties prefixed with `event_properties.`, plus optional `duration` and `start_time` properties.
287
+
288
+ ### User Actions API
289
+
290
+ Both synchronous and asynchronous wrappers are available for the User Actions API. For detailed documentation and examples, see [User Actions API](./4-useractions.md).
291
+
292
+ **Synchronous API:**
293
+ ```typescript
294
+ import {
295
+ createUserAction,
296
+ subscribeToUserActions,
297
+ setAutomaticUserActionDetection,
298
+ getCurrentUserAction
299
+ } from '@dynatrace/rum-javascript-sdk/api';
300
+
301
+ // Create a manual user action
302
+ const userAction = createUserAction({ autoClose: false });
303
+ // perform work
304
+ userAction?.finish();
305
+ ```
306
+
307
+ **Asynchronous API:**
308
+ ```typescript
309
+ import { createUserAction } from '@dynatrace/rum-javascript-sdk/api/promises';
310
+
311
+ const userAction = await createUserAction({ autoClose: false });
312
+ // perform work
313
+ userAction.finish();
314
+ ```
315
+
316
+ ## Error Handling
317
+
318
+ ### DynatraceError
319
+
320
+ Both APIs export a `DynatraceError` class for handling RUM-specific errors:
321
+
322
+ ```typescript
323
+ import { sendEvent, DynatraceError } from '@dynatrace/rum-javascript-sdk/promises';
324
+
325
+ try {
326
+ await sendEvent({ 'event_properties.test': 'value' });
327
+ } catch (error) {
328
+ if (error instanceof DynatraceError) {
329
+ console.error('RUM API Error:', error.message);
330
+ // Handle RUM-specific error
331
+ } else {
332
+ console.error('Unexpected error:', error);
333
+ }
334
+ }
335
+ ```
336
+
337
+ ## TypeScript Support
338
+
339
+ For detailed type information and usage examples, see [Dynatrace Api Types](./3-types.md).
340
+
341
+ ```typescript
342
+ import type {
343
+ ApiCreatedEventPropertiesEvent,
344
+ ApiCreatedSessionPropertiesEvent,
345
+ HealthCheckConfig,
346
+ JSONEvent,
347
+ EventContext
348
+ } from '@dynatrace/rum-javascript-sdk/types';
349
+ ```
350
+
351
+ ## Testing
352
+
353
+ This package includes a Playwright testing framework for validating RUM integration. See **[Testing with Playwright](./2-testing.md)** for complete documentation including:
354
+
355
+ - Setup and configuration
356
+ - Fixture usage and ordering
357
+ - Event assertion methods
358
+ - Troubleshooting guide
359
+
360
+ ## Best Practices
361
+
362
+ ### When to Use Synchronous vs Asynchronous API
363
+
364
+ **Use Synchronous API when:**
365
+ - You want graceful degradation when the RUM JavaScript is not available
366
+ - You're instrumenting existing code and don't want to change control flow
367
+ - You're okay with events being dropped if the RUM JavaScript isn't loaded
368
+
369
+ **Use Asynchronous API when:**
370
+ - You need to ensure events are actually sent
371
+ - You want to handle RUM JavaScript availability errors explicitly
372
+ - You're building critical instrumentation that must not fail silently
373
+
374
+ ### Event Property Naming
375
+
376
+ Follow prefix custom event properties with `event_properties.`:
377
+
378
+ ```typescript
379
+ // ✅ Good - properties with prefix are accepted
380
+ sendEvent({
381
+ 'event_properties.action': 'login',
382
+ 'event_properties.method': 'oauth',
383
+ 'event_properties.page_name': 'dashboard',
384
+ 'event_properties.load_time': 1234
385
+ });
386
+
387
+ // ❌ Avoid - properties without prefix are ignored
388
+ sendEvent({
389
+ 'action': 'click',
390
+ 'data': 'some_value'
391
+ });
392
+ ```
393
+
394
+ ### Session Properties
395
+
396
+ Use session properties for data that applies to the entire user session:
397
+
398
+ ```typescript
399
+ // Set once per session
400
+ sendSessionPropertyEvent({
401
+ 'session_properties.subscription_type': 'premium',
402
+ 'session_properties.region': 'europe',
403
+ 'session_properties.app_version': '2.1.0'
404
+ });
405
+ ```