[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6NVMBM71P0SJ4DEPQKPNEH9":3,"skill-same:01M6NVMBM71P0SJ4DEPQKPNEH9":66},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":28,"commitSha":47,"skillDirectory":48,"forksCount":13,"repositoryHtmlUrl":49,"repositoryHomepageUrl":6,"ownerHtmlUrl":50,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":51,"install":52,"resources":65},"01M6NVMBM71P0SJ4DEPQKPNEH9","applicationinsights-web-ts",null,"Instrument browser\u002Fweb apps with the Application Insights JavaScript SDK (@microsoft\u002Fapplicationinsights-web).","duc-duy-1612\u002FOnline-Delivery-Systems-Web","duc-duy-1612","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F192231384?v=4","01M6NSDKQQDKVTHZ8DZMZ1VYY6","01M6NSDKW8DDVTQHBT1HBDDJPT",0,"MIT","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fapplicationinsights-web-ts\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"web","applicationinsights web ts","license","tree","insights","javascript sdk","with","apps","critical","wed","main","https","typescript","browser","azure","official","microsoft","javascript","sdk","github","2026-11-10 10:12:30",false,"---\nname: applicationinsights-web-ts\ndescription: \"Instrument browser\u002Fweb apps with the Application Insights JavaScript SDK (@microsoft\u002Fapplicationinsights-web).\"\nrisk: critical\nsource: https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\nsource_repo: microsoft\u002Fskills\nsource_type: official\ndate_added: 2026-07-01\nlicense: MIT\nlicense_source: https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Fblob\u002Fmain\u002FLICENSE\n---\n\n# Application Insights JavaScript SDK (Web) for TypeScript\n## When to Use\n\nUse this skill when you need instrument browser\u002Fweb apps with the Application Insights JavaScript SDK (@microsoft\u002Fapplicationinsights-web). Use for Real User Monitoring (RUM) — page views, clicks, AJAX\u002Ffetch dependencies, exceptions, custom events, and browser-side GenAI agent traces correlated to backend...\n\n\nReal User Monitoring (RUM) for browser apps with `@microsoft\u002Fapplicationinsights-web`. Auto-collects page views, AJAX\u002Ffetch 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.\n\n> **Distinct from `azure-monitor-opentelemetry-ts`**, which is for Node.js server apps. This skill is for **browser\u002Fweb** code (and React Native).\n\n## Before Implementation\n\nSearch `microsoft-docs` MCP for current API patterns:\n\n- Query: \"Application Insights JavaScript SDK setup\"\n- Query: \"Application Insights JavaScript SDK configuration\"\n- Query: \"Application Insights JavaScript framework extensions React Angular\"\n- Verify package version: `npm view @microsoft\u002Fapplicationinsights-web version`\n\n## Packages\n\n| Package | Purpose |\n| --- | --- |\n| `@microsoft\u002Fapplicationinsights-web` | Core RUM SDK (page views, AJAX, exceptions). |\n| `@microsoft\u002Fapplicationinsights-clickanalytics-js` | Auto-collect click telemetry. |\n| `@microsoft\u002Fapplicationinsights-react-js` | React plugin (router instrumentation, hooks, HOC, ErrorBoundary). |\n| `@microsoft\u002Fapplicationinsights-react-native` | React Native plugin (native crashes, sessions). |\n| `@microsoft\u002Fapplicationinsights-angularplugin-js` | Angular plugin (router events, ErrorHandler). |\n| `@microsoft\u002Fapplicationinsights-debugplugin-js` | Dev-only telemetry inspector. |\n| `@microsoft\u002Fapplicationinsights-perfmarkmeasure-js` | User Timing (`performance.mark\u002Fmeasure`) integration. |\n\n## Installation\n\n```bash\nnpm i --save @microsoft\u002Fapplicationinsights-web\n# Optional plugins (install only what you use):\nnpm i --save @microsoft\u002Fapplicationinsights-clickanalytics-js\nnpm i --save @microsoft\u002Fapplicationinsights-react-js @microsoft\u002Fapplicationinsights-react-native @microsoft\u002Fapplicationinsights-angularplugin-js\n```\n\nTypings ship with the package — no separate `@types\u002F...` install needed.\n\n## Connection String\n\nThe 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.\n\n```bash\n# Vite \u002F CRA \u002F Next.js — expose to client via the public env prefix\nVITE_APPINSIGHTS_CONNECTION_STRING=\"InstrumentationKey=...;IngestionEndpoint=https:\u002F\u002F...;LiveEndpoint=https:\u002F\u002F...\"\nNEXT_PUBLIC_APPINSIGHTS_CONNECTION_STRING=\"InstrumentationKey=...\"\n```\n\n## Quick Start (npm)\n\n```typescript\nimport { ApplicationInsights } from \"@microsoft\u002Fapplicationinsights-web\";\n\nexport const appInsights = new ApplicationInsights({\n  config: {\n    connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,\n    enableAutoRouteTracking: true,        \u002F\u002F SPA route changes -> page views\n    enableCorsCorrelation: true,          \u002F\u002F propagate Request-Id \u002F traceparent to cross-origin AJAX\n    enableRequestHeaderTracking: true,\n    enableResponseHeaderTracking: true,\n    distributedTracingMode: 2,            \u002F\u002F DistributedTracingModes.AI_AND_W3C — emit traceparent for backend correlation\n    autoTrackPageVisitTime: true,\n    disableFetchTracking: false,          \u002F\u002F fetch() is auto-instrumented by default\n    excludeRequestFromAutoTrackingPatterns: [\u002Flivemetrics\\.azure\\.com\u002Fi]\n  }\n});\n\nappInsights.loadAppInsights();\nappInsights.trackPageView();\n```\n\nCall `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.\n\n## Quick Start (SDK Loader Script)\n\nRecommended when you want auto-updating SDK and zero build pipeline. Paste this as the **first** `\u003Cscript>` in `\u003Chead>`:\n\n```html\n\u003Cscript type=\"text\u002Fjavascript\" src=\"https:\u002F\u002Fjs.monitor.azure.com\u002Fscripts\u002Fb\u002Fai.3.gbl.min.js\" crossorigin=\"anonymous\">\u003C\u002Fscript>\n\u003Cscript type=\"text\u002Fjavascript\">\n  var appInsights = window.appInsights || function (cfg) {\n    \u002F* See: https:\u002F\u002Flearn.microsoft.com\u002Fazure\u002Fazure-monitor\u002Fapp\u002Fjavascript-sdk\n       Use the latest snippet from the Microsoft Learn page above — it includes\n       backup-CDN failover (cr), SDK-load-failure reporting, and the queue shim\n       so calls before SDK ready are not lost. *\u002F\n  }({ src: \"https:\u002F\u002Fjs.monitor.azure.com\u002Fscripts\u002Fb\u002Fai.3.gbl.min.js\",\n      crossOrigin: \"anonymous\",\n      cfg: { connectionString: \"YOUR_CONNECTION_STRING\" } });\n\u003C\u002Fscript>\n```\n\nLoader-only API (queued until SDK loads): `trackEvent`, `trackPageView`, `trackException`, `trackTrace`, `trackDependencyData`, `trackMetric`, `trackPageViewPerformance`, `startTrackPage`, `stopTrackPage`, `startTrackEvent`, `stopTrackEvent`, `addTelemetryInitializer`, `setAuthenticatedUserContext`, `clearAuthenticatedUserContext`, `flush`.\n\n## Core Tracking APIs\n\n```typescript\n\u002F\u002F Page views (SPAs that disable enableAutoRouteTracking)\nappInsights.trackPageView({ name: \"Checkout\", uri: \"\u002Fcheckout\", properties: { cartSize: 3 } });\n\n\u002F\u002F Custom events (user actions, business events)\nappInsights.trackEvent({ name: \"PurchaseCompleted\" }, { orderId: \"ord_123\", amountUsd: 49.95 });\n\n\u002F\u002F Exceptions (caught errors)\ntry {\n  await pay(order);\n} catch (err) {\n  appInsights.trackException({ exception: err as Error, severityLevel: 3, properties: { orderId: order.id } });\n}\n\n\u002F\u002F Traces (logs, severity 0=Verbose, 1=Info, 2=Warning, 3=Error, 4=Critical)\nappInsights.trackTrace({ message: \"Cart hydrated from local storage\", severityLevel: 1 });\n\n\u002F\u002F Custom metrics (numeric)\nappInsights.trackMetric({ name: \"checkout.duration_ms\", average: 1234 });\n\n\u002F\u002F Dependencies (manually-tracked outbound calls — fetch\u002FXHR are auto-tracked)\nappInsights.trackDependencyData({\n  id: crypto.randomUUID(),\n  name: \"GET \u002Fapi\u002Forders\",\n  duration: 87, success: true, responseCode: 200,\n  data: \"https:\u002F\u002Fapi.example.com\u002Fapi\u002Forders\", target: \"api.example.com\", type: \"Fetch\"\n});\n\n\u002F\u002F User identity (set ONCE per authenticated session — values are PII; do not pass emails)\nappInsights.setAuthenticatedUserContext(\"user-id-123\", \"tenant-456\", \u002F*storeInCookie*\u002F true);\nappInsights.clearAuthenticatedUserContext(); \u002F\u002F on logout\n\n\u002F\u002F Force send before unload\nappInsights.flush();\n```\n\n## Telemetry Initializers (enrichment & filtering)\n\nRun for every envelope before send. Return `false` to drop.\n\n```typescript\nimport type { ITelemetryItem } from \"@microsoft\u002Fapplicationinsights-web\";\n\nappInsights.addTelemetryInitializer((item: ITelemetryItem) => {\n  item.tags ??= {};\n  item.tags[\"ai.cloud.role\"] = \"web-shop\";\n  item.tags[\"ai.cloud.roleInstance\"] = window.location.hostname;\n  item.data ??= {};\n  item.data[\"app.version\"] = import.meta.env.VITE_APP_VERSION;\n  item.data[\"app.build\"] = import.meta.env.VITE_BUILD_SHA;\n\n  \u002F\u002F Drop noisy health-check page views\n  if (item.baseType === \"PageviewData\" && item.baseData?.uri?.endsWith(\"\u002Fhealthz\")) return false;\n\n  \u002F\u002F Scrub query-string secrets\n  if (item.baseData?.uri) {\n    item.baseData.uri = item.baseData.uri.replace(\u002F([?&](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Ftoken|sig|key)=)[^&]+\u002Fgi, \"$1REDACTED\");\n  }\n});\n```\n\n## Click Analytics\n\n```typescript\nimport { ClickAnalyticsPlugin } from \"@microsoft\u002Fapplicationinsights-clickanalytics-js\";\n\nconst clickPlugin = new ClickAnalyticsPlugin();\nconst appInsights = new ApplicationInsights({\n  config: {\n    connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,\n    extensions: [clickPlugin],\n    extensionConfig: {\n      [clickPlugin.identifier]: {\n        autoCapture: true,\n        dataTags: { useDefaultContentNameOrId: true, customDataPrefix: \"data-ai-\" },\n        urlCollectHash: false,\n        behaviorValidator: (b: string) => \u002F^[a-z0-9_]+$\u002F.test(b) ? b : \"\"\n      }\n    }\n  }\n});\nappInsights.loadAppInsights();\n```\n\nMark elements with `data-ai-*` attributes; clicks are emitted as Custom Events with parent-content metadata.\n\n## SPA Route Tracking\n\n- **Built-in:** set `enableAutoRouteTracking: true`. Hooks `history.pushState\u002FreplaceState` and `popstate`.\n- **React Router:** use `@microsoft\u002Fapplicationinsights-react-js` `withAITracking` HOC (see [references\u002Fframework-extensions.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fframework-extensions.md)).\n- **Manual:** call `appInsights.trackPageView({ name, uri })` in your router's `useEffect` on route change. Disable `enableAutoRouteTracking` to avoid double counting.\n\n## Distributed Tracing (correlate to backend)\n\nSet `distributedTracingMode: 2` (`DistributedTracingModes.AI_AND_W3C`). The SDK adds `traceparent` (and legacy `Request-Id`) to outbound `fetch`\u002F`XHR`. Backends instrumented with **OpenTelemetry** (e.g. `@azure\u002Fmonitor-opentelemetry`) auto-link to the browser's operation_Id.\n\nFor cross-origin calls, also set `enableCorsCorrelation: true` and add the calling origin to the **CORS exposed headers** on the API.\n\n## GenAI Agent Traces (OTel semantic conventions)\n\nWhen 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 \u002F Log Analytics.\n\n**Set the opt-in env first** so backend instrumentations agree on the same schema version:\n\n```bash\nOTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental\n```\n\n### Required attribute keys (use the OTel names verbatim)\n\n| Span \u002F op | Required attributes |\n| --- | --- |\n| `invoke_agent {agent.name}` | `gen_ai.operation.name=invoke_agent`, `gen_ai.provider.name`, `gen_ai.agent.name`, `gen_ai.agent.id` (when known) |\n| `create_agent {agent.name}` | `gen_ai.operation.name=create_agent`, `gen_ai.provider.name`, `gen_ai.agent.name`, `gen_ai.request.model` |\n| `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` |\n| `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` |\n\n`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`.\n\n> **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.result` are **Opt-In** by default. Gate them behind a runtime flag and avoid them in production unless you have approved data handling.\n\n### Pattern: invoke_agent + nested tool\u002Fmodel spans\n\n```typescript\nimport { ApplicationInsights, SeverityLevel } from \"@microsoft\u002Fapplicationinsights-web\";\n\ntype GenAiAttrs = Record\u003Cstring, string | number | boolean | undefined>;\n\nfunction startGenAiSpan(name: string, attrs: GenAiAttrs) {\n  const id = crypto.randomUUID();\n  const start = performance.now();\n  const baseProps: GenAiAttrs = { \"gen_ai.span.id\": id, ...attrs };\n  return {\n    end(success: boolean, extra: GenAiAttrs = {}, error?: Error) {\n      const duration = Math.round(performance.now() - start);\n      const properties = { ...baseProps, ...extra };\n      appInsights.trackDependencyData({\n        id, name, duration, success,\n        responseCode: error ? 500 : 200,\n        type: \"GenAI\",\n        target: String(attrs[\"gen_ai.provider.name\"] ?? \"genai\"),\n        properties: properties as Record\u003Cstring, string>\n      });\n      if (error) {\n        appInsights.trackException({\n          exception: error,\n          severityLevel: SeverityLevel.Error,\n          properties: { ...properties, \"error.type\": error.name } as Record\u003Cstring, string>\n        });\n      }\n    }\n  };\n}\n\n\u002F\u002F Agent invocation\nconst agentSpan = startGenAiSpan(\"invoke_agent ResearchAssistant\", {\n  \"gen_ai.operation.name\": \"invoke_agent\",\n  \"gen_ai.provider.name\": \"azure.ai.openai\",\n  \"gen_ai.agent.name\": \"ResearchAssistant\",\n  \"gen_ai.agent.id\": \"asst_5j66UpCpwteGg4YSxUnt7lPY\",\n  \"gen_ai.request.model\": \"gpt-4o-mini\",\n  \"server.address\": \"myresource.openai.azure.com\"\n});\n\ntry {\n  \u002F\u002F Nested chat completion span\n  const chat = startGenAiSpan(\"chat gpt-4o-mini\", {\n    \"gen_ai.operation.name\": \"chat\",\n    \"gen_ai.provider.name\": \"azure.ai.openai\",\n    \"gen_ai.request.model\": \"gpt-4o-mini\"\n  });\n  const res = await callAzureOpenAi(\u002F* ... *\u002F);\n  chat.end(true, {\n    \"gen_ai.response.model\": res.model,\n    \"gen_ai.response.id\": res.id,\n    \"gen_ai.response.finish_reasons\": JSON.stringify(res.choices.map(c => c.finish_reason)),\n    \"gen_ai.usage.input_tokens\": res.usage.prompt_tokens,\n    \"gen_ai.usage.output_tokens\": res.usage.completion_tokens,\n    \"gen_ai.output.type\": \"text\"\n  });\n\n  \u002F\u002F Nested tool execution span\n  const tool = startGenAiSpan(\"execute_tool getWeather\", {\n    \"gen_ai.operation.name\": \"execute_tool\",\n    \"gen_ai.tool.name\": \"getWeather\",\n    \"gen_ai.tool.type\": \"function\",\n    \"gen_ai.tool.call.id\": \"call_abc123\"\n  });\n  const toolResult = await runGetWeather({ location: \"SF\" });\n  tool.end(true);\n\n  agentSpan.end(true, {\n    \"gen_ai.usage.input_tokens\": res.usage.prompt_tokens,\n    \"gen_ai.usage.output_tokens\": res.usage.completion_tokens\n  });\n} catch (err) {\n  agentSpan.end(false, { \"error.type\": (err as Error).name }, err as Error);\n}\n```\n\nThe browser's `traceparent` is automatically attached to outbound `fetch` (when `distributedTracingMode: 2`), so downstream Azure OpenAI \u002F agent backend spans hang under the same operation_Id in App Insights.\n\nFor the full attribute reference, well-known values, and content-capture guidance, see [references\u002Fagent-traces.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fagent-traces.md).\n\n### KQL: query GenAI traces in App Insights\n\n```kusto\ndependencies\n| where type == \"GenAI\"\n| extend op   = tostring(customDimensions[\"gen_ai.operation.name\"]),\n         agent = tostring(customDimensions[\"gen_ai.agent.name\"]),\n         model = tostring(customDimensions[\"gen_ai.request.model\"]),\n         tin   = toint(customDimensions[\"gen_ai.usage.input_tokens\"]),\n         tout  = toint(customDimensions[\"gen_ai.usage.output_tokens\"])\n| summarize calls=count(), p95_ms=percentile(duration, 95),\n            avg_in=avg(tin), avg_out=avg(tout) by op, agent, model, bin(timestamp, 5m)\n```\n\n## React (TypeScript)\n\nSee [references\u002Fframework-extensions.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fframework-extensions.md) for full React, React Native, Angular, Next.js, and Vite recipes.\n\n```typescript\nimport { ApplicationInsights } from \"@microsoft\u002Fapplicationinsights-web\";\nimport { ReactPlugin, withAITracking } from \"@microsoft\u002Fapplicationinsights-react-js\";\nimport { createBrowserHistory } from \"history\";\n\nconst reactPlugin = new ReactPlugin();\nconst browserHistory = createBrowserHistory();\n\nexport const appInsights = new ApplicationInsights({\n  config: {\n    connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,\n    extensions: [reactPlugin],\n    extensionConfig: { [reactPlugin.identifier]: { history: browserHistory } }\n  }\n});\nappInsights.loadAppInsights();\n\nexport const TrackedCheckout = withAITracking(reactPlugin, Checkout, \"Checkout\");\n```\n\n## React Native\n\n```typescript\nimport { ApplicationInsights } from \"@microsoft\u002Fapplicationinsights-web\";\nimport { ReactNativePlugin } from \"@microsoft\u002Fapplicationinsights-react-native\";\n\nconst rnPlugin = new ReactNativePlugin();\nconst appInsights = new ApplicationInsights({\n  config: {\n    connectionString: process.env.EXPO_PUBLIC_APPINSIGHTS_CONNECTION_STRING,\n    extensions: [rnPlugin],\n    disableFetchTracking: false\n  }\n});\nappInsights.loadAppInsights();\n```\n\n## Performance — Web Vitals\n\nAuto-collected: page-load timings via `PerformanceTiming` \u002F `PerformanceNavigationTiming`. To add Core Web Vitals:\n\n```typescript\nimport { onCLS, onLCP, onINP, type Metric } from \"web-vitals\";\n\nfunction send(m: Metric) {\n  appInsights.trackMetric(\n    { name: `web_vitals.${m.name.toLowerCase()}`, average: m.value },\n    { rating: m.rating, navigationType: m.navigationType, id: m.id }\n  );\n}\nonCLS(send); onLCP(send); onINP(send);\n```\n\n## Cookies & Privacy\n\n```typescript\nnew ApplicationInsights({ config: {\n  connectionString,\n  isCookieUseDisabled: true,         \u002F\u002F hard-disable all cookies\n  cookieCfg: { enabled: true, domain: \".example.com\", path: \"\u002F\", expiry: 365 }\n}});\n```\n\nTo honor consent dynamically:\n\n```typescript\nappInsights.getCookieMgr().setEnabled(userGaveConsent);\nappInsights.config.disableTelemetry = !userGaveConsent;\n```\n\n## Sampling\n\nServer-side ingestion sampling (recommended) is configured on the App Insights resource. SDK-side sampling reduces network use:\n\n```typescript\nnew ApplicationInsights({ config: { connectionString, samplingPercentage: 50 } });\n```\n\nPer-type sampling via telemetry initializer: drop with `return false` based on `item.baseType`.\n\n## Offline \u002F Send-on-Unload\n\nThe SDK uses `sendBeacon` (default `onunloadDisableBeacon: false`) to flush on `pagehide` \u002F `unload`. For SPAs, also call `appInsights.flush()` before destructive transitions (logout, hard reload).\n\n## Common Pitfalls\n\n1. **Do not initialize twice.** Re-importing the module under different bundles produces duplicate page views. Use a single shared module export.\n2. **Initialize before first user input** to avoid losing early clicks\u002Fexceptions.\n3. **Connection string is public** — never reuse the same App Insights resource for backend secrets.\n4. **`enableAutoRouteTracking` + manual `trackPageView`** = duplicates. Pick one.\n5. **CORS distributed tracing** requires the API to allow `Request-Id`, `Request-Context`, `traceparent`, `tracestate` request headers and expose `Request-Context` response header.\n6. **GenAI sensitive content** (`gen_ai.input.messages` etc.) is Opt-In — never log without an explicit runtime flag and approved data handling.\n7. **Agent token usage is on `chat` spans, not `invoke_agent`** — copy aggregated usage to the parent agent span only if you know it.\n8. **React StrictMode** double-invokes effects in dev — guard `loadAppInsights()` with a module-level singleton.\n\n## Bundle Size\n\nThe 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.\n\n## Key Types\n\n```typescript\nimport {\n  ApplicationInsights,\n  SeverityLevel,\n  DistributedTracingModes,\n  type IConfiguration,\n  type IConfig,\n  type ITelemetryItem,\n  type ITelemetryPlugin,\n  type ICustomProperties,\n  type IPageViewTelemetry,\n  type IEventTelemetry,\n  type IExceptionTelemetry,\n  type ITraceTelemetry,\n  type IMetricTelemetry,\n  type IDependencyTelemetry\n} from \"@microsoft\u002Fapplicationinsights-web\";\n```\n\n## Best Practices\n\n1. **One singleton instance** exported from a single module.\n2. **Initialize early** in the app entrypoint, before router setup.\n3. **Use telemetry initializers** to attach `app.version`, `tenantId`, and to scrub PII \u002F query-string secrets.\n4. **Set `distributedTracingMode: 2`** and ensure your APIs accept\u002Fexpose W3C trace context headers.\n5. **For GenAI**, follow OTel `gen_ai.*` attribute names verbatim — they are queryable across browser and backend telemetry uniformly.\n6. **Gate sensitive content capture** (`gen_ai.input.messages` \u002F `gen_ai.output.messages`) behind a build-time or runtime opt-in.\n7. **Flush on logout \u002F sensitive navigation** so in-flight telemetry isn't dropped.\n\n## References\n\n- [references\u002Fagent-traces.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fagent-traces.md) — Full OTel GenAI semconv distilled (agent \u002F model \u002F tool spans, attributes, content capture).\n- [references\u002Fframework-extensions.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fframework-extensions.md) — React, React Native, Angular, Next.js, Vite recipes.\n- [references\u002Fconfiguration.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fconfiguration.md) — Full `IConfiguration` reference and tuning guide.\n- Microsoft Learn: \u003Chttps:\u002F\u002Flearn.microsoft.com\u002Fazure\u002Fazure-monitor\u002Fapp\u002Fjavascript-sdk>\n- ApplicationInsights-JS source: \u003Chttps:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FApplicationInsights-JS>\n- OTel GenAI semantic conventions: \u003Chttps:\u002F\u002Fopentelemetry.io\u002Fdocs\u002Fspecs\u002Fsemconv\u002Fgen-ai\u002F>\n\n## Limitations\n\n- Use this skill only when the task clearly matches its upstream source and local project context.\n- Verify commands, generated code, dependencies, credentials, and external service behavior before applying changes.\n- Do not treat examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.\n","# Application Insights JavaScript SDK (Web) for TypeScript\n## When to Use\n\nUse this skill when you need instrument browser\u002Fweb apps with the Application Insights JavaScript SDK (@microsoft\u002Fapplicationinsights-web). Use for Real User Monitoring (RUM) — page views, clicks, AJAX\u002Ffetch dependencies, exceptions, custom events, and browser-side GenAI agent traces correlated to backend...\n\n\nReal User Monitoring (RUM) for browser apps with `@microsoft\u002Fapplicationinsights-web`. Auto-collects page views, AJAX\u002Ffetch 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.\n\n> **Distinct from `azure-monitor-opentelemetry-ts`**, which is for Node.js server apps. This skill is for **browser\u002Fweb** code (and React Native).\n\n## Before Implementation\n\nSearch `microsoft-docs` MCP for current API patterns:\n\n- Query: \"Application Insights JavaScript SDK setup\"\n- Query: \"Application Insights JavaScript SDK configuration\"\n- Query: \"Application Insights JavaScript framework extensions React Angular\"\n- Verify package version: `npm view @microsoft\u002Fapplicationinsights-web version`\n\n## Packages\n\n| Package | Purpose |\n| --- | --- |\n| `@microsoft\u002Fapplicationinsights-web` | Core RUM SDK (page views, AJAX, exceptions). |\n| `@microsoft\u002Fapplicationinsights-clickanalytics-js` | Auto-collect click telemetry. |\n| `@microsoft\u002Fapplicationinsights-react-js` | React plugin (router instrumentation, hooks, HOC, ErrorBoundary). |\n| `@microsoft\u002Fapplicationinsights-react-native` | React Native plugin (native crashes, sessions). |\n| `@microsoft\u002Fapplicationinsights-angularplugin-js` | Angular plugin (router events, ErrorHandler). |\n| `@microsoft\u002Fapplicationinsights-debugplugin-js` | Dev-only telemetry inspector. |\n| `@microsoft\u002Fapplicationinsights-perfmarkmeasure-js` | User Timing (`performance.mark\u002Fmeasure`) integration. |\n\n## Installation\n\n```bash\nnpm i --save @microsoft\u002Fapplicationinsights-web\n# Optional plugins (install only what you use):\nnpm i --save @microsoft\u002Fapplicationinsights-clickanalytics-js\nnpm i --save @microsoft\u002Fapplicationinsights-react-js @microsoft\u002Fapplicationinsights-react-native @microsoft\u002Fapplicationinsights-angularplugin-js\n```\n\nTypings ship with the package — no separate `@types\u002F...` install needed.\n\n## Connection String\n\nThe 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.\n\n```bash\n# Vite \u002F CRA \u002F Next.js — expose to client via the public env prefix\nVITE_APPINSIGHTS_CONNECTION_STRING=\"InstrumentationKey=...;IngestionEndpoint=https:\u002F\u002F...;LiveEndpoint=https:\u002F\u002F...\"\nNEXT_PUBLIC_APPINSIGHTS_CONNECTION_STRING=\"InstrumentationKey=...\"\n```\n\n## Quick Start (npm)\n\n```typescript\nimport { ApplicationInsights } from \"@microsoft\u002Fapplicationinsights-web\";\n\nexport const appInsights = new ApplicationInsights({\n  config: {\n    connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,\n    enableAutoRouteTracking: true,        \u002F\u002F SPA route changes -> page views\n    enableCorsCorrelation: true,          \u002F\u002F propagate Request-Id \u002F traceparent to cross-origin AJAX\n    enableRequestHeaderTracking: true,\n    enableResponseHeaderTracking: true,\n    distributedTracingMode: 2,            \u002F\u002F DistributedTracingModes.AI_AND_W3C — emit traceparent for backend correlation\n    autoTrackPageVisitTime: true,\n    disableFetchTracking: false,          \u002F\u002F fetch() is auto-instrumented by default\n    excludeRequestFromAutoTrackingPatterns: [\u002Flivemetrics\\.azure\\.com\u002Fi]\n  }\n});\n\nappInsights.loadAppInsights();\nappInsights.trackPageView();\n```\n\nCall `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.\n\n## Quick Start (SDK Loader Script)\n\nRecommended when you want auto-updating SDK and zero build pipeline. Paste this as the **first** `\u003Cscript>` in `\u003Chead>`:\n\n```html\n\u003Cscript type=\"text\u002Fjavascript\" src=\"https:\u002F\u002Fjs.monitor.azure.com\u002Fscripts\u002Fb\u002Fai.3.gbl.min.js\" crossorigin=\"anonymous\">\u003C\u002Fscript>\n\u003Cscript type=\"text\u002Fjavascript\">\n  var appInsights = window.appInsights || function (cfg) {\n    \u002F* See: https:\u002F\u002Flearn.microsoft.com\u002Fazure\u002Fazure-monitor\u002Fapp\u002Fjavascript-sdk\n       Use the latest snippet from the Microsoft Learn page above — it includes\n       backup-CDN failover (cr), SDK-load-failure reporting, and the queue shim\n       so calls before SDK ready are not lost. *\u002F\n  }({ src: \"https:\u002F\u002Fjs.monitor.azure.com\u002Fscripts\u002Fb\u002Fai.3.gbl.min.js\",\n      crossOrigin: \"anonymous\",\n      cfg: { connectionString: \"YOUR_CONNECTION_STRING\" } });\n\u003C\u002Fscript>\n```\n\nLoader-only API (queued until SDK loads): `trackEvent`, `trackPageView`, `trackException`, `trackTrace`, `trackDependencyData`, `trackMetric`, `trackPageViewPerformance`, `startTrackPage`, `stopTrackPage`, `startTrackEvent`, `stopTrackEvent`, `addTelemetryInitializer`, `setAuthenticatedUserContext`, `clearAuthenticatedUserContext`, `flush`.\n\n## Core Tracking APIs\n\n```typescript\n\u002F\u002F Page views (SPAs that disable enableAutoRouteTracking)\nappInsights.trackPageView({ name: \"Checkout\", uri: \"\u002Fcheckout\", properties: { cartSize: 3 } });\n\n\u002F\u002F Custom events (user actions, business events)\nappInsights.trackEvent({ name: \"PurchaseCompleted\" }, { orderId: \"ord_123\", amountUsd: 49.95 });\n\n\u002F\u002F Exceptions (caught errors)\ntry {\n  await pay(order);\n} catch (err) {\n  appInsights.trackException({ exception: err as Error, severityLevel: 3, properties: { orderId: order.id } });\n}\n\n\u002F\u002F Traces (logs, severity 0=Verbose, 1=Info, 2=Warning, 3=Error, 4=Critical)\nappInsights.trackTrace({ message: \"Cart hydrated from local storage\", severityLevel: 1 });\n\n\u002F\u002F Custom metrics (numeric)\nappInsights.trackMetric({ name: \"checkout.duration_ms\", average: 1234 });\n\n\u002F\u002F Dependencies (manually-tracked outbound calls — fetch\u002FXHR are auto-tracked)\nappInsights.trackDependencyData({\n  id: crypto.randomUUID(),\n  name: \"GET \u002Fapi\u002Forders\",\n  duration: 87, success: true, responseCode: 200,\n  data: \"https:\u002F\u002Fapi.example.com\u002Fapi\u002Forders\", target: \"api.example.com\", type: \"Fetch\"\n});\n\n\u002F\u002F User identity (set ONCE per authenticated session — values are PII; do not pass emails)\nappInsights.setAuthenticatedUserContext(\"user-id-123\", \"tenant-456\", \u002F*storeInCookie*\u002F true);\nappInsights.clearAuthenticatedUserContext(); \u002F\u002F on logout\n\n\u002F\u002F Force send before unload\nappInsights.flush();\n```\n\n## Telemetry Initializers (enrichment & filtering)\n\nRun for every envelope before send. Return `false` to drop.\n\n```typescript\nimport type { ITelemetryItem } from \"@microsoft\u002Fapplicationinsights-web\";\n\nappInsights.addTelemetryInitializer((item: ITelemetryItem) => {\n  item.tags ??= {};\n  item.tags[\"ai.cloud.role\"] = \"web-shop\";\n  item.tags[\"ai.cloud.roleInstance\"] = window.location.hostname;\n  item.data ??= {};\n  item.data[\"app.version\"] = import.meta.env.VITE_APP_VERSION;\n  item.data[\"app.build\"] = import.meta.env.VITE_BUILD_SHA;\n\n  \u002F\u002F Drop noisy health-check page views\n  if (item.baseType === \"PageviewData\" && item.baseData?.uri?.endsWith(\"\u002Fhealthz\")) return false;\n\n  \u002F\u002F Scrub query-string secrets\n  if (item.baseData?.uri) {\n    item.baseData.uri = item.baseData.uri.replace(\u002F([?&](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Ftoken|sig|key)=)[^&]+\u002Fgi, \"$1REDACTED\");\n  }\n});\n```\n\n## Click Analytics\n\n```typescript\nimport { ClickAnalyticsPlugin } from \"@microsoft\u002Fapplicationinsights-clickanalytics-js\";\n\nconst clickPlugin = new ClickAnalyticsPlugin();\nconst appInsights = new ApplicationInsights({\n  config: {\n    connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,\n    extensions: [clickPlugin],\n    extensionConfig: {\n      [clickPlugin.identifier]: {\n        autoCapture: true,\n        dataTags: { useDefaultContentNameOrId: true, customDataPrefix: \"data-ai-\" },\n        urlCollectHash: false,\n        behaviorValidator: (b: string) => \u002F^[a-z0-9_]+$\u002F.test(b) ? b : \"\"\n      }\n    }\n  }\n});\nappInsights.loadAppInsights();\n```\n\nMark elements with `data-ai-*` attributes; clicks are emitted as Custom Events with parent-content metadata.\n\n## SPA Route Tracking\n\n- **Built-in:** set `enableAutoRouteTracking: true`. Hooks `history.pushState\u002FreplaceState` and `popstate`.\n- **React Router:** use `@microsoft\u002Fapplicationinsights-react-js` `withAITracking` HOC (see [references\u002Fframework-extensions.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fframework-extensions.md)).\n- **Manual:** call `appInsights.trackPageView({ name, uri })` in your router's `useEffect` on route change. Disable `enableAutoRouteTracking` to avoid double counting.\n\n## Distributed Tracing (correlate to backend)\n\nSet `distributedTracingMode: 2` (`DistributedTracingModes.AI_AND_W3C`). The SDK adds `traceparent` (and legacy `Request-Id`) to outbound `fetch`\u002F`XHR`. Backends instrumented with **OpenTelemetry** (e.g. `@azure\u002Fmonitor-opentelemetry`) auto-link to the browser's operation_Id.\n\nFor cross-origin calls, also set `enableCorsCorrelation: true` and add the calling origin to the **CORS exposed headers** on the API.\n\n## GenAI Agent Traces (OTel semantic conventions)\n\nWhen 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 \u002F Log Analytics.\n\n**Set the opt-in env first** so backend instrumentations agree on the same schema version:\n\n```bash\nOTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental\n```\n\n### Required attribute keys (use the OTel names verbatim)\n\n| Span \u002F op | Required attributes |\n| --- | --- |\n| `invoke_agent {agent.name}` | `gen_ai.operation.name=invoke_agent`, `gen_ai.provider.name`, `gen_ai.agent.name`, `gen_ai.agent.id` (when known) |\n| `create_agent {agent.name}` | `gen_ai.operation.name=create_agent`, `gen_ai.provider.name`, `gen_ai.agent.name`, `gen_ai.request.model` |\n| `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` |\n| `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` |\n\n`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`.\n\n> **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.result` are **Opt-In** by default. Gate them behind a runtime flag and avoid them in production unless you have approved data handling.\n\n### Pattern: invoke_agent + nested tool\u002Fmodel spans\n\n```typescript\nimport { ApplicationInsights, SeverityLevel } from \"@microsoft\u002Fapplicationinsights-web\";\n\ntype GenAiAttrs = Record\u003Cstring, string | number | boolean | undefined>;\n\nfunction startGenAiSpan(name: string, attrs: GenAiAttrs) {\n  const id = crypto.randomUUID();\n  const start = performance.now();\n  const baseProps: GenAiAttrs = { \"gen_ai.span.id\": id, ...attrs };\n  return {\n    end(success: boolean, extra: GenAiAttrs = {}, error?: Error) {\n      const duration = Math.round(performance.now() - start);\n      const properties = { ...baseProps, ...extra };\n      appInsights.trackDependencyData({\n        id, name, duration, success,\n        responseCode: error ? 500 : 200,\n        type: \"GenAI\",\n        target: String(attrs[\"gen_ai.provider.name\"] ?? \"genai\"),\n        properties: properties as Record\u003Cstring, string>\n      });\n      if (error) {\n        appInsights.trackException({\n          exception: error,\n          severityLevel: SeverityLevel.Error,\n          properties: { ...properties, \"error.type\": error.name } as Record\u003Cstring, string>\n        });\n      }\n    }\n  };\n}\n\n\u002F\u002F Agent invocation\nconst agentSpan = startGenAiSpan(\"invoke_agent ResearchAssistant\", {\n  \"gen_ai.operation.name\": \"invoke_agent\",\n  \"gen_ai.provider.name\": \"azure.ai.openai\",\n  \"gen_ai.agent.name\": \"ResearchAssistant\",\n  \"gen_ai.agent.id\": \"asst_5j66UpCpwteGg4YSxUnt7lPY\",\n  \"gen_ai.request.model\": \"gpt-4o-mini\",\n  \"server.address\": \"myresource.openai.azure.com\"\n});\n\ntry {\n  \u002F\u002F Nested chat completion span\n  const chat = startGenAiSpan(\"chat gpt-4o-mini\", {\n    \"gen_ai.operation.name\": \"chat\",\n    \"gen_ai.provider.name\": \"azure.ai.openai\",\n    \"gen_ai.request.model\": \"gpt-4o-mini\"\n  });\n  const res = await callAzureOpenAi(\u002F* ... *\u002F);\n  chat.end(true, {\n    \"gen_ai.response.model\": res.model,\n    \"gen_ai.response.id\": res.id,\n    \"gen_ai.response.finish_reasons\": JSON.stringify(res.choices.map(c => c.finish_reason)),\n    \"gen_ai.usage.input_tokens\": res.usage.prompt_tokens,\n    \"gen_ai.usage.output_tokens\": res.usage.completion_tokens,\n    \"gen_ai.output.type\": \"text\"\n  });\n\n  \u002F\u002F Nested tool execution span\n  const tool = startGenAiSpan(\"execute_tool getWeather\", {\n    \"gen_ai.operation.name\": \"execute_tool\",\n    \"gen_ai.tool.name\": \"getWeather\",\n    \"gen_ai.tool.type\": \"function\",\n    \"gen_ai.tool.call.id\": \"call_abc123\"\n  });\n  const toolResult = await runGetWeather({ location: \"SF\" });\n  tool.end(true);\n\n  agentSpan.end(true, {\n    \"gen_ai.usage.input_tokens\": res.usage.prompt_tokens,\n    \"gen_ai.usage.output_tokens\": res.usage.completion_tokens\n  });\n} catch (err) {\n  agentSpan.end(false, { \"error.type\": (err as Error).name }, err as Error);\n}\n```\n\nThe browser's `traceparent` is automatically attached to outbound `fetch` (when `distributedTracingMode: 2`), so downstream Azure OpenAI \u002F agent backend spans hang under the same operation_Id in App Insights.\n\nFor the full attribute reference, well-known values, and content-capture guidance, see [references\u002Fagent-traces.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fagent-traces.md).\n\n### KQL: query GenAI traces in App Insights\n\n```kusto\ndependencies\n| where type == \"GenAI\"\n| extend op   = tostring(customDimensions[\"gen_ai.operation.name\"]),\n         agent = tostring(customDimensions[\"gen_ai.agent.name\"]),\n         model = tostring(customDimensions[\"gen_ai.request.model\"]),\n         tin   = toint(customDimensions[\"gen_ai.usage.input_tokens\"]),\n         tout  = toint(customDimensions[\"gen_ai.usage.output_tokens\"])\n| summarize calls=count(), p95_ms=percentile(duration, 95),\n            avg_in=avg(tin), avg_out=avg(tout) by op, agent, model, bin(timestamp, 5m)\n```\n\n## React (TypeScript)\n\nSee [references\u002Fframework-extensions.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fframework-extensions.md) for full React, React Native, Angular, Next.js, and Vite recipes.\n\n```typescript\nimport { ApplicationInsights } from \"@microsoft\u002Fapplicationinsights-web\";\nimport { ReactPlugin, withAITracking } from \"@microsoft\u002Fapplicationinsights-react-js\";\nimport { createBrowserHistory } from \"history\";\n\nconst reactPlugin = new ReactPlugin();\nconst browserHistory = createBrowserHistory();\n\nexport const appInsights = new ApplicationInsights({\n  config: {\n    connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,\n    extensions: [reactPlugin],\n    extensionConfig: { [reactPlugin.identifier]: { history: browserHistory } }\n  }\n});\nappInsights.loadAppInsights();\n\nexport const TrackedCheckout = withAITracking(reactPlugin, Checkout, \"Checkout\");\n```\n\n## React Native\n\n```typescript\nimport { ApplicationInsights } from \"@microsoft\u002Fapplicationinsights-web\";\nimport { ReactNativePlugin } from \"@microsoft\u002Fapplicationinsights-react-native\";\n\nconst rnPlugin = new ReactNativePlugin();\nconst appInsights = new ApplicationInsights({\n  config: {\n    connectionString: process.env.EXPO_PUBLIC_APPINSIGHTS_CONNECTION_STRING,\n    extensions: [rnPlugin],\n    disableFetchTracking: false\n  }\n});\nappInsights.loadAppInsights();\n```\n\n## Performance — Web Vitals\n\nAuto-collected: page-load timings via `PerformanceTiming` \u002F `PerformanceNavigationTiming`. To add Core Web Vitals:\n\n```typescript\nimport { onCLS, onLCP, onINP, type Metric } from \"web-vitals\";\n\nfunction send(m: Metric) {\n  appInsights.trackMetric(\n    { name: `web_vitals.${m.name.toLowerCase()}`, average: m.value },\n    { rating: m.rating, navigationType: m.navigationType, id: m.id }\n  );\n}\nonCLS(send); onLCP(send); onINP(send);\n```\n\n## Cookies & Privacy\n\n```typescript\nnew ApplicationInsights({ config: {\n  connectionString,\n  isCookieUseDisabled: true,         \u002F\u002F hard-disable all cookies\n  cookieCfg: { enabled: true, domain: \".example.com\", path: \"\u002F\", expiry: 365 }\n}});\n```\n\nTo honor consent dynamically:\n\n```typescript\nappInsights.getCookieMgr().setEnabled(userGaveConsent);\nappInsights.config.disableTelemetry = !userGaveConsent;\n```\n\n## Sampling\n\nServer-side ingestion sampling (recommended) is configured on the App Insights resource. SDK-side sampling reduces network use:\n\n```typescript\nnew ApplicationInsights({ config: { connectionString, samplingPercentage: 50 } });\n```\n\nPer-type sampling via telemetry initializer: drop with `return false` based on `item.baseType`.\n\n## Offline \u002F Send-on-Unload\n\nThe SDK uses `sendBeacon` (default `onunloadDisableBeacon: false`) to flush on `pagehide` \u002F `unload`. For SPAs, also call `appInsights.flush()` before destructive transitions (logout, hard reload).\n\n## Common Pitfalls\n\n1. **Do not initialize twice.** Re-importing the module under different bundles produces duplicate page views. Use a single shared module export.\n2. **Initialize before first user input** to avoid losing early clicks\u002Fexceptions.\n3. **Connection string is public** — never reuse the same App Insights resource for backend secrets.\n4. **`enableAutoRouteTracking` + manual `trackPageView`** = duplicates. Pick one.\n5. **CORS distributed tracing** requires the API to allow `Request-Id`, `Request-Context`, `traceparent`, `tracestate` request headers and expose `Request-Context` response header.\n6. **GenAI sensitive content** (`gen_ai.input.messages` etc.) is Opt-In — never log without an explicit runtime flag and approved data handling.\n7. **Agent token usage is on `chat` spans, not `invoke_agent`** — copy aggregated usage to the parent agent span only if you know it.\n8. **React StrictMode** double-invokes effects in dev — guard `loadAppInsights()` with a module-level singleton.\n\n## Bundle Size\n\nThe 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.\n\n## Key Types\n\n```typescript\nimport {\n  ApplicationInsights,\n  SeverityLevel,\n  DistributedTracingModes,\n  type IConfiguration,\n  type IConfig,\n  type ITelemetryItem,\n  type ITelemetryPlugin,\n  type ICustomProperties,\n  type IPageViewTelemetry,\n  type IEventTelemetry,\n  type IExceptionTelemetry,\n  type ITraceTelemetry,\n  type IMetricTelemetry,\n  type IDependencyTelemetry\n} from \"@microsoft\u002Fapplicationinsights-web\";\n```\n\n## Best Practices\n\n1. **One singleton instance** exported from a single module.\n2. **Initialize early** in the app entrypoint, before router setup.\n3. **Use telemetry initializers** to attach `app.version`, `tenantId`, and to scrub PII \u002F query-string secrets.\n4. **Set `distributedTracingMode: 2`** and ensure your APIs accept\u002Fexpose W3C trace context headers.\n5. **For GenAI**, follow OTel `gen_ai.*` attribute names verbatim — they are queryable across browser and backend telemetry uniformly.\n6. **Gate sensitive content capture** (`gen_ai.input.messages` \u002F `gen_ai.output.messages`) behind a build-time or runtime opt-in.\n7. **Flush on logout \u002F sensitive navigation** so in-flight telemetry isn't dropped.\n\n## References\n\n- [references\u002Fagent-traces.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fagent-traces.md) — Full OTel GenAI semconv distilled (agent \u002F model \u002F tool spans, attributes, content capture).\n- [references\u002Fframework-extensions.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fframework-extensions.md) — React, React Native, Angular, Next.js, Vite recipes.\n- [references\u002Fconfiguration.md](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts\u002Freferences\u002Fconfiguration.md) — Full `IConfiguration` reference and tuning guide.\n- Microsoft Learn: \u003Chttps:\u002F\u002Flearn.microsoft.com\u002Fazure\u002Fazure-monitor\u002Fapp\u002Fjavascript-sdk>\n- ApplicationInsights-JS source: \u003Chttps:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FApplicationInsights-JS>\n- OTel GenAI semantic conventions: \u003Chttps:\u002F\u002Fopentelemetry.io\u002Fdocs\u002Fspecs\u002Fsemconv\u002Fgen-ai\u002F>\n\n## Limitations\n\n- Use this skill only when the task clearly matches its upstream source and local project context.\n- Verify commands, generated code, dependencies, credentials, and external service behavior before applying changes.\n- Do not treat examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.\n",{"name":5,"risk":26,"source":43,"license":14,"date_added":44,"description":7,"source_repo":45,"source_type":33,"license_source":46},"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Ftree\u002Fmain\u002F.github\u002Fplugins\u002Fazure-sdk-typescript\u002Fskills\u002Fapplicationinsights-web-ts",1782864000000,"microsoft\u002Fskills","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills\u002Fblob\u002Fmain\u002FLICENSE","f3312ba749561b6159f477dbfc9313c875d40a56",".agents\u002Fskills_archive\u002Fapplicationinsights-web-ts","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612","2026-10-25 23:50:58",{"source":8,"skillName":5,"commands":53,"prompt":63,"zipAvailable":64},[54,57,60],{"tool":55,"command":56},"npx","npx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill applicationinsights-web-ts",{"tool":58,"command":59},"bunx","bunx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill applicationinsights-web-ts",{"tool":61,"command":62},"pnpm","pnpm dlx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill applicationinsights-web-ts","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fapplicationinsights-web-ts\u002FSKILL.md",true,[],[67,96,120,142,170,193],{"skillNo":68,"name":69,"nameZh":6,"description":70,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":78,"publishedAt":38},"01M6Q0FA5FZ410Z33Z3TFQ4DBA","zero-trust","Implement zero-trust network architecture. Configure identity-based access, micro-segmentation, and continuous verification. Use when implementing modern security architectures.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzero-trust\u002FSKILL.md",[73],{"categoryNo":74,"categoryName":75,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[79,80,81,82,83,84,69,85,86,87,88,89,90,28,91,26,92,93,94,95],"ZeRO","trust","zero trust","architecture","assessment","verification","segmentation","devops-security","access","configure","only","community","active","scope","scripts","relevant","implementing",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":38},"01M6Q0F1YZJW3KX5FBKEVZ8CV4","zcode-delegate","Delegate coding tasks to the Z.AI ZCode CLI only when the user explicitly requests it, while the orchestrator retains review and landing responsibility.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzcode-delegate\u002FSKILL.md",[],[103,104,105,106,107,108,109,110,111,112,113,114,115,89,116,90,117,118,26,119],"delegate","zcode","zcode delegate","review","cli","orchestration","tasks","run","Bash","model","node","read","orchestrator","files","desktop app","app","agent-orchestration",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":38},"01M6Q0ETK41VGNMYEXW0T00AJN","youtube-transcript","Fetch YouTube transcripts through DeepAPI or local fallback tooling and save clean text output.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript\u002FSKILL.md",[],[127,128,129,130,37,131,132,20,29,133,134,135,136,90,28,137,138,139,140,141],"transcript","youtube transcript","youtube","safe","codex","research","text","fetch","tooling","clean","local","output","deepapi","youtube transcripts","blob",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":159,"publishedAt":38},"01M6Q0EPPH2PVMDW40017F8WX0","youtube-transcript-skills","Fetch YouTube video transcripts, search videos\u002Fchannels, browse channels, and extract playlists via the getyoutubetranscript.com API - free tier, no card required.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript-skills\u002FSKILL.md",[148,151,154],{"categoryNo":149,"categoryName":150,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":152,"categoryName":153,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":155,"categoryName":156,"taxonomyType":157,"taxonomyTypeDesc":158},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[127,128,129,160,130,161,37,131,20,162,163,164,165,134,166,90,28,167,168,169],"youtube transcript skills","gemini","search","api","Video","browse","api-integration","free","card","channels",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":180,"publishedAt":38},"01M6Q0EAB96PX83W5PTE8A0R8D","youtube-notetaker","Turn YouTube talks into local study notes with slides, transcripts, editable annotations, and a markdown-backed viewer.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-notetaker\u002FSKILL.md",[176,179],{"categoryNo":177,"categoryName":178,"taxonomyType":76,"taxonomyTypeDesc":77},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":152,"categoryName":153,"taxonomyType":76,"taxonomyTypeDesc":77},[129,181,182,107,130,183,33,184,185,20,164,186,187,188,189,28,190,137,191,192],"youtube notetaker","notetaker","workflow","notes","code","markdown","slides","annotations","README","study","dair-academy","viewer",{"skillNo":194,"name":195,"nameZh":6,"description":196,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":197,"categories":198,"keywords":200,"publishedAt":38},"01M6Q0E55F0GW5MX48V8HXS8B5","youtube-full","Fetch YouTube transcripts, search videos, browse channels, and extract playlists via TranscriptAPI — no yt-dlp, no Google API key, works from any cloud server.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-full\u002FSKILL.md",[199],{"categoryNo":149,"categoryName":150,"taxonomyType":76,"taxonomyTypeDesc":77},[201,129,202,203,130,161,162,204,205,163,164,165,134,206,166,90,28,167,207,140],"youtube full","full","google","server","dlp","credits","automatic"]