<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Spencer Taylor</title>
    <description>The latest articles on Forem by Spencer Taylor (@set808).</description>
    <link>https://forem.com/set808</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F99045%2F8d28eded-76b7-4957-be91-1a6e8d650d7c.jpg</url>
      <title>Forem: Spencer Taylor</title>
      <link>https://forem.com/set808</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/set808"/>
    <language>en</language>
    <item>
      <title>How to Monitor App Router Next.js Applications with New Relic</title>
      <dc:creator>Spencer Taylor</dc:creator>
      <pubDate>Tue, 23 Jul 2024 21:21:35 +0000</pubDate>
      <link>https://forem.com/set808/how-to-monitor-app-router-nextjs-applications-with-new-relic-ghp</link>
      <guid>https://forem.com/set808/how-to-monitor-app-router-nextjs-applications-with-new-relic-ghp</guid>
      <description>&lt;p&gt;Next.js is a powerful JavaScript framework that offers optimized speed and performance for both development and runtime. With the release of Next.js 13, the App Router has become the recommended way to handle routing in Next.js applications. This new router leverages React’s latest features, such as Server Components and Streaming, to offer a more modern and efficient approach to building web applications.&lt;/p&gt;

&lt;p&gt;In this blog post, you’ll learn how to set up application performance monitoring for the server side and browser monitoring for the frontend using the new App Router, giving you full-stack observability in your Next.js application. To start, you’ll need a &lt;a href="https://newrelic.com/signup" rel="noopener noreferrer"&gt;New Relic account&lt;/a&gt; and &lt;a href="https://docs.newrelic.com/docs/apis/intro-apis/new-relic-api-keys/" rel="noopener noreferrer"&gt;license key&lt;/a&gt;, both available for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing the agent and middleware
&lt;/h2&gt;

&lt;p&gt;Run the following command in your Next.js project to install the New Relic Node.js &lt;a href="https://docs.newrelic.com/docs/apm/new-relic-apm/getting-started/introduction-apm" rel="noopener noreferrer"&gt;APM&lt;/a&gt; agent and New Relic middleware for Next.js.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npm &lt;span class="nb"&gt;install &lt;/span&gt;newrelic @newrelic/next


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After the command completes successfully, you’ll see the dependencies included in your &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

 &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"@newrelic/next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^0.10.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"newrelic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^11.23.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"14.2.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^18"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"react-dom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^18"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;@newrelic/next&lt;/code&gt; package provides official instrumentation for New Relic monitoring of Next.js applications. It focuses on server-side rendering, middleware, and transaction naming for both page and server requests, ensuring comprehensive observability of server-side activities.&lt;/p&gt;

&lt;p&gt;This package is installed separately but integrates seamlessly with the New Relic Node.js agent, offering all the agent's capabilities for enhanced performance monitoring and error tracking in Next.js applications.&lt;/p&gt;

&lt;p&gt;While it doesn't cover client-side actions, you can inject the New Relic browser agent for client-side telemetry (more on that later in this blog post).&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;To effectively instrument a Next.js application with New Relic, you need to modify the &lt;code&gt;next.config.js&lt;/code&gt; file. This configuration ensures that the modules supported by New Relic are not mangled by webpack, and it externalizes those modules.&lt;/p&gt;

&lt;p&gt;Create or update the &lt;code&gt;next.config.js&lt;/code&gt; file in your project root with the following content:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nrExternals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@newrelic/next/load-externals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;experimental&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;serverComponentsExternalPackages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;newrelic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;webpack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;nrExternals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, modify your &lt;code&gt;dev&lt;/code&gt; and &lt;code&gt;start&lt;/code&gt; npm scripts by amending the scripts section of &lt;code&gt;package.json&lt;/code&gt; file. Allow your application to run with Node’s &lt;code&gt;-r&lt;/code&gt; option, which will preload &lt;code&gt;@newrelic/next&lt;/code&gt; middleware.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NODE_OPTIONS='-r @newrelic/next' next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NODE_OPTIONS='-r @newrelic/next' next start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next lint"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Before you run your application, add the &lt;code&gt;newrelic.js&lt;/code&gt; &lt;a href="https://docs.newrelic.com/docs/apm/agents/nodejs-agent/installation-configuration/nodejs-agent-configuration/#methods-and-precedence" rel="noopener noreferrer"&gt;AMP agent configuration file&lt;/a&gt; to the root directory of your project. For more information, &lt;a href="https://github.com/newrelic-experimental/newrelic-nextjs-integration/blob/main/newrelic.js" rel="noopener noreferrer"&gt;see an example config file for your Next.js app&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Additionally, use &lt;code&gt;NEW_RELIC_APP_NAME&lt;/code&gt; and &lt;code&gt;NEW_RELIC_LICENSE_KEY&lt;/code&gt; in your &lt;code&gt;.env&lt;/code&gt; file as shown in an &lt;a href="https://github.com/newrelic/newrelic-node-examples/blob/main/nextjs/nextjs-app-router/.env.sample" rel="noopener noreferrer"&gt;example .env file for your application&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing performance data in New Relic
&lt;/h2&gt;

&lt;p&gt;Run your application and go to the APM page in New Relic. You’ll see your application’s server-side data flowing into New Relic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnewrelic.com%2Fsites%2Fdefault%2Ffiles%2F2024-07%2FNextJs%252BNewRelic_APM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnewrelic.com%2Fsites%2Fdefault%2Ffiles%2F2024-07%2FNextJs%252BNewRelic_APM.png" alt="New Relic UI - APM Node agent telemetry summary view, with visualizations of important performance metrics such as transaction time, Apdex score, throughput, and error rate."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend observability
&lt;/h2&gt;

&lt;p&gt;To inject the browser agent when using the App Router, we’ll be editing the &lt;code&gt;app/layout.js(.ts)&lt;/code&gt; file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Script&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;newrelic&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;newrelic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./style.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;RootLayout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newrelic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isConnected&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;newrelic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;browserTimingHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newrelic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBrowserTimingHeader&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;hasToRemoveScriptWrapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;allowTransactionlessInjection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Script&lt;/span&gt;
        &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nr-browser-agent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;browserTimingHeader&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;navbar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;about&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;About&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/html&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here are the steps for this process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/@newrelic/next" rel="noopener noreferrer"&gt;Install&lt;/a&gt; the &lt;code&gt;newrelic&lt;/code&gt; npm package if you haven’t already with the &lt;code&gt;npm install newrelic @newrelic/next&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the &lt;code&gt;newrelic.getBrowserTimingHeader&lt;/code&gt; method.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pass &lt;code&gt;hasToRemoveScriptWrapper: true&lt;/code&gt; as an argument to &lt;code&gt;newrelic.getBrowserTimingHeader&lt;/code&gt; so that the browser script is returned without the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; wrapper. See the &lt;a href="https://docs.newrelic.com/docs/apm/agents/nodejs-agent/extend-your-instrumentation/browser-monitoring-nodejs-agent/#procedures" rel="noopener noreferrer"&gt;node-newrelic docs&lt;/a&gt; for more details.&lt;/li&gt;
&lt;li&gt;Pass &lt;code&gt;allowTransactionlessInjection: true&lt;/code&gt; as an argument to &lt;code&gt;newrelic.GetBrowserTimingHeader&lt;/code&gt; to allow injection of the browser agent when not in a transaction.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;In the render method, inject the New Relic Browser agent script to the end of the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; of the document.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;The &lt;code&gt;layout.js(.ts)&lt;/code&gt; file should be in the root of the app directory of your project.&lt;/p&gt;&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;For the example &lt;code&gt;layout.js(.ts)&lt;/code&gt; file, visit the following &lt;a href="https://github.com/newrelic/newrelic-node-examples/blob/58f760e828c45d90391bda3f66764d4420ba4990/nextjs-app-router/app/layout.js" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing browser data in New Relic
&lt;/h2&gt;

&lt;p&gt;Start the application and then go to the browser monitoring page in New Relic to see client-side data from your application flowing into New Relic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnewrelic.com%2Fsites%2Fdefault%2Ffiles%2F2024-07%2Fnext%252Bbrowser.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnewrelic.com%2Fsites%2Fdefault%2Ffiles%2F2024-07%2Fnext%252Bbrowser.png" alt="New Relic UI - Browser telemetry summary view, with visualization of important metrics such as core web vitals, user time on the page, load times, page views or throughput."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending detailed error information to New Relic
&lt;/h2&gt;

&lt;p&gt;For capturing detailed error information in your Next.js application, you need to handle both client-side and server-side errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client-side errors
&lt;/h3&gt;

&lt;p&gt;For client-side errors, you can use the &lt;code&gt;error.ts(.js)&lt;/code&gt; file to capture and send error details to New Relic. Below is an example of how this can be implemented:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;newrelic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;newrelic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;noticeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Something&lt;/span&gt; &lt;span class="nx"&gt;went&lt;/span&gt; &lt;span class="nx"&gt;wrong&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this example, the &lt;code&gt;useEffect&lt;/code&gt; hook is used to call &lt;code&gt;window.newrelic.noticeError&lt;/code&gt; whenever an error occurs. This sends the error details to New Relic for further analysis.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;error.js(.ts)&lt;/code&gt; file defines an error UI boundary for a route segment. To handle errors in root layout, use &lt;code&gt;global-error.js(.ts)&lt;/code&gt; and place it in the root &lt;code&gt;app&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;For more information on error handling in Next.js, refer to the &lt;a href="https://nextjs.org/docs/app/api-reference/file-conventions/error" rel="noopener noreferrer"&gt;Next.js documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-side errors
&lt;/h2&gt;

&lt;p&gt;For errors coming from the backend, the &lt;code&gt;@newrelic/next&lt;/code&gt; module handles them out of the box. You don't need to add any additional code for server-side error tracking; the module will automatically capture and report these errors to New Relic.&lt;/p&gt;

&lt;p&gt;This ensures that both client-side and server-side errors are effectively monitored and reported to New Relic, providing comprehensive error tracking for your Next.js application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;You can find all the code samples in this blog post in the &lt;a href="https://github.com/newrelic/newrelic-node-examples/tree/main/nextjs/nextjs-app-router" rel="noopener noreferrer"&gt;newrelic-node-examples GitHub repository&lt;/a&gt;. You can &lt;a href="https://github.com/newrelic/newrelic-node-examples/issues" rel="noopener noreferrer"&gt;give us any feedback&lt;/a&gt; in the GitHub repository issues section.&lt;br&gt;
Check out our &lt;a href="https://github.com/newrelic/newrelic-node-nextjs" rel="noopener noreferrer"&gt;Next.js integration page on GitHub&lt;/a&gt;.&lt;br&gt;
&lt;a href="https://live-d9newrelic.pantheonsite.io/signup" rel="noopener noreferrer"&gt;Sign up for a free New Relic account&lt;/a&gt;. Your free account includes 100 GB/month of free data ingest, one free full-access user, and unlimited free basic users.&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>webdev</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What are the most important features you need in your logging product?</title>
      <dc:creator>Spencer Taylor</dc:creator>
      <pubDate>Tue, 01 Sep 2020 16:13:46 +0000</pubDate>
      <link>https://forem.com/set808/what-are-the-most-important-features-you-need-in-your-logging-product-2bh</link>
      <guid>https://forem.com/set808/what-are-the-most-important-features-you-need-in-your-logging-product-2bh</guid>
      <description>

</description>
      <category>discuss</category>
      <category>reliability</category>
      <category>logging</category>
    </item>
    <item>
      <title>What are your top UI/UX design resources?</title>
      <dc:creator>Spencer Taylor</dc:creator>
      <pubDate>Fri, 25 Jan 2019 00:29:53 +0000</pubDate>
      <link>https://forem.com/set808/what-are-your-top-uiux-design-resources-2oae</link>
      <guid>https://forem.com/set808/what-are-your-top-uiux-design-resources-2oae</guid>
      <description>&lt;p&gt;Discussion on must read UI/UX design resources.&lt;/p&gt;

</description>
      <category>design</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Prefilling Form on Redirect with URL Params &amp; Google Analytics Params</title>
      <dc:creator>Spencer Taylor</dc:creator>
      <pubDate>Thu, 17 Jan 2019 00:28:10 +0000</pubDate>
      <link>https://forem.com/set808/prefilling-form-on-redirect-with-url-params--google-analytics-params-4h95</link>
      <guid>https://forem.com/set808/prefilling-form-on-redirect-with-url-params--google-analytics-params-4h95</guid>
      <description>&lt;p&gt;Hello there! I really hope you can help me out. I have created a landing page which has a simple "form" to get a potential user's email and password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input id="email" type="email" name="email" placeholder="E-mail Address" style="width:100%; border: 1px solid #eaeaea"&amp;gt;
&amp;lt;input id="password" type="password" name="password" placeholder="Password" style="width:100%; border: 1px solid #eaeaea"&amp;gt;
&amp;lt;a onclick="redirect()" class="custom-link btn btn-sm startscreening-btn btn-default btn-icon-left btn-shadow" data-title="Sign Up Now" title="Sign Up Now" style="margin-top: 1rem"&amp;gt;Create Account&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;Create Account&lt;/strong&gt; button has an &lt;code&gt;onclick&lt;/code&gt; event listener which calls the function &lt;code&gt;redirect&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;script&amp;gt;
const redirect = () =&amp;gt; {
  const email = document.getElementById("email").value;
  const password = document.getElementById("password").value;

  let param = '';

  if (email || password) {
    const tempParam = "email=" + encodeURIComponent(email) + "&amp;amp;password=" + encodeURIComponent(password);
    param = "?" + window.btoa(tempParam);
  }

  window.location = "https://app.naborly.com/signup" + param;
}

&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;On redirect, the values that were encoded in &lt;code&gt;param&lt;/code&gt; are used to prefill a signup form. This code works as intended so far. The issue is that once I try to add &lt;code&gt;utm_source&lt;/code&gt; and &lt;code&gt;utm_campaign&lt;/code&gt; parameters onto the redirect URL I encounter some issues.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If I append &lt;code&gt;&amp;amp;utm_source=some_source&amp;amp;utm_campaign=some_campaign&lt;/code&gt; onto the end of the assignment of &lt;code&gt;window.location&lt;/code&gt; The signup form is populated with garbage values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*If I append &lt;code&gt;&amp;amp;utm_source=some_source&amp;amp;utm_campaign=some_campaign&lt;/code&gt; onto the end of the &lt;code&gt;tempParam&lt;/code&gt; assignment the password value is shortened to 4 characters.&lt;/p&gt;

&lt;p&gt;Is there anyway to prefill the form and have GA campaign parameters on the same link, or is this a futile effort?&lt;/p&gt;

</description>
      <category>help</category>
    </item>
  </channel>
</rss>
