Track page hits with SharePoint Framework and App Insights

A need for modern SharePoint site page hits or analytics


Page hits are maybe one of the first business requirements we get from the business when we start on a new project. Also typical for News and publishing SharePoint portals to identify how many times an article has been visited for example. The SharePoint basic 'Site usage' page (/_layouts/15/siteanalytics.aspx?view=11) does not offer hits per page now, so we can use application insights to track that until that has been implemented.


Is application insights a good fit?


It is the Microsoft analog of Google Analytics so can potentially serve the same as you would use the Google Analytics, but in some cases has better integration with Microsoft Development Frameworks. For example we can easy log exceptions data from the front end JavaScript, back-end .net applications and in the same time record page hits and user interactions. The data can easily be ported to Power Bi so we can create a good looking reports. I will not explain how to create application insights in that post, but here is a nice article how this can be done App insights create new resource


Track page hits with a hidden application customizer


We can create html free SharePoint Framework Application Customizer that can execute JavaScript/Typescript and send page hit data to a Microsoft Application Insights instance. One prerequisite is to create App Insights resource so we have the instrumentation key. Once we have the key we are ready to proceed with the implementation on the SharePoint side.

I also assume that you have SharePoint Framework development environment setup and new application customizer is scaffold-ed using the Yeoman generator so we can focus on the actual app insights implementation.


Add app insights reference to the package.json


We have to add the application insights javascript library to our solution



"dependencies": {
...
"applicationinsights-js":"1.0.15"
},
"devDependencies": {
...
"@types/applicationinsights-js":"1.0.5"
}


Run npm install to get the new packages


npm install


Able to configure application insights without the need to redeploy the SharePoint solution package


When creating the app customizer we can add the app insights instrumentation key as property of the app customizer so we can change it at any given time by just running office365 cli or PnP PowerShell script. So our application property can look like that:



export interface IAppInsightsApplicationCustomizerProperties {

instrumentationKey: string;
}


Then we can import the application insights into our customizer and set it to send page hits. Here is how the entire code might look like:



/// <reference types="applicationinsights-js" />

import { override } from '@microsoft/decorators';
import { Log } from '@microsoft/sp-core-library';
import { BaseApplicationCustomizer } from '@microsoft/sp-application-base';
import {AppInsights} from "applicationinsights-js";
const LOG_SOURCE: string = 'AppInsightsApplicationCustomizer';


export interface IAppInsightsApplicationCustomizerProperties {
// App Insights instrumentation key
instrumentationKey: string;
}

export default class AppInsightsApplicationCustomizer
extends BaseApplicationCustomizer<IAppInsightsApplicationCustomizerProperties> {

@override
public onInit(): Promise<void> {
Log.info(LOG_SOURCE, `Initialized.`);

/* Call downloadAndSetup to download full ApplicationInsights script from CDN and initialize it with instrumentation key */
AppInsights.downloadAndSetup({ instrumentationKey: this.properties.instrumentationKey });
/* example: track page view */
AppInsights.trackPageView(
null, //"FirstPage", /* (optional) page name */
null, /* (optional) page url if available */
{
user: this.context.pageContext.user.displayName,
siteUrl: this.context.pageContext.web.absoluteUrl,
currentUICultureName: this.context.pageContext.cultureInfo.currentUICultureName,
cultureInfo: this.context.pageContext.cultureInfo.currentCultureName,
correlationId: this.context.pageContext.site.correlationId.toString(),
siteId: this.context.pageContext.site.id.toString(),
language: this.context.pageContext.web.language.toString()
}, /* (optional) dimension dictionary */
{ client: 1 }, /* (optional) metric dictionary */
//123 /* page view duration in milliseconds */
);

/* example: track event */
//AppInsights.trackEvent("TestEvent", { prop1: "prop1", prop2: "prop2" }, { measurement1: 1 });
Log.info(LOG_SOURCE, `trackPageView sent`);

return Promise.resolve();
}
}


Custom data payload when page hit request is send


We can use the SharePoint Framewrok component context as quick reference to information if we have to pass some additional details along with the page hits. As can be seen from the code above, I am sending user display name, absolute url and other details from the context of the application customizer. This is handy and does not cost additional requests, but the payload can be any type of data. For example you might like to access the user profiles service and pass more details for the current user or access a list and pass data from that list.


Change the app insights instrumentation key


Since we added the instrumentation key as property, we can easily change it without the need to redeploy the Application Customizer solution package. We just need to know the user custom action id that the customizer has been deployed with.

The office 365 cli tool has handy command for updating the instrumentation key:



spo customaction set -u https://contoso.sharepoint.com/sites/test -i 058140e3-0e37-44fc-a1d3-79c487d371a3 -p '{"instrumentationKey":"YOUR_NEW_KEY"}'


PnP Powershell cmdlet is also available :



Remove-PnPCustomAction -Identity e2ef3a4b-9f85-40fc-9e34-1d4c876dc065

Add-PnPCustomAction -Title 'AppInsightsApplicationCustomizer' -Location ClientSideExtension.ApplicationCustomizer -ClientSideComponentId 6efbae5b-8af4-4550-8469-22467f7eb884 -ClientSideComponentProperties "{ ""instrumentationKey"": ""YOUR_NEW_KEY"" }"


Conclusion


This is maybe 30 mins setup, but can give the business valuable information on the usage of the modern SharePoint pages and it is flexible enough so the key can be changed without the need to redeploy the solution.