Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
108 changes: 108 additions & 0 deletions docs/reference/edot-browser/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
navigation_title: Configuration
description: Configure the Elastic Distribution of OpenTelemetry Browser (EDOT Browser).
applies_to:
stack: ga
serverless:
observability: ga
products:
- id: cloud-serverless
- id: observability
- id: edot-sdk
---

# Configure EDOT Browser

This page explains how to configure EDOT Browser, which settings are supported, and what’s required to start exporting browser telemetry.

EDOT Browser follows OpenTelemetry configuration conventions where possible. Like the upstream OpenTelemetry Browser SDK, it uses explicit configuration at initialization rather than environment variables, which are not available in the browser.

## Configuration model in the browser [configuration-model-in-the-browser]

EDOT Browser runs in your users’ browsers. This has important implications:

- Environment variables exist at build time, when your app is bundled. For example, a bundler replaces `process.env.*` with values. However, the variables are not available at runtime, meaning when the app runs in the browser. You can provide configuration at build time (bundler-defined constants) or at runtime (options passed to the initialization function).
- Never embed secrets in browser configuration.

EDOT Browser does not read `OTEL_*` variables directly. Instead, it accepts configuration values passed explicitly during initialization.

### Common configuration patterns

Typical configuration patterns include:

- Passing configuration from a server-rendered page.
- Loading configuration from a global object populated at runtime.

The best approach depends on your application architecture and build tooling.

## Supported configuration settings [supported-configuration-settings]

Configuration is passed as an object to `startBrowserSdk`. The following options are supported:

| Option | Description |
|---|---|
| `serviceName` | Logical name of the frontend service. Defaults to `unknown_service:web` if not set. |
| `serviceVersion` | Version of the application. Optional. |
| `logLevel` | Diagnostic log level (`error`, `warn`, `info`, `debug`, `verbose`). Defaults to `info`. |
| `otlpEndpoint` | Base URL of the OTLP export endpoint (reverse proxy). Do not include signal paths such as `/v1/traces`. Defaults to `http://localhost:4318`. |
| `sampleRate` | Trace sampling ratio (0–1). Defaults to `1` (100%). |
| `resourceAttributes` | Optional resource attributes to attach to telemetry. |
| `exportHeaders` | Headers to send with export requests. Defaults to `{}`. The reverse proxy typically injects `Authorization`; do not put API keys here in browser code. |
| `disabled` | If `true`, the SDK does not start. |
| `configInstrumentations` | Per-instrumentation config. Set `enabled: false` for a key to turn off that instrumentation. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: this is still in discussion and it may include sub-properties that need to be described in this table


## Minimal required configuration [minimal-required-configuration]

At a minimum, EDOT Browser requires:

- A service name to identify the frontend application
- An export endpoint that points to a reverse proxy

You can also set a log level, which is recommended during setup.

```js
import { startBrowserSdk } from '@elastic/opentelemetry-browser';

startBrowserSdk({
serviceName: 'my-web-app',
otlpEndpoint: 'https://telemetry.example.com',
logLevel: 'info',
});
```

- `serviceName` identifies the browser application in {{product.observability}}.
- `otlpEndpoint` points to a reverse proxy, not directly to {{product.observability}}.
- `logLevel` controls diagnostic output in the browser console.

## Export endpoint configuration [export-endpoint-configuration]

Configure `otlpEndpoint` to point to a reverse proxy that forwards OTLP traffic to {{product.observability}}. Use the base URL of the proxy only: do not include signal paths such as `/v1/traces`, `/v1/metrics`, or `/v1/logs`. The SDK appends these paths when exporting each signal.

Use a service name that identifies your frontend application and doesn't contain special characters, so that data is correctly categorized in {{product.observability}}.

For details on reverse proxy and authorization, refer to [OpenTelemetry for Real User Monitoring (RUM)](docs-content://solutions/observability/applications/otel-rum.md).

## Logging and diagnostics [logging-and-diagnostics]

EDOT Browser uses the OpenTelemetry diagnostic logger.

To troubleshoot setup issues, increase the log level when calling `startBrowserSdk`:

```js
import { startBrowserSdk } from '@elastic/opentelemetry-browser';

startBrowserSdk({
serviceName: 'my-web-app',
otlpEndpoint: 'https://telemetry.example.com',
logLevel: 'debug',
});
```

Diagnostic logs are written to the browser console. For more information on using debug logging to troubleshoot issues, refer to [Enable debug logging for EDOT SDKs](docs-content://troubleshoot/ingest/opentelemetry/edot-sdks/enable-debug-logging.md) and [Enable debug logging](docs-content://troubleshoot/ingest/opentelemetry/edot-collector/enable-debug-logging.md) (Collector).

## Next steps [next-steps]

- Refer to [Install the agent](install-agent.md) and [Proxy and CORS](proxy-cors.md) for installation and proxy configuration.
- Refer to [Metrics, traces, and logs](telemetry.md) for what each signal emits and limitations.
- Review [Supported technologies](supported-technologies.md) for browser and instrumentation support.
- Refer to [Troubleshooting](troubleshooting.md) for EDOT Browser–specific issues, or [OpenTelemetry ingest troubleshooting](docs-content://troubleshoot/ingest/opentelemetry/index.md) for general OTLP ingest issues.
62 changes: 62 additions & 0 deletions docs/reference/edot-browser/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
navigation_title: EDOT Browser
description: Overview of the Elastic Distribution of OpenTelemetry Browser (EDOT Browser).
applies_to:
stack: ga
serverless:
observability: ga
products:
- id: cloud-serverless
- id: observability
- id: edot-sdk
---

# {{edot}} Browser

EDOT Browser is Elastic’s distribution of the OpenTelemetry Browser SDK. It provides a bundled, opinionated setup for collecting traces, metrics, and logs from real user interactions in web applications and exporting that data to {{product.observability}} using the OpenTelemetry Protocol (OTLP).

EDOT Browser is intended for Real User Monitoring (RUM) use cases, where telemetry is collected directly from users’ browsers to understand frontend performance, user interactions, and end-to-end request flows between frontend and backend services. It is based on OpenTelemetry standards and aims to align with contrib OpenTelemetry behavior.

EDOT Browser collects the following signals:

- **Traces**: For distributed tracing and frontend-to-backend correlation
- **Metrics**: Browser-side performance and runtime metrics
- **Logs**: Using the OpenTelemetry Logs API

For what each signal includes, known limitations, and what is not yet supported, refer to [Metrics, traces, and logs](telemetry.md).

## How it works [how-it-works]

EDOT Browser runs in the user's browser as part of your web application. When initialized, it instruments the page and captures telemetry from document load, user interactions, and network requests. Data is exported using the OpenTelemetry Protocol (OTLP) over HTTP to an endpoint you configure, typically a reverse proxy that injects authentication and forwards the data to {{product.observability}} or an OpenTelemetry Collector. Because the SDK runs in the browser, it cannot hold credentials. A reverse proxy is responsible for adding API keys or other auth before sending data to {{product.observability}}.

In {{product.observability}}, you see `external.http` spans for browser fetch and XHR requests, user interaction spans (such as click, submit) that group related frontend and backend activity, and end-to-end traces from the browser to your backend in Discover and Service Maps. For details, refer to [What to expect in {{kib}}](setup.md#what-to-expect-in-kibana) in the setup guide.

## Limitations [limitations]

The following capabilities are not currently available in EDOT Browser:

- Full feature parity with classic Elastic {{product.apm}} browser agents
- Migration tooling from classic agents

## Browser telemetry and authentication [browser-telemetry-and-authentication]

Because EDOT Browser runs in the user’s browser, it cannot safely embed authentication credentials such as API keys. Telemetry must be exported through a reverse proxy that sits between the browser and your OTLP endpoint ({{ecloud}} Managed OTLP or an EDOT Collector). The reverse proxy is required for three reasons:

- **Authentication**: The EDOT Collector or Managed OTLP endpoint expects an `Authorization` header with an API key. The reverse proxy injects the header so the key stays on the server and isn't exposed.
- **Cross-origin requests**: Your web application and the OTLP endpoint often have different origins. Browsers enforce Cross-Origin Resource Sharing (CORS), meaning that without the right headers, export requests are blocked. A reverse proxy on the same origin as your app (or configured to allow it) can add the required CORS headers and handle preflight `OPTIONS` requests.
- **Traffic control**: You can apply rate limiting or other controls at the proxy before traffic reaches the Collector or {{product.observability}}.

For reverse proxy and CORS configuration, refer to [Proxy and CORS](proxy-cors.md). For installation and initialization, refer to [Set up EDOT Browser](setup.md) and [Install the agent](install-agent.md).

:::{note}
Avoid using EDOT Browser alongside any other {{product.apm}} or RUM agent (including classic Elastic {{product.apm}} browser agents). Running multiple agents can cause conflicting instrumentation, duplicate telemetry, or unexpected behavior.
:::

## Next steps [next-steps]

To get started with EDOT Browser:

- Follow the setup instructions in [Set up EDOT Browser](setup.md): [Install the agent](install-agent.md) and [Configure proxy and CORS](proxy-cors.md)
- Review configuration options in [Configure EDOT Browser](configuration.md)
- Refer to [Supported technologies](supported-technologies.md) for details on browsers and instrumentations
- If telemetry does not appear, refer to [Troubleshooting](troubleshooting.md)
80 changes: 80 additions & 0 deletions docs/reference/edot-browser/install-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
navigation_title: Install the agent
description: Install and initialize the EDOT Browser agent (package or bundle).
applies_to:
stack: ga
serverless:
observability: ga
products:
- id: cloud-serverless
- id: observability
- id: edot-sdk
---

# Install the agent

EDOT Browser is distributed in two ways. The choice affects how you install it, how much control you have over instrumentations and bundle size, and how updates might affect your application.

## Package versus bundle [package-vs-bundle]

| Option | Best for | Trade-offs |
|--------|----------|------------|
| **Bundle** | Applications that don't use a bundler (single JS file loaded using script tag). | Works out of the box with no build step. Updating the bundle can introduce breaking changes when upstream instrumentations or configuration change. You have to absorb those changes when you upgrade. |
| **Package** | Applications that use a bundler (for example: webpack, Vite, Rollup). | You choose which instrumentations to include, so you have more control and can achieve a smaller bundle size by installing only what you need. You control when to upgrade instrumentations and can pin versions to avoid breaking changes until you are ready. |

Before installing, ensure you have [configured a reverse proxy and CORS](proxy-cors.md) so the browser can export telemetry securely.

## Install using the package [install-package]

Install EDOT Browser using your package manager:

```bash
npm install @elastic/opentelemetry-browser
```

When you use the package, your bundler includes only the code you import. You can control which instrumentations are enabled using configuration and, if the SDK supports it in the future, by passing only the instrumentation instances you need. This can reduce the final bundle size compared to the full bundle.

For supported bundlers and browser requirements, refer to [Supported technologies](supported-technologies.md).

## Install using the bundle [install-bundle]

A single JS bundle is available for script-tag usage (for example, from a CDN or your own host). Use it when your application doesn't use a bundler.

The bundle works out of the box: you add a script tag and initialize the SDK. When you update to a newer bundle version, upstream instrumentation or configuration changes might introduce breaking changes. You must test upgrades in a non-production environment.

<!-- TODO: add instructions and URL for the bundle when released -->

## Initialize EDOT Browser [initialize]

Initialize EDOT Browser as early as possible in your application lifecycle so it can capture initial page loads, user interactions, and network requests. Call `startBrowserSdk`:

- At the top of your application entry point
- In a framework-specific bootstrap location (for example, a React root component, Angular `main.ts`, or a Vue plugin)

Minimal example (package):

```js
import { startBrowserSdk } from '@elastic/opentelemetry-browser';

startBrowserSdk({
serviceName: 'my-web-app',
otlpEndpoint: 'https://telemetry.example.com', // reverse proxy URL; do not include /v1/traces or other signal paths
});
```

At a minimum, configure:

- `serviceName`: Identifies your frontend application in {{product.observability}}.
- `otlpEndpoint`: Must point to your reverse proxy (not directly to {{product.observability}}).

For all configuration options, refer to [Configure EDOT Browser](configuration.md).

## Verify setup [verify]

You have successfully set up EDOT Browser when the SDK loads without errors in the browser console and telemetry flows to your reverse proxy. To confirm data in {{product.observability}}, open {{kib}} and check for your service and traces. For what you see in the UI, refer to [What to expect in {{kib}}](setup.md#what-to-expect-in-kibana) in the setup guide.

## Next steps [next-steps]

- Refer to [Set up EDOT Browser](setup.md) for an overview and what to expect in {{kib}}.
- Refer to [Configure EDOT Browser](configuration.md) to customize behavior and defaults.
- Review [Supported technologies](supported-technologies.md) for browsers and instrumentations.
77 changes: 77 additions & 0 deletions docs/reference/edot-browser/proxy-cors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
navigation_title: Proxy and CORS
description: Configure a reverse proxy and CORS for EDOT Browser telemetry export.
applies_to:
stack: ga
serverless:
observability: ga
products:
- id: cloud-serverless
- id: observability
- id: edot-sdk
---

# Proxy and CORS configuration

EDOT Browser exports telemetry from the user's browser to an OTLP endpoint. You must put a reverse proxy in front of your OTLP endpoint and configure it for authentication and Cross-Origin Resource Sharing (CORS).

## Why a reverse proxy is required [why-reverse-proxy]

Do not send telemetry directly from the browser to {{product.observability}} with an API key in client-side code. Any credentials in browser code are visible to end users and can be misused. EDOT Browser requires a reverse proxy in front of the OTLP endpoint for these reasons:

- **Authentication**: The EDOT Collector or {{ecloud}} Managed OTLP endpoint expects an `Authorization` header with an API key. The reverse proxy injects the header so the key stays on the server and is not exposed to the browser.
- **Cross-origin requests**: Your web application and the OTLP endpoint often have different origins. Browsers enforce CORS, so without the right headers, export requests are blocked. A reverse proxy on the same origin as your app (or configured to allow it) can add the required CORS headers and handle preflight `OPTIONS` requests.
- **Traffic control**: You can apply rate limiting or other controls at the proxy before traffic reaches the Collector or {{product.observability}}.

For complete examples and security considerations, refer to [OpenTelemetry for Real User Monitoring (RUM)](docs-content://solutions/observability/applications/otel-rum.md).

## Content Security Policy (CSP) [content-security-policy]

If your site uses a Content Security Policy (CSP), add the domain of your reverse proxy or OTLP endpoint to the `connect-src` directive so the browser allows export requests. For example: `connect-src 'self' https://telemetry.example.com`.

## CORS requirements [cors-requirements]

When your web application and the export endpoint have different origins, the browser might block requests unless CORS is configured. Your reverse proxy must:

- Return `Access-Control-Allow-Origin` matching your application origin
- Respond to `OPTIONS` preflight requests with 204
- Include `Authorization` in `Access-Control-Allow-Headers` when using API key authentication

## Example: NGINX reverse proxy [example-nginx]

The following example forwards telemetry from `webapp.example.com` to an EDOT Collector at `collector.example.com`, injects the required `Authorization` header, and handles CORS preflight:

```nginx
server {
# Configuration for HTTP/HTTPS goes here
location / {
# Take care of preflight requests
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Access-Control-Allow-Origin' 'webapp.example.com' always;
add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Language,Authorization,Content-Language,Content-Type' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}

add_header 'Access-Control-Allow-Origin' 'webapp.example.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Language,Authorization,Content-Language,Content-Type' always;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Set the auth header for the Collector here. Follow security best practices
# for adding secrets (for example Docker secrets, Kubernetes Secrets).
proxy_set_header Authorization 'ApiKey ...your Elastic API key...';
proxy_pass https://collector.example.com:4318;
}
}
```

## Next steps [next-steps]

- [Install the agent](install-agent.md) and initialize EDOT Browser in your application.
- Refer to [Configure EDOT Browser](configuration.md) for initialization options.
Loading
Loading