Home  >  Article  >  Web Front-end  >  How to Monitor App Router Next.js Applications with New Relic

How to Monitor App Router Next.js Applications with New Relic

WBOY
WBOYOriginal
2024-07-24 11:18:53774browse

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.

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 New Relic account and license key, both available for free.

Installing the agent and middleware

Run the following command in your Next.js project to install the New Relic Node.js APM agent and New Relic middleware for Next.js.

npm install newrelic @newrelic/next

After the command completes successfully, you’ll see the dependencies included in your package.json file.

 "dependencies": {
   "@newrelic/next": "^0.10.0",
   "newrelic": "^11.23.0",
   "next": "14.2.5",
   "react": "^18",
   "react-dom": "^18"
 },

The @newrelic/next 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.

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.

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).

Configuration

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

Create or update the next.config.js file in your project root with the following content:

'use strict'

const nrExternals = require('@newrelic/next/load-externals')

module.exports = {
  experimental: {
    serverComponentsExternalPackages: ['newrelic']
  },
  webpack: (config) => {
    nrExternals(config)
    return config
  }
}

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

"scripts": {
  "dev": "NODE_OPTIONS='-r @newrelic/next' next",
  "build": "next build",
  "start": "NODE_OPTIONS='-r @newrelic/next' next start",
  "lint": "next lint"
}

Before you run your application, add the newrelic.js AMP agent configuration file to the root directory of your project. For more information, see an example config file for your Next.js app.

Additionally, use NEW_RELIC_APP_NAME and NEW_RELIC_LICENSE_KEY in your .env file as shown in an example .env file for your application.

Viewing performance data in New Relic

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.

How to Monitor App Router Next.js Applications with New Relic

Frontend observability

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

import Script from 'next/script'
import Link from 'next/link'
import newrelic from 'newrelic'
import './style.css'

export default async function RootLayout({ children }) {
  if (newrelic.agent.collector.isConnected() === false) {
    await new Promise((resolve) => {
      newrelic.agent.on("connected", resolve)
    })
  }

  const browserTimingHeader = newrelic.getBrowserTimingHeader({
    hasToRemoveScriptWrapper: true,
    allowTransactionlessInjection: true,
  })

  return (
    <html>
    <Script
        id="nr-browser-agent"
        dangerouslySetInnerHTML={{ __html: browserTimingHeader }}
      />
      <body>
        <ul className="navbar">
          <li><a href="/">Home</a></li>
          <li><Link href="/users" key={"users"}>Users</Link></li>
          <li><Link href="/about" key={"about"}>About</Link></li>
        </ul>
        {children}
      </body>
    </html>
  )
}

Here are the steps for this process:

  1. Install the newrelic npm package if you haven’t already with the npm install newrelic @newrelic/next command.
  2. Add the newrelic.getBrowserTimingHeader method.

    1. Pass hasToRemoveScriptWrapper: true as an argument to newrelic.getBrowserTimingHeader so that the browser script is returned without the