Applicationinsights Web TS
MicrosoftOfficialCreated by Microsoft
- Skill
- Tool integration
- Cloud and DevOps
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The Application Insights JavaScript SDK provides comprehensive Real User Monitoring (RUM) for web applications, including React, React Native, and Angular. It enables automatic collection of page views, dependencies, exceptions, and custom events. The SDK supports distributed tracing by propagating W3C trace context, allowing browser-side telemetry to correlate with backend OpenTelemetry spans. It also includes specific support for tracking GenAI agent interactions using OpenTelemetry semantic conventions.
What it does
- Auto-collects page views, AJAX/fetch dependencies, and unhandled exceptions.
- Supports distributed tracing to correlate browser activity with backend services.
- Provides framework-specific plugins for React, React Native, and Angular.
- Enables custom telemetry collection for events, metrics, and traces.
- Supports OpenTelemetry semantic conventions for tracking GenAI agent, tool, and model calls.
- Offers click analytics via an optional plugin to track user interactions.
When to use it
- When you need to monitor user experience and performance in browser-based applications.
- When you need to correlate client-side browser events with backend OpenTelemetry traces.
- When you are building AI-enabled web applications and need to track agent interactions.
- When you require a standardized way to capture and report browser-side errors and metrics.
Advantages
- Native support for OpenTelemetry GenAI semantic conventions.
- Seamless integration with Azure Monitor and Log Analytics.
- Extensible architecture with support for various frontend frameworks.
- Configurable telemetry initializers for data enrichment and filtering.
Usage examples
- “How do I initialize the Application Insights SDK in a TypeScript web application?”
- You import the ApplicationInsights class, configure it with your connection string, and call loadAppInsights() during your application's early startup phase.
- “How can I track a custom event in my React application?”
- You use the trackEvent method provided by the SDK instance, passing the event name and any relevant custom properties.
- “How do I link browser-side AI agent calls to my backend traces?”
- You use the trackDependencyData method with attributes following the OTel GenAI semantic conventions, ensuring distributedTracingMode is set to 2.
- “How do I filter out specific telemetry items before they are sent?”
- You use the addTelemetryInitializer method to inspect each telemetry item and return false to drop items that meet your exclusion criteria.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/applicationinsights-web-ts/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip applicationinsights-web-ts.zip -d .agents/skills
Documentation by Microsoft
Application Insights JavaScript SDK (Web) for TypeScript
Real User Monitoring (RUM) for browser apps with @microsoft/applicationinsights-web. Auto-collects page views, AJAX/fetch dependencies, unhandled exceptions, and (with the Click Analytics plugin) clicks. Supports custom events, metrics, and GenAI agent traces that follow OpenTelemetry GenAI semantic conventions and correlate to backend spans via W3C Trace Context.
Distinct from
azure-monitor-opentelemetry-ts, which is for Node.js server apps. This skill is for browser/web code (and React Native).
Before Implementation
Search microsoft-docs MCP for current API patterns:
Query: "Application Insights JavaScript SDK setup"
Query: "Application Insights JavaScript SDK configuration"
Query: "Application Insights JavaScript framework extensions React Angular"
Verify package version:
npm view @microsoft/applicationinsights-web version
Packages
| Package | Purpose |
|---|---|
@microsoft/applicationinsights-web | Core RUM SDK (page views, AJAX, exceptions). |
@microsoft/applicationinsights-clickanalytics-js | Auto-collect click telemetry. |
@microsoft/applicationinsights-react-js | React plugin (router instrumentation, hooks, HOC, ErrorBoundary). |
@microsoft/applicationinsights-react-native | React Native plugin (native crashes, sessions). |
@microsoft/applicationinsights-angularplugin-js | Angular plugin (router events, ErrorHandler). |
@microsoft/applicationinsights-debugplugin-js | Dev-only telemetry inspector. |
@microsoft/applicationinsights-perfmarkmeasure-js | User Timing (performance.mark/measure) integration. |
Installation
npm i --save @microsoft/applicationinsights-web
# Optional plugins (install only what you use):
npm i --save @microsoft/applicationinsights-clickanalytics-js
npm i --save @microsoft/applicationinsights-react-js @microsoft/applicationinsights-react-native @microsoft/applicationinsights-angularplugin-jsTypings ship with the package — no separate @types/... install needed.
Connection String
The browser SDK requires a connection string at init time. It ships in plaintext to clients — Microsoft Entra ID auth is not supported for browser telemetry. Use a separate App Insights resource with local auth enabled for browser RUM if you need to isolate it from backend telemetry.
# Vite / CRA / Next.js — expose to client via the public env prefix
VITE_APPINSIGHTS_CONNECTION_STRING="InstrumentationKey=...;IngestionEndpoint=https://...;LiveEndpoint=https://..."
NEXT_PUBLIC_APPINSIGHTS_CONNECTION_STRING="InstrumentationKey=..."Quick Start (npm)
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
export const appInsights = new ApplicationInsights({
config: {
connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,
enableAutoRouteTracking: true, // SPA route changes -> page views
enableCorsCorrelation: true, // propagate Request-Id / traceparent to cross-origin AJAX
enableRequestHeaderTracking: true,
enableResponseHeaderTracking: true,
distributedTracingMode: 2, // DistributedTracingModes.AI_AND_W3C — emit traceparent for backend correlation
autoTrackPageVisitTime: true,
disableFetchTracking: false, // fetch() is auto-instrumented by default
excludeRequestFromAutoTrackingPatterns: [/livemetrics\.azure\.com/i]
}
});
appInsights.loadAppInsights();
appInsights.trackPageView();Call loadAppInsights() exactly once, as early as possible (before user interactions you want tracked). Then trackPageView() for the initial load — when enableAutoRouteTracking is on, subsequent route changes are automatic.
Quick Start (SDK Loader Script)
Recommended when you want auto-updating SDK and zero build pipeline. Paste this as the first <script> in <head>:
<script type="text/javascript" src="https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js" crossorigin="anonymous"></script>
<script type="text/javascript">
var appInsights = window.appInsights || function (cfg) {
/* See: https://learn.microsoft.com/azure/azure-monitor/app/javascript-sdk
Use the latest snippet from the Microsoft Learn page above — it includes
backup-CDN failover (cr), SDK-load-failure reporting, and the queue shim
so calls before SDK ready are not lost. */
}({ src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js",
crossOrigin: "anonymous",
cfg: { connectionString: "YOUR_CONNECTION_STRING" } });
</script>Loader-only API (queued until SDK loads): trackEvent, trackPageView, trackException, trackTrace, trackDependencyData, trackMetric, trackPageViewPerformance, startTrackPage, stopTrackPage, startTrackEvent, stopTrackEvent, addTelemetryInitializer, setAuthenticatedUserContext, clearAuthenticatedUserContext, flush.
Core Tracking APIs
// Page views (SPAs that disable enableAutoRouteTracking)
appInsights.trackPageView({ name: "Checkout", uri: "/checkout", properties: { cartSize: 3 } });
// Custom events (user actions, business events)
appInsights.trackEvent({ name: "PurchaseCompleted" }, { orderId: "ord_123", amountUsd: 49.95 });
// Exceptions (caught errors)
try {
await pay(order);
} catch (err) {
appInsights.trackException({ exception: err as Error, severityLevel: 3, properties: { orderId: order.id } });
}
// Traces (logs, severity 0=Verbose, 1=Info, 2=Warning, 3=Error, 4=Critical)
appInsights.trackTrace({ message: "Cart hydrated from local storage", severityLevel: 1 });
// Custom metrics (numeric)
appInsights.trackMetric({ name: "checkout.duration_ms", average: 1234 });
// Dependencies (manually-tracked outbound calls — fetch/XHR are auto-tracked)
appInsights.trackDependencyData({
id: crypto.randomUUID(),
name: "GET /api/orders",
duration: 87, success: true, responseCode: 200,
data: "https://api.example.com/api/orders", target: "api.example.com", type: "Fetch"
});
// User identity (set ONCE per authenticated session — values are PII; do not pass emails)
appInsights.setAuthenticatedUserContext("user-id-123", "tenant-456", /*storeInCookie*/ true);
appInsights.clearAuthenticatedUserContext(); // on logout
// Force send before unload
appInsights.flush();Telemetry Initializers (enrichment & filtering)
Run for every envelope before send. Return false to drop.
import type { ITelemetryItem } from "@microsoft/applicationinsights-web";
appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
item.tags ??= {};
item.tags["ai.cloud.role"] = "web-shop";
item.tags["ai.cloud.roleInstance"] = window.location.hostname;
item.data ??= {};
item.data["app.version"] = import.meta.env.VITE_APP_VERSION;
item.data["app.build"] = import.meta.env.VITE_BUILD_SHA;
// Drop noisy health-check page views
if (item.baseType === "PageviewData" && item.baseData?.uri?.endsWith("/healthz")) return false;
// Scrub query-string secrets
if (item.baseData?.uri) {
item.baseData.uri = item.baseData.uri.replace(/([?&](token|sig|key)=)[^&]+/gi, "$1REDACTED");
}
});Click Analytics
import { ClickAnalyticsPlugin } from "@microsoft/applicationinsights-clickanalytics-js";
const clickPlugin = new ClickAnalyticsPlugin();
const appInsights = new ApplicationInsights({
config: {
connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,
extensions: [clickPlugin],
extensionConfig: {
[clickPlugin.identifier]: {
autoCapture: true,
dataTags: { useDefaultContentNameOrId: true, customDataPrefix: "data-ai-" },
urlCollectHash: false,
behaviorValidator: (b: string) => /^[a-z0-9_]+$/.test(b) ? b : ""
}
}
}
});
appInsights.loadAppInsights();Mark elements with data-ai-* attributes; clicks are emitted as Custom Events with parent-content metadata.
SPA Route Tracking
Built-in: set
enableAutoRouteTracking: true. Hookshistory.pushState/replaceStateandpopstate.React Router: use
@microsoft/applicationinsights-react-jswithAITrackingHOC (see references/framework-extensions.md).Manual: call
appInsights.trackPageView({ name, uri })in your router'suseEffecton route change. DisableenableAutoRouteTrackingto avoid double counting.
Distributed Tracing (correlate to backend)
Set distributedTracingMode: 2 (DistributedTracingModes.AI_AND_W3C). The SDK adds traceparent (and legacy Request-Id) to outbound fetch/XHR. Backends instrumented with OpenTelemetry (e.g. @azure/monitor-opentelemetry) auto-link to the browser's operation_Id.
For cross-origin calls, also set enableCorsCorrelation: true and add the calling origin to the CORS exposed headers on the API.
GenAI Agent Traces (OTel semantic conventions)
When the browser invokes an AI agent (function-calling, tool-use, model calls direct from the client), emit App Insights Dependency telemetry whose attributes follow the OpenTelemetry GenAI semantic conventions so they are queryable alongside backend agent spans in App Insights / Log Analytics.
Set the opt-in env first so backend instrumentations agree on the same schema version:
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimentalRequired attribute keys (use the OTel names verbatim)
| Span / op | Required attributes |
|---|---|
invoke_agent {agent.name} | gen_ai.operation.name=invoke_agent, gen_ai.provider.name, gen_ai.agent.name, gen_ai.agent.id (when known) |
create_agent {agent.name} | gen_ai.operation.name=create_agent, gen_ai.provider.name, gen_ai.agent.name, gen_ai.request.model |
chat {model} | gen_ai.operation.name=chat, gen_ai.provider.name, gen_ai.request.model, gen_ai.response.model, gen_ai.usage.input_tokens, gen_ai.usage.output_tokens |
execute_tool {tool.name} | gen_ai.operation.name=execute_tool, gen_ai.tool.name, gen_ai.tool.type (function | extension | datastore), gen_ai.tool.call.id |
gen_ai.provider.name well-known values: openai, azure.ai.openai, azure.ai.inference, anthropic, aws.bedrock, gcp.gemini, gcp.vertex_ai, cohere, mistral_ai, groq, deepseek, perplexity, x_ai, ibm.watsonx.ai.
Sensitive content opt-in.
gen_ai.system_instructions,gen_ai.input.messages,gen_ai.output.messages,gen_ai.tool.call.arguments,gen_ai.tool.call.resultare Opt-In by default. Gate them behind a runtime flag and avoid them in production unless you have approved data handling.
Pattern: invoke_agent + nested tool/model spans
import { ApplicationInsights, SeverityLevel } from "@microsoft/applicationinsights-web";
type GenAiAttrs = Record<string, string | number | boolean | undefined>;
function startGenAiSpan(name: string, attrs: GenAiAttrs) {
const id = crypto.randomUUID();
const start = performance.now();
const baseProps: GenAiAttrs = { "gen_ai.span.id": id, ...attrs };
return {
end(success: boolean, extra: GenAiAttrs = {}, error?: Error) {
const duration = Math.round(performance.now() - start);
const properties = { ...baseProps, ...extra };
appInsights.trackDependencyData({
id, name, duration, success,
responseCode: error ? 500 : 200,
type: "GenAI",
target: String(attrs["gen_ai.provider.name"] ?? "genai"),
properties: properties as Record<string, string>
});
if (error) {
appInsights.trackException({
exception: error,
severityLevel: SeverityLevel.Error,
properties: { ...properties, "error.type": error.name } as Record<string, string>
});
}
}
};
}
// Agent invocation
const agentSpan = startGenAiSpan("invoke_agent ResearchAssistant", {
"gen_ai.operation.name": "invoke_agent",
"gen_ai.provider.name": "azure.ai.openai",
"gen_ai.agent.name": "ResearchAssistant",
"gen_ai.agent.id": "asst_5j66UpCpwteGg4YSxUnt7lPY",
"gen_ai.request.model": "gpt-4o-mini",
"server.address": "myresource.openai.azure.com"
});
try {
// Nested chat completion span
const chat = startGenAiSpan("chat gpt-4o-mini", {
"gen_ai.operation.name": "chat",
"gen_ai.provider.name": "azure.ai.openai",
"gen_ai.request.model": "gpt-4o-mini"
});
const res = await callAzureOpenAi(/* ... */);
chat.end(true, {
"gen_ai.response.model": res.model,
"gen_ai.response.id": res.id,
"gen_ai.response.finish_reasons": JSON.stringify(res.choices.map(c => c.finish_reason)),
"gen_ai.usage.input_tokens": res.usage.prompt_tokens,
"gen_ai.usage.output_tokens": res.usage.completion_tokens,
"gen_ai.output.type": "text"
});
// Nested tool execution span
const tool = startGenAiSpan("execute_tool getWeather", {
"gen_ai.operation.name": "execute_tool",
"gen_ai.tool.name": "getWeather",
"gen_ai.tool.type": "function",
"gen_ai.tool.call.id": "call_abc123"
});
const toolResult = await runGetWeather({ location: "SF" });
tool.end(true);
agentSpan.end(true, {
"gen_ai.usage.input_tokens": res.usage.prompt_tokens,
"gen_ai.usage.output_tokens": res.usage.completion_tokens
});
} catch (err) {
agentSpan.end(false, { "error.type": (err as Error).name }, err as Error);
}The browser's traceparent is automatically attached to outbound fetch (when distributedTracingMode: 2), so downstream Azure OpenAI / agent backend spans hang under the same operation_Id in App Insights.
For the full attribute reference, well-known values, and content-capture guidance, see references/agent-traces.md.
KQL: query GenAI traces in App Insights
dependencies
| where type == "GenAI"
| extend op = tostring(customDimensions["gen_ai.operation.name"]),
agent = tostring(customDimensions["gen_ai.agent.name"]),
model = tostring(customDimensions["gen_ai.request.model"]),
tin = toint(customDimensions["gen_ai.usage.input_tokens"]),
tout = toint(customDimensions["gen_ai.usage.output_tokens"])
| summarize calls=count(), p95_ms=percentile(duration, 95),
avg_in=avg(tin), avg_out=avg(tout) by op, agent, model, bin(timestamp, 5m)React (TypeScript)
See references/framework-extensions.md for full React, React Native, Angular, Next.js, and Vite recipes.
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
import { ReactPlugin, withAITracking } from "@microsoft/applicationinsights-react-js";
import { createBrowserHistory } from "history";
const reactPlugin = new ReactPlugin();
const browserHistory = createBrowserHistory();
export const appInsights = new ApplicationInsights({
config: {
connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,
extensions: [reactPlugin],
extensionConfig: { [reactPlugin.identifier]: { history: browserHistory } }
}
});
appInsights.loadAppInsights();
export const TrackedCheckout = withAITracking(reactPlugin, Checkout, "Checkout");React Native
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
import { ReactNativePlugin } from "@microsoft/applicationinsights-react-native";
const rnPlugin = new ReactNativePlugin();
const appInsights = new ApplicationInsights({
config: {
connectionString: process.env.EXPO_PUBLIC_APPINSIGHTS_CONNECTION_STRING,
extensions: [rnPlugin],
disableFetchTracking: false
}
});
appInsights.loadAppInsights();Performance — Web Vitals
Auto-collected: page-load timings via PerformanceTiming / PerformanceNavigationTiming. To add Core Web Vitals:
import { onCLS, onLCP, onINP, type Metric } from "web-vitals";
function send(m: Metric) {
appInsights.trackMetric(
{ name: `web_vitals.${m.name.toLowerCase()}`, average: m.value },
{ rating: m.rating, navigationType: m.navigationType, id: m.id }
);
}
onCLS(send); onLCP(send); onINP(send);Cookies & Privacy
new ApplicationInsights({ config: {
connectionString,
isCookieUseDisabled: true, // hard-disable all cookies
cookieCfg: { enabled: true, domain: ".example.com", path: "/", expiry: 365 }
}});To honor consent dynamically:
appInsights.getCookieMgr().setEnabled(userGaveConsent);
appInsights.config.disableTelemetry = !userGaveConsent;Sampling
Server-side ingestion sampling (recommended) is configured on the App Insights resource. SDK-side sampling reduces network use:
new ApplicationInsights({ config: { connectionString, samplingPercentage: 50 } });Per-type sampling via telemetry initializer: drop with return false based on item.baseType.
Offline / Send-on-Unload
The SDK uses sendBeacon (default onunloadDisableBeacon: false) to flush on pagehide / unload. For SPAs, also call appInsights.flush() before destructive transitions (logout, hard reload).
Common Pitfalls
Do not initialize twice. Re-importing the module under different bundles produces duplicate page views. Use a single shared module export.
Initialize before first user input to avoid losing early clicks/exceptions.
Connection string is public — never reuse the same App Insights resource for backend secrets.
enableAutoRouteTracking+ manualtrackPageView= duplicates. Pick one.CORS distributed tracing requires the API to allow
Request-Id,Request-Context,traceparent,tracestaterequest headers and exposeRequest-Contextresponse header.GenAI sensitive content (
gen_ai.input.messagesetc.) is Opt-In — never log without an explicit runtime flag and approved data handling.Agent token usage is on
chatspans, notinvoke_agent— copy aggregated usage to the parent agent span only if you know it.React StrictMode double-invokes effects in dev — guard
loadAppInsights()with a module-level singleton.
Bundle Size
The full web SDK is ~110 KB minified (~36 KB gzipped). For aggressive budgets, use the Loader Script path so the SDK loads asynchronously off the critical path, or tree-shake unused plugins.
Key Types
import {
ApplicationInsights,
SeverityLevel,
DistributedTracingModes,
type IConfiguration,
type IConfig,
type ITelemetryItem,
type ITelemetryPlugin,
type ICustomProperties,
type IPageViewTelemetry,
type IEventTelemetry,
type IExceptionTelemetry,
type ITraceTelemetry,
type IMetricTelemetry,
type IDependencyTelemetry
} from "@microsoft/applicationinsights-web";Best Practices
One singleton instance exported from a single module.
Initialize early in the app entrypoint, before router setup.
Use telemetry initializers to attach
app.version,tenantId, and to scrub PII / query-string secrets.Set
distributedTracingMode: 2and ensure your APIs accept/expose W3C trace context headers.For GenAI, follow OTel
gen_ai.*attribute names verbatim — they are queryable across browser and backend telemetry uniformly.Gate sensitive content capture (
gen_ai.input.messages/gen_ai.output.messages) behind a build-time or runtime opt-in.Flush on logout / sensitive navigation so in-flight telemetry isn't dropped.
References
references/agent-traces.md — Full OTel GenAI semconv distilled (agent / model / tool spans, attributes, content capture).
references/framework-extensions.md — React, React Native, Angular, Next.js, Vite recipes.
references/configuration.md — Full
IConfigurationreference and tuning guide.Microsoft Learn: https://learn.microsoft.com/azure/azure-monitor/app/javascript-sdk
ApplicationInsights-JS source: https://github.com/microsoft/ApplicationInsights-JS
OTel GenAI semantic conventions: https://opentelemetry.io/docs/specs/semconv/gen-ai/
Files
- ATTRIBUTION.mdAdded by AutoGineer939 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md20.4 KiB
- references/agent-traces.md7.6 KiB
- references/configuration.md6.5 KiB
- references/framework-extensions.md7.7 KiB
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills · .github/skills/applicationinsights-web-ts · commit 0696600
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Also distributed in
- microsoft/skills
AutoGineer is not affiliated with or endorsed by Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download applicationinsights-web-ts.zip