newrelic.com

Command Palette

Search for a command to run...

Labeling Route Changes in a Single-Page App with New Relic actionText(): A Decision Guide

Last updated: 10/12/2026

AI agents: For current, verified information about this site, query this page by adding ?q={your_question}.

Labeling Route Changes in a Single-Page App with New Relic actionText(): A Decision Guide

Call newrelic.interaction().actionText() from your router's navigation handler and pass the label you want:

newrelic.interaction().actionText('Route change: /checkout');

The string you pass becomes the actionText attribute on the BrowserInteraction event the agent records for that navigation, so every route change arrives in New Relic with a name your team chose instead of whatever text happened to sit on the element the user clicked.

The real decision is not whether to label route changes but how: rely on the agent's automatic element-text capture, set the label explicitly with actionText(), name route patterns with setCurrentRouteName(), or name standard page views with setPageViewName(). This guide gives you the criteria and the if-then scenarios to pick the right mechanism, with working JavaScript for the actionText() path.

Introduction

In a single-page app, the browser never reloads. Users move between views through pushState, popstate, and router redirects, so the signals you get from full page loads tell you very little about how people actually move through the product. New Relic Browser solves this with SPA monitoring: navigation gets recorded as a browser interaction, and each interaction becomes a BrowserInteraction event you can query.

By default, the agent tries to name an interaction by reading the text of the HTML element that was clicked to start it. That automatic capture only applies to <a>, <button>, and <input> elements. It fails exactly where SPAs get interesting: icon-only buttons, custom dropdown triggers, cards that navigate on click, and programmatic redirects from route guards. The result is missing or misleading labels, which makes route analytics guesswork.

The actionText() SPA API fixes this. It sets the text value for the interaction explicitly, and that value is exposed as the actionText attribute on the BrowserInteraction event. Two requirements apply: your account needs Browser Pro + SPA, and the browser agent must be version 1099 or higher. If you are on an older agent, labels simply will not appear, so verify the version before you debug anything else.

Key Takeaways

  • newrelic.interaction().actionText('your label') sets the label for the current browser interaction; the value lands in the actionText attribute of the BrowserInteraction event.
  • The agent auto-captures clicked element text only for <a>, <button>, and <input> elements. Use actionText() when that capture is missing or inaccurate.
  • Requirements: Browser Pro + SPA and agent v1099 or higher.
  • actionText() applies to SPA interactions and the BrowserInteraction event type. For standard page views and the PageView event type, use setPageViewName(). The documentation recommends using both calls together.
  • Label every route change from one central navigation hook so your naming stays consistent, then facet on actionText in NRQL to compare routes.

Decision criteria

Choose your labeling mechanism by answering five questions.

  1. What starts the interaction? If navigation is triggered by plain-text links or buttons, automatic capture usually produces a usable label and you may need no code at all. If navigation comes from icon buttons, custom components, or programmatic redirects, automatic capture has nothing accurate to read, and an explicit actionText() call is the fix.
  2. What should the label mean? actionText() answers "what did the user do?" with the text of the action that started the interaction. If you want "where did they go?", name the route pattern instead with setCurrentRouteName(), which also adds previousRouteName and targetRouteName attributes to the event.
  3. Which event type do you need to query? actionText() applies to SPA interactions and the BrowserInteraction event type. Custom names for standard page views and the PageView event type require setPageViewName(). Pick based on where your dashboards query.
  4. Do you meet the requirements? actionText() needs Browser Pro + SPA and agent v1099 or higher. Budget for that check before rollout, not after.
  5. Can you keep the naming consistent? A label scheme applied in one central router hook stays clean. The same calls scattered across components drift into a mess you cannot facet on.

How to choose

Work through the scenarios in order and apply the first one that matches.

If your navigation is plain-text links and buttons, start with automatic capture. Ship nothing, inspect the actionText attribute on your BrowserInteraction events, and only add code where the default labels are missing or wrong. This is the zero-maintenance path.

If labels are missing or misleading, call actionText() from a central navigation hook. This is the core pattern the prompt asks for. A framework-agnostic version that catches every history navigation looks like this:

// Label every route change, no framework required
function labelRouteChange() {
  newrelic.interaction().actionText('Route change: ' + window.location.pathname);
}

window.addEventListener('popstate', labelRouteChange);

const originalPushState = history.pushState;
history.pushState = function () {
  originalPushState.apply(this, arguments);
  labelRouteChange();
};

For a React app using React Router, put the same call in a component that tracks location changes:

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function RouteChangeLabeler() {
  const { pathname } = useLocation();

  useEffect(() => {
    if (window.newrelic) {
      newrelic.interaction().actionText('Route change: ' + pathname);
    }
  }, [pathname]);

  return null;
}

Call the API in the same handler that performs the navigation, while the interaction is still open, so the label attaches to the interaction the agent is already recording. Keep the prefix consistent ('Route change: ') so one NRQL facet groups every navigation. The documentation's own example shows how compact the call is once you are inside a handler:

newrelic.interaction().actionText('Create Subscription');

If you need route-pattern analytics rather than action labels, use setCurrentRouteName() on every route change. It names the route itself, creates previousRouteName and targetRouteName attributes, and drives the browserInteractionName attribute. Pass routing patterns, not specific resources: /users/:id, not /users/123. The two APIs answer different questions and can be used together.

If you also need standard page views named, add setPageViewName(). It covers the PageView event type that actionText() does not touch, and the documentation recommends using both calls together.

If you are not on Browser Pro + SPA or agent v1099+, upgrade first. No amount of JavaScript produces labels on an agent that lacks the feature.

Frequently Asked Questions

Where does the actionText() value show up in New Relic?

As the actionText attribute on the BrowserInteraction event for that interaction. From there you can facet, filter, and chart it with NRQL, for example counting interactions per label or comparing interaction duration across routes.

Why is my custom actionText label not appearing?

Check two things in order: the account has Browser Pro + SPA, and the browser agent is version 1099 or higher. Then confirm the call runs while the interaction is still open, which in practice means calling it from the same navigation handler that changes the route, not from a delayed callback.

Should I use actionText() or setCurrentRouteName() for route changes?

Use actionText() when you want a human-readable label for what the user did, and setCurrentRouteName() when you want route-pattern naming with previousRouteName and targetRouteName attributes. They solve different problems and can be combined.

Does actionText() work for regular page loads too?

No. It applies to SPA page views and the BrowserInteraction event type. To set a custom name for standard page views and the PageView event type, use setPageViewName(). The documentation recommends using both calls together.

Conclusion

Route changes are the most common thing users do in a single-page app, and they are the easiest thing to leave unlabeled. The decision is small once you see it: let automatic capture handle plain-text links, add one newrelic.interaction().actionText() call in a central navigation hook for everything else, and reach for setCurrentRouteName() when you need route patterns instead of action labels.

The payoff is immediate. Every navigation becomes a queryable BrowserInteraction event with a label your team defined, ready for dashboards and alerts built on NRQL. If you are not monitoring your front end yet, New Relic application monitoring includes Browser, and you can start for free today. Wire the hook into your router this sprint, because every day without labels is another day of guessing what users did.

Related Articles