This topic documents how to get started with the LaunchDarkly observability plugins in an htmx application.
htmx is a lightweight library that lets you build modern web applications using HTML attributes to issue AJAX requests, handle events, and update the DOM, without writing JavaScript. htmx applications render server-provided html and text fragments without a JavaScript framework, so you can use the LaunchDarkly client-side JavaScript SDK directly in htmx applications.
The LaunchDarkly JavaScript SDK supports the following observability plugins:
LaunchDarkly’s observability and session replay plugins use DOM mutation observers to track changes when htmx swaps content in or out of the page. The plugins capture these changes automatically, requiring no additional configuration. To learn more, read How htmx works with observability.
LaunchDarkly’s SDKs are open source. In addition to this reference guide, we provide source, API reference documentation, and a sample application:
The session replay plugins are available only for the LaunchDarkly client-side JavaScript-based SDKs.
To learn more about LaunchDarkly’s different SDK types, read Choosing an SDK type.
This reference guide assumes that you are familiar with the LaunchDarkly JavaScript SDK and with htmx.
The observability plugin requires JavaScript SDK version 3.7.0 or later.
htmx applications differ from traditional single-page applications (SPAs) in important ways that affect observability:
hx-boost and hx-push-url attributes to update the browser URL, but does not use a client-side router.The observability plugins work well with htmx because they use DOM mutation observers to track changes. When htmx swaps content in or out of the page, the session replay plugin automatically captures these updates. No additional configuration is needed for basic observability and session replay.
Follow these steps to get started:
LaunchDarkly uses plugins to the JavaScript SDK to provide observability. Most customers use both the observability and session replay plugins. However, there is no dependency between them, and you can use only one or the other if you like.
The first step is to make both the SDK and the observability plugins available as dependencies.
If your htmx application uses a bundler such as Vite, esbuild, or webpack, install the packages with a package manager:
Then, import the plugins into your code:
If your htmx application does not use a bundler, you can load the SDK and plugins using <script> tags in your HTML. Add these to your base template’s <head> element so they load once and persist across all htmx navigations.
Do not use script tags with sources from unpkg or jsDelivr in production environments. These introduce a critical dependency on a third-party service. Use the unpkg and jsDelivr scripts only during development for ease of use when getting started.
In production environments, we strongly recommend that you self-host the JavaScript SDK and observability plugins alongside your other JavaScript resources. To learn more, read Make the SDK available with a script tag in the JavaScript SDK reference guide.
Next, initialize the SDK and the plugins.
To initialize, you need your LaunchDarkly environment’s client-side ID. This authorizes your application to connect to a particular environment within LaunchDarkly. To learn more, read Initialize the client in the JavaScript SDK reference guide.
The JavaScript observability SDK requires a client-side ID. Client-side IDs are specific to each project and environment. They are not secret, and you can include them in client-side code. Do not embed a server-side SDK key in a client-side application.
You can find client-side IDs and project keys on the SDK keys page under Settings. To learn more about key types, read Keys.
In an htmx application, you should initialize the SDK once, typically in your base HTML template or application entry point. The SDK persists across htmx navigations because htmx swaps DOM content rather than performing full page reloads.
Here’s how to initialize the SDK and plugins:
You can initialize the observability and session replay plugins manually, after the SDK client is initialized.
This approach supports feature-flagged rollouts or dynamic initialization after end user consent. Both plugins use a manualStart option combined with .start() calls.
First, configure the plugins with manualStart: true:
Then, start the plugins when appropriate, such as after receiving end user consent or when a feature flag enables observability.
Here’s an example starting the observability plugin:
Here’s an example with the session replay plugin:
This approach allows you to:
You can configure options for the observability plugins when you initialize the SDK. The plugin constructors take an optional object with the configuration details.
By default, session replays use the strict privacy setting, which obscures some data. Use none to turn off session replay obfuscation. This enables more detail on session replays, but may expose more of your customer data than your privacy or data retention policies allow. To learn more, read Session replay config.
Here is an example:
When networkRecording is enabled, the observability plugin automatically captures all HTTP requests made by htmx, including requests triggered by the hx-get, hx-post, hx-put, hx-patch, and hx-delete attributes. This gives you visibility into the performance and status of every htmx interaction.
For more information on plugin options, read Configuration for client-side observability and Configuration for session replay.
The session replay plugin uses DOM mutation observers to record changes. htmx updates the page by swapping HTML content in and out of the DOM, which the mutation observers capture automatically. This means session replay works out of the box with htmx, regardless of which swap strategy you use (innerHTML, outerHTML, beforebegin, afterend, and so forth).
If your htmx application uses hx-boost to convert standard links and forms into AJAX requests, the observability plugin handles these navigations correctly. The SDK stays initialized across boosted navigations because htmx swaps the page body content rather than performing a full page reload.
When hx-boost or hx-push-url updates the browser URL, the observability plugin detects this through the browser’s History API and tracks it as a navigation event.
The observability plugin automatically captures JavaScript errors through standard browser error handling. For htmx-specific errors, such as failed AJAX requests, the plugin captures these through network request monitoring when networkRecording is enabled.
If you want to track additional htmx-specific events, you can use the LDObserve API to log custom events:
In htmx applications, scripts loaded in the <head> element persist across hx-boost navigations by default. This means the LaunchDarkly SDK initializes once and continues running throughout the user’s session. You do not need to reinitialize the SDK when htmx swaps page content.
If you use the htmx head-support extension, be aware that it merges <head> elements during boosted navigations. Scripts that are textually identical are preserved and not re-executed. This is the correct behavior for the LaunchDarkly SDK.
If your application runs in an environment that enforces content security policies, you must set the Content-Security-Policy (CSP) in your application to tell the browser how your page can interact with third-party scripts.
Here are the policies you need to set to use the observability plugin:
connect-src: https://pub.observability.app.launchdarkly.com https://otel.observability.app.launchdarkly.com: This policy allows connecting with LaunchDarkly servers to send recorded observability data.worker-src: data: blob:: This policy allows creating an inline web worker initialized by the npm package for this plugin.Your CSP definition may look something like this:
Alternatively, you can set the CSP in the HTML document response header Content-Security-Policy. Check your initial app HTML document load for the header to make sure you are setting it to the desired value.
The observability plugin supports the following features. After the SDK and plugins are initialized, you can access these from within your application:
After you initialize the SDK and observability plugins, your application automatically starts sending observability data back to LaunchDarkly in the form of custom events. You can review this information in the LaunchDarkly user interface. To learn how, read Observability.
Specifically, the observability data includes events that LaunchDarkly uses to automatically create the following metrics:
To learn more, read Observability autogenerated metrics.