Add Azure Application Insights to a static NextJS App
Tags: nextjs, azure, observability, beginners
Published: 2023-01-14 21:17:40

I needed to add a basic level of observability to my NextJS app, which is hosted on an Azure Static Web App. I chose to use Azure Application Insights because it is native in the Azure ecosystem, I wouldn't be hit with egress charges, and it's been easy to work with in other projects, but this NextJS configuration is a first for me.

Throughout my many years working with Microsoft tools the documentation has been, overall, quite poor. However, this was not the case when instrumenting my NextJS app with Application Insights. The Microsoft Documentation I followed can be found [here](https://learn.microsoft.com/en-us/azure/azure-monitor/app/javascript-react-plugin), but you can also follow along with this article to review my code snippets.

## Step 1: Provision Azure Monitor Resources

The first step is to create both a Log Analytics Workspace and an Application Insights component in Azure. I used the Azure CLI to do this, but you can also provision them through the Azure Portal or with ARM/Bicep templates.

**Note:** Replace the names with your own.

```bash
RESOURCE_GROUP_NAME="your-resource-group-name"
LOCATION="azure-region-name"
APP_INSIGHTS_NAME="app-insights-component-name"
LOG_ANALYTICS_NAME="log-analytics-workspace-name"

WORKSPACE_ID=$(az monitor log-analytics workspace create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $LOG_ANALYTICS_NAME \
    --location $LOCATION \
    --sku "PerGB2018" \
    --ingestion-access "Enabled" \
    --query "id" \
    --output tsv)

az monitor app-insights component create \
    --app $APP_INSIGHTS_NAME \
    --resource-group $RESOURCE_GROUP_NAME \
    --location $LOCATION \
    --ingestion-access "Enabled" \
    --application-type "web" \
    --kind "web" \
    --workspace $WORKSPACE_ID
```

## Step 2: Install Application Insights NPM Packages

The following packages are required to instrument your NextJS app with Application Insights.

```bash
npm install @microsoft/applicationinsights-react-js 
npm install @microsoft/applicationinsights-web
```

## Step 3: Connect Application Insights to NextJS

I pass the Application Insights connection string to my NextJS app as an environment variable so it can be accessed at build time. Below is the React component I used to setup Application Insights.

```typescript
import React from "react";
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
import {
  ReactPlugin,
  withAITracking,
  AppInsightsContext,
} from "@microsoft/applicationinsights-react-js";

let reactPlugin = new ReactPlugin();
let appInsights = new ApplicationInsights({
  config: {
    connectionString: process.env.NEXT_PUBLIC_APP_INSIGHT,
    enableAutoRouteTracking: true,
    enableCorsCorrelation: true,
    enableRequestHeaderTracking: true,
    enableResponseHeaderTracking: true,
    enableAjaxPerfTracking: true,
    isBrowserLinkTrackingEnabled: true,
    extensions: [reactPlugin],
  },
});

appInsights.loadAppInsights();

const AzureAppInsights = ({ children }) => {
  return (
    <AppInsightsContext.Provider value={reactPlugin}>
      {children}
    </AppInsightsContext.Provider>
  );
};

export default withAITracking(reactPlugin, AzureAppInsights);
```
I plan to keep all the configuration settings enabled until I have a better understanding of what telemetry is useful for this app. Once I know what provides value, I can setup dashboards in Azure or another service like Grafana, PowerBI, etc.

*NOTE: Note the property `enableAutoRouteTracking` is set to true. This will automatically track page views and route changes in your NextJS app in the absence of a History object (which NextJS does not have) but anyone building with Create-React-App and React Router may have been used to.*

## Step 4: Wrap _app with above AzureAppInsights component

Wrap the _app.tsx file with the AzureAppInsights component created in the above step. Notice it is wrapped with the withAITracking HOC and the AppInsightsContext.Provider so you can access the app insight context throughout your app.

```typescript
import AzureAppInsights from "../components/AzureAppInsights/AzureAppInsights";

export default function Application({ Component, pageProps }) {
  return (
    <AzureAppInsights>
         <Component {...pageProps} />
    </AzureAppInsights>
  );
}
```

Once the _app.tsx file is setup your app will begin sending telemetry to Application Insights. It may take a few minutes for the data to show up in the Azure Portal, typically it showed up in 2-3 minutes when I tested it.

## Step 5: Observe

Once you have the data flowing into Application Insights, you can start to observe your app. I am currently working on the proper configuration of my dashboards based on the features added to this very minimal site. I will continue to share my progress as I go.