OpenTelemetry Browser SDK for Uptrace

This guide explains how to configure the OpenTelemetry JavaScript SDK for web browsers to export spans and metrics to Uptrace using OTLP/HTTP. You'll learn how to instrument your web applications for effective client-side monitoring and observability.

If you need to monitor JavaScript web applications, using Sentry SDK instead of OpenTelemetry JS might provide better results for error tracking and user experience monitoring.

To learn about the OpenTelemetry API, see OpenTelemetry JS Tracing API and OpenTelemetry JS Metrics API.

Prerequisites

Before you begin, ensure you have:

  • A web application running in modern browsers (supporting ES2022)
  • An Uptrace account with a valid DSN (Data Source Name)
  • A build system that supports ES6 modules (Webpack, Vite, Rollup, etc.)

Uptrace Web SDK

uptrace-js is a lightweight wrapper around opentelemetry-js that pre-configures the OpenTelemetry SDK to export data to Uptrace. It doesn't add new functionality but simplifies the setup process for your convenience.

Installation

To install @uptrace/web:

shell
# npm npm install @uptrace/web --save-dev  # yarn yarn add @uptrace/web --dev 

Configuration

Configure the Uptrace client using a DSN (Data Source Name) from your project settings page. Replace <FIXME> with your actual Uptrace DSN.

js
import { getWebAutoInstrumentations } from '@opentelemetry/auto-instrumentations-web' import { configureOpentelemetry } from '@uptrace/web'  // configureOpentelemetry automatically sets up window.onerror handler. const sdk = configureOpentelemetry({  // Set dsn or UPTRACE_DSN env var.  dsn: '<FIXME>',   serviceName: 'myservice',  serviceVersion: '1.0.0',   instrumentations: [getWebAutoInstrumentations({})], }) sdk.start() 

You can use the following options to configure Uptrace client.

OptionDescription
dsnA data source that is used to connect to uptrace.dev. For example, https://<token>@uptrace.dev/<project_id>.
serviceNameservice.name resource attribute. For example, myservice.
serviceVersionservice.version resource attribute. For example, 1.0.0.
deploymentEnvironmentdeployment.environment resource attribute. For example, production.
resourceAttributesAny other resource attributes.
resourceResource contains attributes representing an entity that produces telemetry. Resource attributes are copied to all spans and events.

Context Manager

ZoneContextManager is a context manager implementation based on the Zone.js library. It enables context propagation within the application using zones, which is particularly useful for tracking asynchronous operations in browsers.

Installation

To install the Zone.js context manager:

shell
npm install --save @opentelemetry/context-zone 

Usage

To use the Zone.js context manager:

js
import { ZoneContextManager } from '@opentelemetry/context-zone'  configureOpentelemetry({  contextManager: new ZoneContextManager(), }) 

Benefits of Zone.js context manager:

  • Automatic context propagation across async operations
  • Better trace correlation for setTimeout, Promise chains, and event handlers
  • Improved debugging capabilities for complex web applications

Instrumentations

OpenTelemetry provides several instrumentations specifically designed for browser environments to automatically capture telemetry data from common web APIs and user interactions.

Available Instrumentations

  • Fetch API: Automatically instruments fetch() requests
  • XMLHttpRequest: Instruments traditional AJAX requests
  • Document Load: Monitors page load performance

For additional instrumentations, see the OpenTelemetry JS web plugins documentation.

Basic Setup

You can use configureOpentelemetry to register individual instrumentations:

js
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch' import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request'  const sdk = configureOpentelemetry({  instrumentations: [  new FetchInstrumentation(),  new XMLHttpRequestInstrumentation(),  ], }) sdk.start() 

To automatically register all available web instrumentations:

js
import { getWebAutoInstrumentations } from '@opentelemetry/auto-instrumentations-web'  const sdk = configureOpentelemetry({  instrumentations: [getWebAutoInstrumentations({})], }) sdk.start() 

Alternative Method

You can also use registerInstrumentations directly:

js
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch' import { registerInstrumentations } from '@opentelemetry/instrumentation'  registerInstrumentations({  instrumentations: [new FetchInstrumentation()], }) 

See the OpenTelemetry JS web plugins for the full list of available instrumentations.

Advanced Configuration

Configure instrumentations with custom options:

js
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch'  configureOpentelemetry({  instrumentations: [  new FetchInstrumentation({  // Ignore requests to specific URLs  ignoreUrls: [/\/analytics/, /\/tracking/],  // Add custom attributes  requestHook: (span, request) => {  span.setAttribute('custom.request.type', 'api')  },  }),  ], }) 

Framework Integrations

Instrumenting Vue.js 2.x

Integrate OpenTelemetry with Vue.js applications for comprehensive error tracking:

js
import Vue from 'vue' import { configureOpentelemetry } from '@uptrace/web'  const sdk = configureOpentelemetry({  dsn: '<FIXME>', }) sdk.start()  Vue.config.errorHandler = (err, vm, info) => {  sdk.reportException(err, {  vm: vm,  info: info,  }) } 

Instrumenting React

For React applications, you can set up error tracking with OpenTelemetry:

js
import React from 'react' import { configureOpentelemetry } from '@uptrace/web' import { trace } from '@opentelemetry/api'  const sdk = configureOpentelemetry({  dsn: '<FIXME>', }) sdk.start()  const tracer = trace.getTracer('react-app', '1.0.0')  class ErrorBoundary extends React.Component {  constructor(props) {  super(props)  this.state = { hasError: false }  }   static getDerivedStateFromError(error) {  return { hasError: true }  }   componentDidCatch(error, errorInfo) {  const span = tracer.startSpan('react.error')  span.recordException(error)  span.setAttributes({  'error.component': errorInfo.componentStack,  })  span.end()  }   render() {  if (this.state.hasError) {  return <h1>Something went wrong.</h1>  }  return this.props.children  } } 

Manual Instrumentation

Create custom spans for specific user interactions or business logic:

js
import { trace } from '@opentelemetry/api'  const tracer = trace.getTracer('web-app', '1.0.0')  function trackUserAction(actionName) {  const span = tracer.startSpan(`user.${actionName}`)   span.setAttributes({  'user.action': actionName,  'page.url': window.location.href,  'user.agent': navigator.userAgent,  })   // Your business logic here   span.end() }  // Usage document.getElementById('submit-button').addEventListener('click', () => {  trackUserAction('form_submit') }) 

Performance Monitoring

Monitor key performance metrics in your web application:

js
import { trace, metrics } from '@opentelemetry/api'  const tracer = trace.getTracer('web-performance', '1.0.0') const meter = metrics.getMeter('web-performance', '1.0.0')  // Create metrics const pageLoadTime = meter.createHistogram('page.load_time', {  description: 'Page load time in milliseconds', })  // Measure page load time window.addEventListener('load', () => {  const loadTime =  performance.timing.loadEventEnd - performance.timing.navigationStart  pageLoadTime.record(loadTime, {  'page.url': window.location.pathname,  }) }) 

Querying Data

Once your browser application is instrumented and sending data to Uptrace, you can analyze user behavior and performance:

Browser-Specific Span Analysis

  • Network requests: Monitor API calls, resource loading, and external service dependencies
  • User interactions: Track clicks, form submissions, and navigation patterns
  • Performance bottlenecks: Identify slow-loading resources and long-running JavaScript tasks
  • Error tracking: Analyze client-side errors and their impact on user experience

Client-Side Metrics

  • Page load metrics: Monitor loading performance and user experience
  • User engagement: Track session duration, page views, and interaction patterns
  • Resource performance: Analyze loading times for various assets
  • Error rates: Monitor client-side error frequency and patterns

Cross-Platform Correlation

  • Full-stack tracing: Correlate browser spans with backend API calls
  • User journey tracking: Follow user interactions across multiple pages and services
  • Error propagation: Track how client-side errors relate to server-side issues

Verifying Your Setup

After configuration, your browser application will start sending telemetry data to Uptrace. To verify the setup:

  1. Load your application in a browser with developer tools open
  2. Interact with your application by clicking buttons, making requests, or navigating between pages
  3. Check the Network tab for requests to https://api.uptrace.dev/v1/traces
  4. View traces in Uptrace within 1-2 minutes of generating activity

Troubleshooting

If OpenTelemetry is not working as expected, you can enable verbose logging to check for potential issues:

js
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'  diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG) 

Browser-Specific Issues

CORS errors:

  • Ensure your Uptrace project allows requests from your domain
  • Check that the browser is not blocking requests due to CORS policy
  • Verify that your DSN is correctly configured

Bundle size concerns:

  • Use tree-shaking to include only necessary OpenTelemetry packages
  • Consider lazy-loading instrumentation for non-critical paths
  • Monitor the impact on your application's bundle size

Performance impact:

  • Configure appropriate sampling rates to reduce overhead
  • Use batch processors to minimize network requests
  • Test performance impact in production-like environments

Ad blockers:

  • Some ad blockers may interfere with telemetry data collection
  • Consider using a custom subdomain for telemetry endpoints
  • Provide fallback mechanisms for when telemetry is blocked

What's Next?

Next, instrument more operations to get a more detailed picture. Try to prioritize network calls, disk operations, database queries, errors, and logs.