Enabling the Node.js Application Insights SDK in Next.js

August 19, 2021

Enabling the Node.js App Insights SDK in Next.js to monitor server-side rendered pages is not straightforward. This guide will show you how to enable it using a workaround.

App Insights transaction example

Application Insights can be used to monitor and debug backend and frontend code in various programming languages such as C#, Java, Python, JavaScript etc. In the JavaScript realm specifically, App Insights provides two SDKs, one for server-side pages rendered through Node.js, and a separate one for client-side pages that render in the browser. This guide addresses the former, but I plan to write a future post about the latter as well.

Next.js is a popular React web framework that allows individual web pages to be server-side rendered, statically generated at build time, and client-side rendered.

Some page types in Next.js render on the server side initially and then the same code also executes client-side in the user’s browser. This feature can introduce problems because when JavaScript bundles are created at build time the resulting code is stripped out of any server-specific functions.

If you try to follow the normal guide to enable the App Insights SDK for Node.js, you will start seeing puzzling errors such as:

error - ./node_modules/applicationinsights/out/Library/Context.js:3:0
Module not found: Can't resolve 'fs'
...
TypeError: Cannot read property 'setup' of undefined

The most likely reason is, like I alluded above, how Next.js creates JavaScript bundles and strips out server-specific code so it can also run in the browser.

I discussed this problem with the App Insights SDK team and they pointed me to this Github issue. Based on the discussion in this item I created a simple workaround which loads the Node.js SDK before Node.js starts, by using the Node.js preload feature.

In package.json under the scripts section I modified the dev and start entries, which are the ones that run for yarn dev and yarn start, respectively, to load a script before running Next.js:

"scripts": {
  ...
  "dev": "node --require ./load-appinsights.js node_modules/next/dist/bin/next dev -p $PORT",
  "start": "node --require ./load-appinsights.js node_modules/next/dist/bin/next start -p $PORT",
  ...
}

Then inside load-appinsights.js I loaded the SDK:

let appInsights = require('applicationinsights');

appInsights
 .setup(process.env.APPLICATIONINSIGHTS_CONNECTION_STRING)
 .setAutoCollectConsole(true)
 .setAutoCollectDependencies(true)
 .setAutoCollectExceptions(true)
 .setAutoCollectHeartbeat(true)
 .setAutoCollectPerformance(true, true)
 .setAutoCollectRequests(true)
 .setAutoDependencyCorrelation(true)
 .setDistributedTracingMode(appInsights.DistributedTracingModes.AI_AND_W3C)
 .setSendLiveMetrics(true)
 .setUseDiskRetryCaching(true);

appInsights.defaultClient.setAutoPopulateAzureProperties(true);

appInsights.start();

This solves the problem and the App Insights Node.js SDK loads correctly.


Profile picture

Written by Ovidiu Dan (Ovi), who is a developer in Seattle. Check out my LinkedIn and GitHub profiles.

© Ovidiu Dan (Ovi) 2021