If you’re familiar with New Relic browser monitoring, you might be using single-page application (SPA) monitoring for deeper visibility and actionable insights into real user interactions with single-page apps. After you set up your single-page app with an SPA-enabled version of the browser monitoring agent, you’re excited to capture all the metrics and traces from your app. But, wait! Distributed tracing isn’t working!
The agent shows that distributed tracing is enabled by default, but you can’t capture distributed trace details. Several thoughts go through your mind… Is it because the backend service doesn’t have an agent? Or is it because the backend service is deployed separately from your web service? Maybe it’s both. Help!
This blog post will help you with SPA monitoring, so you can take advantage of distributed tracing to find out what your users are experiencing, fix issues quickly, and make customers happy.
Example scenario
In this scenario, let’s say you have a full-stack JavaScript application. Your frontend (you might be using React, Angular, or Vue, for example) is hosted on a static web host (which might be something like Netlify, Amazon S3, Render, or GitHub Pages). Your backend web service could be hosted on an Amazon Elastic Compute Cloud, an Amazon Elastic Block Store, or on Google Cloud Platform with Google Engine Compute Engine or Google App Engine.
The name of your frontend browser app is www.spa-app.awesome.com
.
The name of your backend web service is www.robust-webservice.awesome.com
.
Configure New Relic for SPA and Node.js APM agents
You're setting up New Relic for two application performance monitoring (APM) agents: SPA and Node.js. That means you configure your applications with these New Relic agents:
- The browser monitoring agent for SPA
- (Optional) An APM agent for the backend service, in this case the Node.js agent for an Express app (a Node.js web application framework).
The problem
As you can see in this screen capture, when you configure your settings at Browser > Settings > Applications settings, you see the default browser agent configuration Pro+SPA and can set Distributed Tracing to ON.
But with the application hosting model described earlier, this setting does not show any traces.
Three attempted fixes
I’ll walk through three ways you might try to fix the problem. Let’s assume you are using the application model described in the example scenario section.
Spoiler alert: As I’ll show with our example scenario in this blog post, the third attempt will work.
Attempted fix #1: Enable CORS
If your frontend app and backend service are hosted on different subdomains or hosts, you might want to enable cross-origin resource sharing, also called CORS, for the browser agent. Select Browser > Settings > Applications settings again. Include the base URL for your backend service or API, as shown in this screenshot.
But the result for enabling CORS still doesn’t help. You don’t see any distributed traces!
Attempted fix #2: Enable CORS with New Relic headers
OK, let’s try again. Go back to Browser > Settings > Applications settings again.
This time, under Cross-Origin Resource Sharing (CORS), add origins. Select Use newrelic header and Use trace context headers, as shown in the next screen capture.
You hope that if you add origins, you’ll see the distributed traces for your cross-origin AJAX calls.
The result? Still no traces!
Attempted fix #3: Accept the CORS headers
Look at the previous screenshot again. When you’re in the Browser > Settings > Application settings, you’ll notice that the Cross-Origin Resource Sharing (CORS) section includes a warning about potential failure of AJAX requests if the New Relic custom header or WC3 trace context headers are not accepted.
If there aren’t any failures in AJAX requests from the frontend app, you might overlook or ignore this message.
But this is the answer to your problem!
You need to both accept and return these headers as part of the response to the AJAX/API calls from the frontend application.
Use this example to allow the headers:
/* Node+Express JS Sample */
//set custom headers
app.use(function(req, res, next) {
res.setHeader(
"Access-Control-Allow-Headers", ["newrelic","traceparent","tracestate"]
);
return next();
});
Here are your results: Finally, you see your traces! In this example, you can see 2 entities: angular12-spa
and angular12-nodeService
. This is the distributed trace from your browser app to your backend service.
Next steps
Now that you know how to get distributed tracing working for your single-page application (SPA) monitoring, you are closer to understanding how your customers use your applications.
Continue on your browser monitoring and distributed tracing journey with New Relic.
- Explore more browser monitoring features to monitor the performance of your applications.
- To monitor the availability of your browser-based applications, get started with synthetic monitoring.
The views expressed on this blog are those of the author and do not necessarily reflect the views of New Relic. Any solutions offered by the author are environment-specific and not part of the commercial solutions or support offered by New Relic. Please join us exclusively at the Explorers Hub (discuss.newrelic.com) for questions and support related to this blog post. This blog may contain links to content on third-party sites. By providing such links, New Relic does not adopt, guarantee, approve or endorse the information, views or products available on such sites.