Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b69c51e
refactor(http): extract propagator/error helpers from fetch.ts into s…
parker-edwards Jul 3, 2026
846b481
feat(xhr): add @dash0/xhr instrumentation name and wire stub into init()
parker-edwards Jul 3, 2026
8ad02d6
feat(xhr): implement XHR span creation, attributes, and header injection
parker-edwards Jul 3, 2026
ec1f29c
feat(xhr): implement XHR request completion (success/error/timeout/ab…
parker-edwards Jul 3, 2026
edd8896
fix(xhr): remove per-request event listeners on request completion
parker-edwards Jul 3, 2026
5313161
test(xhr): add e2e coverage for raw XHR, cross-origin propagation, an…
parker-edwards Jul 3, 2026
5c2eb81
test(xhr): verify X-Amzn-Trace-Id reaches the server in the XHR X-Ray…
parker-edwards Jul 3, 2026
4edd60f
docs: document XMLHttpRequest instrumentation alongside fetch
parker-edwards Jul 3, 2026
1c3880a
feat: add browser.interaction event name and interaction attribute keys
parker-edwards Jul 3, 2026
5c8aff7
feat: add pure action-name derivation for click instrumentation
parker-edwards Jul 3, 2026
11f8a2e
test: pin OPTION privacy exclusion and exact ancestor-walk cap boundary
parker-edwards Jul 3, 2026
aca18aa
feat: add config plumbing for interaction instrumentation
parker-edwards Jul 3, 2026
ffc7112
docs: clarify the double gate on interaction instrumentation enablement
parker-edwards Jul 3, 2026
2747d3d
feat: implement click capture, event construction, and transmission
parker-edwards Jul 3, 2026
d2a1423
feat: wire click instrumentation into the interactions composition root
parker-edwards Jul 3, 2026
e62e809
fix: apply selector length cap on the id-anchored path and pin select…
parker-edwards Jul 3, 2026
31945d3
test: add e2e fixture page for enabled interaction instrumentation
parker-edwards Jul 3, 2026
13833b6
test: add e2e fixture page for default-disabled interaction instrumen…
parker-edwards Jul 3, 2026
8c58101
test: add e2e spec covering interaction instrumentation click behavior
parker-edwards Jul 3, 2026
2a0b5d2
test: align interactions e2e with suite conventions (browser-error ch…
parker-edwards Jul 3, 2026
2680107
docs: document opt-in interaction instrumentation configuration
parker-edwards Jul 3, 2026
0fb5fee
Improve interaction capture quality and add scroll/keypress/change ev…
Jul 14, 2026
d69eaa5
Make scroll/key-press/change capture opt-in (default false)
parker-edwards Jul 20, 2026
da0ce33
Restrict HTTP span attribution to activation keys (Enter/Space)
parker-edwards Jul 20, 2026
fa87faa
test(interactions): align e2e expectations with plain-string body and…
parker-edwards Jul 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 65 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ These can all be passed via the Dash0 Web SDK's `init` call.

### Backend Correlation

The SDK supports trace context propagation to correlate frontend requests with backend services. You can configure
The SDK supports trace context propagation to correlate frontend requests with backend services, for both `fetch`
and `XMLHttpRequest` (including libraries built on XHR, such as axios's default browser adapter). You can configure
different header types (`traceparent`, `X-Amzn-Trace-Id`) for different endpoints using the `propagators` configuration.

> Misconfiguration of cross origin trace correlation can lead to request failures. Please make sure to carefully
Expand Down Expand Up @@ -243,7 +244,7 @@ The SDK enumerates the env vars above under every framework prefix the bundler e
optional: `true`<br>
default: `undefined`<br>
List of instrumentations to enable. Defaults to `undefined`, enabling all instrumentations.
Supported values: `'@dash0/navigation' | '@dash0/web-vitals' | '@dash0/error' | '@dash0/fetch'`
Supported values: `'@dash0/navigation' | '@dash0/web-vitals' | '@dash0/error' | '@dash0/fetch' | '@dash0/xhr' | '@dash0/interactions'`
Please note that some dash0 features might not work as expected if instrumentations are disabled.

- **Ignore URLs**<br>
Expand Down Expand Up @@ -541,6 +542,68 @@ The SDK auto-detects VCS (version control) context from the build environment an
- "HASH" changes to the urls hash / fragment
- "SEARCH" changes to the urls search / query parameters

#### Interaction instrumentation

Opt-in automatic capture of click interactions (Datadog RUM `trackUserInteractions` parity). Disabled by default --
set `interactionInstrumentation.enabled: true` to turn it on. When enabled, a single capture-phase listener on
`window` observes clicks anywhere on the page (no per-element wiring, no listener leakage) and emits a
`browser.interaction` web event per click with a derived, privacy-conscious interaction name and a compact
target-element selector.

- **Enable Interaction Instrumentation**<br>
key: `interactionInstrumentation.enabled`<br>
type: `boolean`<br>
optional: `true`<br>
default: `false`<br>
Whether the SDK should automatically capture click interactions. Also requires `'@dash0/interactions'` to be
present in `enabledInstrumentations` when that option is explicitly set (it is included by default when
`enabledInstrumentations` is left `undefined`).
- **Action Name Attribute**<br>
key: `interactionInstrumentation.actionNameAttribute`<br>
type: `string`<br>
optional: `true`<br>
default: `"data-dash0-action-name"`<br>
The element attribute the SDK checks first (on the clicked element or any of its ancestors) when deriving a
human-readable interaction name. Set this attribute on interactive elements for full control over the captured
name, e.g. `<button data-dash0-action-name="Save Settings">`.

**Name derivation priority** (first match wins, walking from the clicked element up to 10 ancestors, stopping at
the first `FORM`, `BODY`, `HTML`, or `HEAD` boundary):

1. `custom_attribute` -- the configured `actionNameAttribute`, on the target or a qualifying ancestor.
2. `standard_attribute` -- attribute-derived names checked on the target then ancestors: for `button`/`submit`/`reset`
inputs, `.value`; then `aria-label`, `aria-labelledby` (resolved via the referenced element(s)' text), `alt`,
`title`, or `placeholder`.
3. `text_content` -- visible text: first the text of clickable-tag elements (`BUTTON`, `LABEL`, `A`, or
`role="button"`) found while walking up from the target, then the target's own visible text. This fallback never
applies when the click target itself is an `INPUT`, `TEXTAREA`, `SELECT`, or `OPTION` element, since their text
content is user data rather than an action label.
4. `blank` -- an empty name, if nothing above matched.

Attribute-derived sources always outrank text: the full phase order is custom attribute → standard attributes
(walk) → text content (walk, then target) → blank. Each captured event's `name_source` attribute reflects which
phase produced the name.

**Privacy defaults (not configurable):** the SDK never reads the value of `password`, `text`, `textarea`, or
`select` elements -- only `button`/`submit`/`reset` inputs expose their value for name derivation, and the
text-content fallback above never applies to `INPUT`/`TEXTAREA`/`SELECT`/`OPTION` targets. Derived names are
whitespace-normalized and truncated to 100 characters. The target-element selector is independently capped at 128
characters.

Note: capturing interaction events requires both `interactionInstrumentation.enabled: true` **and**
`'@dash0/interactions'` present in `enabledInstrumentations` if that option is explicitly set to a non-default
list -- either gate alone is not sufficient.

```ts
init({
serviceName: "my-website",
endpoint: { url: "{OTLP via HTTP endpoint}", authToken: "{authToken}" },
interactionInstrumentation: {
enabled: true,
},
});
```

## API

The Dash0 Web SDK provides several API functions to help you customize telemetry collection and add contextual
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Features include:

- Page view instrumentation
- Navigation timing instrumentation
- HTTP request instrumentation
- HTTP request instrumentation (fetch and XMLHttpRequest)
- Error tracking

## Getting started
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"@wdio/mocha-framework": "^9.12.5",
"@wdio/sauce-service": "^9.12.5",
"@wdio/spec-reporter": "^9.12.3",
"axios": "^1.18.1",
"body-parser": "^2.2.0",
"dotenv-cli": "^8.0.0",
"eslint": "^9.24.0",
Expand Down
53 changes: 42 additions & 11 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/api/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import { startWebVitalsInstrumentation } from "../instrumentations/web-vitals";
import { startErrorInstrumentation } from "../instrumentations/errors";
import { addAttribute } from "../utils/otel";
import { instrumentFetch } from "../instrumentations/http/fetch";
import { instrumentXhr } from "../instrumentations/http/xhr";
import { startNavigationInstrumentation } from "../instrumentations/navigation";
import { startInteractionInstrumentation } from "../instrumentations/interactions";
import { initializeTabId } from "../utils/tab-id";
import { InitOptions, InstrumentationName } from "../types/options";
import { BrowserBuildEnv, pickFirstString } from "./browser-env";
Expand Down Expand Up @@ -85,6 +87,7 @@ export function init(opts: InitOptions) {
"headersToCapture",
"urlAttributeScrubber",
"pageViewInstrumentation",
"interactionInstrumentation",
"enableTransportCompression",
])
)
Expand Down Expand Up @@ -120,6 +123,13 @@ export function init(opts: InitOptions) {
if (isInstrumentationEnabled("@dash0/fetch", opts)) {
instrumentFetch();
}
if (isInstrumentationEnabled("@dash0/xhr", opts)) {
instrumentXhr();
}
// Both gates must pass: the instrumentation-name allowlist and the opt-in settings flag.
if (isInstrumentationEnabled("@dash0/interactions", opts) && vars.interactionInstrumentation.enabled) {
startInteractionInstrumentation();
}

hasBeenInitialised = true;
}
Expand Down
Loading
Loading