Grafana Cloud

Monitor user actions

Track your users’ key interactions with your application using Faro’s user action instrumentation. User actions let you follow end-to-end user journeys and attach context to related signals, such as HTTP requests and performance metrics, as users interact with your app.

Overview

A user action represents an end user’s interaction with your product, for example, activating a button or submitting a form. User actions can start automatically or manually and are linked with signals such as measurements, logs, and errors. This linkage helps you monitor critical paths, identify issues, and measure feature adoption.

Create a user action

You can create user actions automatically from an HTML element or manually with the Faro API.

Create actions automatically

Faro starts a user action on pointerdown, or on keydown when the user presses Space or Enter, if the target HTML element includes the data-faro-user-action-name attribute.

HTML
<button data-faro-user-action-name="save">Save</button>

You can override the initial activity timeout for an element with data-faro-user-action-timeout:

HTML
<button data-faro-user-action-name="save" data-faro-user-action-timeout="500">Save</button>

You can also customize the action attribute name. Refer to Customize declarative attributes for more information.

Create actions manually

Use the Faro Web SDK faro.api.startUserAction method to start a user action programmatically. Refer to Start a user action manually for the API parameters and an example.

Understand the user action lifecycle

When the action completes, Faro adds an action field to eligible signals captured while the action is active. Web Vitals measurements and signals excluded by userActionsInstrumentation.excludeItem aren’t linked to the action. For example, a performance resource event can look like this:

JSON
{
  "name": "faro.performance.resource",
  "domain": "browser",
  "attributes": {
    "name": "http://localhost:3000/",
    "duration": "45",
    "tcpHandshakeTime": "1"
  },
  "timestamp": "2025-07-17T08:09:34.051Z",
  "trace": {
    "trace_id": "77ae1ba7a590bb8c085deacb83907e87",
    "span_id": "83e4ec9b0511a4ec"
  },
  "action": {
    "parentId": "CdK96bsFeT",
    "name": "fetch-success"
  }
}

When a user action starts, Faro waits for the first qualifying signal. Qualifying signals include a tracked HTTP request start, DOM mutation, or performance entry. If Faro doesn’t receive a qualifying signal within the effective initial activity timeout, it cancels the action.

The configured initial activity timeout applies only while Faro waits for this first signal. After the first signal, Faro uses a fixed 100 ms rolling inactivity window. Each new qualifying signal resets that window, and the action completes after 100 ms without another qualifying signal.

If tracked HTTP requests remain pending when the rolling inactivity window ends, Faro halts the action while those requests drain. The action completes as soon as all pending tracked requests finish, or when the fixed 10-second drain timeout expires. The drain timeout isn’t configurable.

The user action completion event includes timing attributes such as userActionStartTime, userActionEndTime, and userActionDuration.

Configure user action instrumentation

User action instrumentation is enabled by default in the Faro Web SDK. If you use custom instrumentation, manually include UserActionInstrumentation:

JavaScript
import { UserActionInstrumentation } from '@grafana/faro-web-sdk';

const instrumentations = [
  // ...other instrumentations
  new UserActionInstrumentation(),
];

Set the initial activity timeout

The initial activity timeout defaults to 100 ms. To configure it globally, set initialActivityTimeout in userActionsInstrumentation:

JavaScript
initializeFaro({
  // ...other configuration
  userActionsInstrumentation: {
    initialActivityTimeout: 500,
  },
});

Faro resolves the effective initial activity timeout in this order:

  1. The element override or the startUserAction API override
  2. The global userActionsInstrumentation.initialActivityTimeout setting
  3. The default of 100 ms

Timeout values must be finite and greater than zero. Faro handles other values as follows:

  • For an invalid element or API override, Faro logs a warning and uses the global setting, or the default if no valid global setting exists.
  • For an invalid global setting, Faro logs a warning and uses the default of 100 ms.
  • For a value greater than 1,000 ms, Faro logs a warning and clamps the value to 1,000 ms.

The effective timeout controls the user action lifecycle in the browser. Faro doesn’t include it in emitted telemetry.

Troubleshoot canceled user actions

If Faro cancels a user action because the initial activity timeout expires before a qualifying signal occurs, you can enable verbose internal logging to see the cancellation in the browser console:

JavaScript
import { initializeFaro, InternalLoggerLevel } from '@grafana/faro-web-sdk';

initializeFaro({
  // ...other configuration
  internalLoggerLevel: InternalLoggerLevel.VERBOSE,
});

The SDK writes User action not sent; no DOM, resource, or HTTP activity: <action-name> to console.debug. This message isn’t sent as telemetry. Verbose logging also enables other internal SDK debug messages, so enable it only while troubleshooting.

Customize declarative attributes

The dataAttributeName option accepts either a complete HTML data-* attribute or a camelCase dataset key. Faro normalizes either form to an HTML data-* attribute.

Faro derives the timeout attribute from the normalized action attribute. If the action attribute ends in -name, Faro replaces that suffix with -timeout. Otherwise, Faro appends -timeout.

The exported userActionTimeoutDataAttribute constant represents only the default data-faro-user-action-timeout attribute. When you customize dataAttributeName, use the derived timeout attribute instead.

dataAttributeName valueAction attributeTimeout attribute
data-product-action-name or productActionNamedata-product-action-namedata-product-action-timeout
data-product-action or productActiondata-product-actiondata-product-action-timeout

For example, configure an action attribute that ends in -name:

JavaScript
initializeFaro({
  // ...other configuration
  userActionsInstrumentation: {
    dataAttributeName: 'productActionName',
  },
});

Then use the normalized action attribute and its derived timeout attribute in HTML:

HTML
<button data-product-action-name="save" data-product-action-timeout="500">Save</button>

For an action attribute that doesn’t end in -name, configure dataAttributeName: 'data-product-action' and use these attributes:

HTML
<button data-product-action="save" data-product-action-timeout="500">Save</button>

Start a user action manually

Use the startUserAction method for programmatic control and customization:

typescript
startUserAction(
  name: string,
  attributes?: Record<string, string>,
  options?: StartUserActionOptions
): UserActionInterface | undefined

Parameters

NameTypeDescription
namestringThe name of the user action.
attributesRecord<string, string> (optional)Additional attributes to include in the user action completion event.
options.triggerNamestring (optional)Describes the action origin. Defaults to faroApiCall for manually created actions.
options.importance'normal' | 'critical' (optional)Sets the importance level. Defaults to 'normal'.
options.initialActivityTimeoutnumber (optional)Overrides the global initial activity timeout for this action. The value is in milliseconds.

Return value

The method returns a UserActionInterface when it starts the action. If another user action is already active, Faro logs an error and returns undefined.

For example, start an action with custom attributes and a 500 ms initial activity timeout:

JavaScript
const attributes = {
  cartSize: '3',
  paymentMethod: 'card',
};

faro.api.startUserAction('checkout', attributes, {
  triggerName: 'customEvent',
  initialActivityTimeout: 500,
});

Follow user action best practices

  • Use descriptive action names to make filtering and analysis easier.
  • Attach relevant attributes to actions for more context, for example, the control name and page context.
  • For highly custom interactions, use startUserAction to start actions manually.
  • In a single-page application (SPA), increase the initial activity timeout only when delayed rendering or asynchronous work can cause the first qualifying signal to occur after 100 ms. Keep the timeout as short as practical.