[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-grafana-faro-setup-web":3,"mdc-i0g169-key":36,"related-org-grafana-faro-setup-web":4053,"related-repo-grafana-faro-setup-web":4233},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":31,"sourceUrl":34,"mdContent":35},"faro-setup-web","instrument web apps with Grafana Faro","Instruments a web app with Grafana Faro Web SDK for frontend observability. Use when setting up error tracking, Web Vitals, session monitoring, or distributed tracing in a browser app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"grafana","Grafana","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fgrafana.jpg",[12,16,19,22],{"name":13,"slug":14,"type":15},"Observability","observability","tag",{"name":17,"slug":18,"type":15},"Monitoring","monitoring",{"name":20,"slug":21,"type":15},"Distributed Tracing","distributed-tracing",{"name":23,"slug":24,"type":15},"Frontend","frontend",1103,"https:\u002F\u002Fgithub.com\u002Fgrafana\u002Ffaro-web-sdk","2026-07-12T07:43:24.63314","Apache-2.0",121,[],{"repoUrl":26,"stars":25,"forks":29,"topics":32,"description":33},[],"The Grafana Faro Web SDK, part of the Grafana Faro project, is a highly configurable web SDK for real user monitoring (RUM) that instruments browser frontend applications to capture observability signals. Frontend telemetry can then be correlated with backend and infrastructure data for full-stack observability.","https:\u002F\u002Fgithub.com\u002Fgrafana\u002Ffaro-web-sdk\u002Ftree\u002FHEAD\u002Fai\u002Fgrafana-cloud\u002Ffaro-setup\u002Fskills\u002Ffaro-web","---\nname: faro-setup-web\ndescription: Instruments a web app with Grafana Faro Web SDK for frontend observability. Use when setting up error tracking, Web Vitals, session monitoring, or distributed tracing in a browser app.\nversion: 0.1.0\nauthor: Grafana Labs\nlicense: Apache-2.0\nuser-invocable: true\nallowed-tools: Read, Glob, Grep, Bash, Write, Edit\ncompatibility:\n  faro-web-sdk: '^2.0.0'\n  frameworks:\n    react: '>=16.8'\n    next: '>=13'\n    angular: '>=14'\n    vue: '>=3'\n    svelte: '>=4'\n  claude-code: '>=1.0'\n---\n\nYou are a knowledgeable collaborator helping the user instrument their web app with Grafana Faro. Work through the phases below. The goal is to feel like pairing with a developer — not filling out a form.\n\n\u003C!-- shared:communication:start -->\n\n## How to communicate\n\n- **One thing at a time.** Never ask multiple unrelated questions in one message. Ask one, wait for the answer, proceed.\n- **Show your work briefly.** Before writing code, say what you're about to do in one sentence. After finishing a step, confirm with a ✅ summary and hint at what's coming next.\n- **Lead with findings.** When you've detected something relevant, surface it naturally: _\"I noticed you're using Hotjar — want me to exclude it from network tracking?\"_ Don't wait for the user to ask.\n- **Progression.** Step 2 = get Faro running. Step 3 = apply noise reduction defaults. Step 4 = add enhancements one suggestion at a time. Step 5 = verify data flows before the PR. Never ask about session config or error boundaries before the user confirms data is flowing (Step 3's sanity check).\n- **Always offer an exit.** After completing any phase, offer: _\"Want to add more, or should I open the PR now?\"_ The user can bail at any point.\n- **Keep messages short.** One or two sentences per thought unless explaining something complex.\n\u003C!-- shared:communication:end -->\n\n\u003C!-- shared:code-rules:start -->\n\n## Code rules (apply throughout)\n\n- **Imports go at the top.** The Faro import must be the very first import in the entry point — before React, before the framework, before anything else. This ensures Faro captures errors from the moment the app loads.\n- **One file per concern.** Faro init goes in its own file. Don't inline it in the entry point.\n- **Preserve code style.** Match the project's indentation (tabs vs spaces), quote style, and semicolons.\n- **Use the project's language.** `.js` project → create `.js` files. `.tsx` → create `.tsx`. Match what exists.\n- **Don't modify code you don't understand.** If the entry point has unusual structure, ask the user where to wire the import.\n- **Never hardcode secrets.** Collector URLs are not secrets (they're client-side), but treat `.env.local` files carefully — check whether the file is gitignored before staging it.\n- **Batch file edits.** Collect ALL config options before writing `src\u002Ffaro.ts`. Write the final file once — not once per option.\n\u003C!-- shared:code-rules:end -->\n\n---\n\n\u003C!-- shared:auto-detection:start -->\n\n# Step 0: Auto-detection\n\nSilently gather project information. Do NOT ask the user anything yet.\n\nRead `package.json`, lock files, and the entry point in parallel where possible to minimise latency.\n\n## 0a. Monorepo detection\n\nBefore anything else, check for a monorepo:\n\n- `package.json` at the root has a `\"workspaces\"` field, OR\n- Multiple `package.json` files exist under `packages\u002F*\u002F` or `apps\u002F*\u002F`\n\nIf a monorepo is detected, ask the user which package\u002Fapp to instrument and use that subdirectory as the working directory for all subsequent steps.\n\n## 0b. Package manager and framework\n\nRead `package.json` and lock files to determine the package manager and framework. If there's no `package.json`, look for `.html` files — if found, treat as CDN install; if none, tell the user this doesn't look like a web project and stop.\n\n## 0c. Framework-specific detection\n\n**React projects** — check for React Router:\n\n- Look for `react-router-dom` or `react-router` in deps\n- If present, read its version from `package.json` (or `node_modules\u002Freact-router-dom\u002Fpackage.json`) to determine v4\u002Fv5\u002Fv6\u002Fv7\n- Search source files for `createBrowserRouter` — if found, it's a data router\n\n**Next.js projects** — determine router type:\n\n- `app\u002F` directory at project root or under `src\u002F` → App Router\n- `pages\u002F` directory → Pages Router\n- Both → App Router (it takes precedence)\n\n## 0d. Architecture pattern detection\n\nDetect special architectural patterns that require specific Faro wiring.\n\n**Microfrontend detection** — check for:\n\n- `package.json` deps: `single-spa`, `@single-spa\u002Frecommended-layout`, `@single-spa\u002Fparcel`, `@module-federation\u002Fruntime`, `@module-federation\u002Fenhanced`, `qiankun`, `garfish`, `wujie`\n- Webpack config files (`webpack.config.js`, `webpack.config.ts`): grep for `ModuleFederationPlugin`\n\nIf found, record: **microfrontend framework detected** (and which one).\n\n**iFrame \u002F embedded app detection** — scan `src\u002F` source files (`.js,.ts,.jsx,.tsx,.vue,.svelte`) for:\n\n- `window\\.parent` — this app may run inside or communicate with a parent frame\n- `window\\.top` — checking iframe context at runtime\n- `\\.postMessage\\(` — cross-frame messaging\n\nIf found, record: **cross-frame communication patterns detected**.\n\nDo not surface these yet — add them to the Step 0h summary.\n\n## 0e. Check for existing Faro\n\nCheck if `@grafana\u002Ffaro-web-sdk` or `@grafana\u002Ffaro-react` is already in `package.json` dependencies. If found, present three options before continuing:\n\n> Faro is already installed. What would you like to do?\n>\n> 1. **Add more options** — set up route tracking, user identity, cookie consent, or other advanced features\n> 2. **Reconfigure** — re-run the full setup from scratch\n> 3. **Stop** — nothing to do here\n\nIf **1 (Add more)**: skip Steps 0c, 0d, 0f, 0g, 0h and Steps 1–3. Instead, silently locate the existing Faro init file (search for files containing `initializeFaro` in `src\u002F`) and use the framework already detected in Step 0b as context. Then jump directly to Step 4's setup menu.\n\nIf **2 (Reconfigure)**: continue with the rest of Step 0 as normal.\n\nIf **3 (Stop)**: exit.\n\n## 0f. Find entry points\n\nLocate the main entry file:\n\n- **React**: `src\u002Fmain.tsx`, `src\u002Fmain.ts`, `src\u002Findex.tsx`, `src\u002Findex.ts`, `src\u002Fmain.jsx`, `src\u002Findex.jsx`\n- **Next.js App Router**: `app\u002Flayout.tsx`, `app\u002Flayout.jsx`, `src\u002Fapp\u002Flayout.tsx`, `src\u002Fapp\u002Flayout.jsx`\n- **Next.js Pages Router**: `pages\u002F_app.tsx`, `pages\u002F_app.jsx`, `src\u002Fpages\u002F_app.tsx`, `src\u002Fpages\u002F_app.jsx`\n- **Angular**: `src\u002Fapp\u002Fapp.module.ts`, `src\u002Fmain.ts`\n- **Vue**: `src\u002Fmain.ts`, `src\u002Fmain.js`\n- **Svelte**: `src\u002Fmain.ts`, `src\u002Fmain.js`\n- **Vanilla JS**: `src\u002Fmain.ts`, `src\u002Fmain.js`, `src\u002Findex.ts`, `src\u002Findex.js`, `index.js`, `app.js` or similar\n- **Plain HTML**: `index.html`, `*.html` in root\n\nRead the entry point file so you understand its current structure.\n\n## 0g. Scan for 3rd party noise\n\nSilently scan the project for analytics, tracking, and session recording scripts that would generate noise in Faro's network instrumentation. Do NOT ask the user anything yet — collect candidates only.\n\n**Scan locations:**\n\n1. HTML files — look for `\u003Cscript src=\"...\">` attributes pointing to external domains.\n2. `package.json` — look for known packages in dependencies\u002FdevDependencies.\n3. Source files — grep for known 3rd party domain strings in `.js,.ts,.jsx,.tsx,.vue,.svelte` files under `src\u002F` only, up to 3 levels deep. Do NOT scan `node_modules\u002F`, `dist\u002F`, or `build\u002F`.\n\n**Known 3rd party signals:**\n\n| Package \u002F Domain                                                                                            | Service                |\n| ----------------------------------------------------------------------------------------------------------- | ---------------------- |\n| `@segment\u002Fanalytics-next`, `analytics.js`, `cdn.segment.com`, `api.segment.io`                              | Segment                |\n| `posthog-js`, `app.posthog.com`, `eu.posthog.com`                                                           | PostHog                |\n| `mixpanel-browser`, `api.mixpanel.com`, `cdn.mxpnl.com`                                                     | Mixpanel               |\n| `amplitude-js`, `@amplitude\u002Fanalytics-browser`, `api2.amplitude.com`, `cdn.amplitude.com`                   | Amplitude              |\n| `@hotjar\u002Fbrowser`, `static.hotjar.com`, `script.hotjar.com`                                                 | Hotjar                 |\n| `@fullstory\u002Fbrowser`, `fullstory.com`, `rs.fullstory.com`                                                   | FullStory              |\n| `@intercom\u002Fmessenger-js-sdk`, `widget.intercom.io`, `api-iam.intercom.io`                                   | Intercom               |\n| `@datadog\u002Fbrowser-rum`, `browser-intake-datadoghq.com`                                                      | Datadog RUM            |\n| `react-ga`, `react-ga4`, `vue-gtag`, `google-analytics.com`, `googletagmanager.com`, `analytics.google.com` | Google Analytics \u002F GTM |\n| `drift`, `js.driftt.com`, `api.drift.com`                                                                   | Drift                  |\n| `crisp-sdk-web`, `client.crisp.chat`                                                                        | Crisp                  |\n| `logrocket`, `cdn.logrocket.io`, `r.lr-ingest.io`                                                           | LogRocket              |\n| `connect.facebook.net`, `facebook.com\u002Ftr`                                                                   | Facebook Pixel         |\n\nFor each match, record: the service name, the matched signal (package or domain), and where it was found (file path).\n\nAlso collect universally noisy browser errors to suggest for `ignoreErrors`:\n\n- `ResizeObserver loop limit exceeded` — a harmless browser quirk, not a real error\n- `ResizeObserver loop completed with undelivered notifications` — same\n- Chrome\u002FFirefox extension interference: errors from `chrome-extension:\u002F\u002F` or `moz-extension:\u002F\u002F` URLs\n- Script errors from cross-origin scripts with no stack: `Script error.` with empty stack\n\n## 0h. Present summary and confirm\n\nShow a one-line summary of what was detected and ask the user to confirm:\n\n> Detected: [Framework] [version if relevant] + [Router if applicable], [Package manager], [Faro status: \"no Faro yet\" or \"Faro already installed\"]. Entry point: `[path]`.\n\nIf 3rd party libraries were found in 0g, mention them in the summary (but do NOT configure them yet — that happens after the base setup):\n\n> Also found: Hotjar (`static.hotjar.com`) in `public\u002Findex.html`, Segment (`@segment\u002Fanalytics-next`) in `package.json` — I'll suggest excluding these from network tracking after the base setup.\n\nIf architecture patterns were found in 0d, note them prominently — users need to know their setup is recognized:\n\n> ⚠️ **Microfrontend framework detected** (`single-spa`). Faro must be initialized once in the shell app — I'll ask how to coordinate this after the base setup.\n\n> ⚠️ **Cross-frame communication patterns detected** (`window.parent`, `postMessage`). Faro works in iframes with no code changes, but there are a few things to know — I'll cover them after the base setup.\n\nIf the project has a React\u002FVue\u002FSvelte\u002FNext.js SPA with a router, call it out:\n\n> This is a **Single Page Application**. Route tracking is strongly recommended — without it, all errors, logs, and performance data appear under a single \"\u002F\" view in Grafana, making it hard to isolate page-specific issues. I'll offer this in the advanced setup.\n\nIf the project is a React\u002FVue\u002FSvelte\u002FNext.js SPA but **no router was detected** (or the detected router has no supported Faro integration), call it out:\n\n> No router found — I'll enable auto-navigation tracking as part of the base setup so you still get URL change and timing data.\n\nIf anything looks wrong, let the user correct it before proceeding.\n\n\u003C!-- shared:auto-detection:end -->\n\n---\n\n# Step 1: Collector URL\n\nAsk the user:\n\n> Do you have the snippet from the Grafana Cloud wizard, or just the collector URL? Paste either one.\n>\n> If you haven't created a Frontend Observability app yet, go to **Grafana Cloud → Observability → Frontend → Create new**, copy the snippet, and come back.\n\nHandle the response:\n\n- **Full `initializeFaro({...})` snippet pasted**: extract the `url` value and `app.name` value. Skip to Step 1b confirmation.\n- **URL pasted** (starts with `https:\u002F\u002F`): use it as the collector URL. Proceed to Q2.\n- **Neither**: wait. Tell them you need a collector URL to proceed.\n\n**Q2 — App name** (only if not extracted from a snippet):\n\nRead `name` from `package.json` if available, and offer it as default:\n\n> What should the app be called in Faro? Detected: `[package.json name]`. Reply **y** to confirm or type a new name.\n\n**Step 1b — Confirm before generating code:**\n\n> Ready to instrument with:\n>\n> - Collector: `[URL]`\n> - App name: `[name]`\n> - Framework: `[detected framework]`\n> - Entry point: `[path]`\n>\n> Proceed?\n\n---\n\n# Step 2: Base implementation\n\nRead `frameworks.md` now. Use the section matching the detected framework for install commands, init file content, and entry point wiring. Replace `\u003CCOLLECTOR_URL>` and `\u003CAPP_NAME>` with the values from Step 1.\n\nRun the package install command from the matching `frameworks.md` section (skip for CDN projects).\n\nIf **no router was detected** or the detected router has no supported Faro integration, add `experimental: { trackNavigation: true }` to the `initializeFaro` call in the init file. Do NOT ask — apply it silently as part of the base config. This captures URL changes and navigation timing without a router.\n\n---\n\n\u003C!-- shared:noise-reduction:start -->\n\n# Step 3: Noise reduction defaults\n\n1. Silently add `ignoreErrors` for universal browser noise. Skip for CDN projects. Do NOT ask — these are always correct:\n\n   ```ts\n   ignoreErrors: [\n     \u002F\u002F Layout quirks — harmless, not real errors\n     \u002F^ResizeObserver loop limit exceeded$\u002F,\n     \u002F^ResizeObserver loop completed with undelivered notifications$\u002F,\n     \u002F\u002F Cross-origin scripts with no useful stack\n     \u002F^Script error\\.$\u002F,\n     \u002F\u002F Browser extension interference\n     \u002Fchrome-extension:\\\u002F\\\u002F\u002F,\n     \u002Fmoz-extension:\\\u002F\\\u002F\u002F,\n   ],\n   ```\n\n2. If 3rd party services were detected in Step 0g, silently add `ignoreUrls` to the faro init file for all detected services. Do NOT ask — apply all of them. Use this table to determine the domains:\n\n   | Service                | Regex patterns to add                                                                 |\n   | ---------------------- | ------------------------------------------------------------------------------------- |\n   | Segment                | `\u002Fcdn\\.segment\\.com\u002F`, `\u002Fapi\\.segment\\.io\u002F`                                           |\n   | PostHog                | `\u002Fapp\\.posthog\\.com\u002F`, `\u002Feu\\.posthog\\.com\u002F`                                           |\n   | Mixpanel               | `\u002Fapi\\.mixpanel\\.com\u002F`, `\u002Fcdn\\.mxpnl\\.com\u002F`                                           |\n   | Amplitude              | `\u002Fapi2\\.amplitude\\.com\u002F`, `\u002Fcdn\\.amplitude\\.com\u002F`                                     |\n   | Hotjar                 | `\u002Fstatic\\.hotjar\\.com\u002F`, `\u002Fscript\\.hotjar\\.com\u002F`                                      |\n   | FullStory              | `\u002Ffullstory\\.com\u002F`, `\u002Frs\\.fullstory\\.com\u002F`                                            |\n   | Intercom               | `\u002Fwidget\\.intercom\\.io\u002F`, `\u002Fapi-iam\\.intercom\\.io\u002F`                                   |\n   | Datadog RUM            | `\u002Fbrowser-intake-datadoghq\\.com\u002F`                                                     |\n   | Google Analytics \u002F GTM | `\u002Fgoogletagmanager\\.com\u002F`, `\u002Fanalytics\\.google\\.com\u002F`, `\u002Fwww\\.google-analytics\\.com\u002F` |\n   | Drift                  | `\u002Fjs\\.driftt\\.com\u002F`, `\u002Fapi\\.drift\\.com\u002F`                                              |\n   | Crisp                  | `\u002Fclient\\.crisp\\.chat\u002F`                                                               |\n   | LogRocket              | `\u002Fcdn\\.logrocket\\.io\u002F`, `\u002Fr\\.lr-ingest\\.io\u002F`                                          |\n   | Facebook Pixel         | `\u002Fconnect\\.facebook\\.net\u002F`, `\u002Ffacebook\\.com\\\u002Ftr\u002F`                                     |\n   | Microsoft Clarity      | `\u002Fclarity\\.ms\u002F`                                                                       |\n   | Pendo                  | `\u002Fcdn\\.pendo\\.io\u002F`, `\u002Fapp\\.pendo\\.io\u002F`                                                |\n   | Heap                   | `\u002Fcdn\\.heapanalytics\\.com\u002F`, `\u002Fheapanalytics\\.com\u002F`                                   |\n   | Rudderstack            | `\u002Fcdn\\.rudderlabs\\.com\u002F`, `\u002Fapi\\.rudderstack\\.com\u002F`                                   |\n   | Plausible              | `\u002Fplausible\\.io\u002F`                                                                     |\n   | Fathom                 | `\u002Fcdn\\.usefathom\\.com\u002F`                                                               |\n\n3. Confirm what was done with a short ✅ summary:\n   > ✅ Done! Here's what was set up:\n   >\n   > - Installed: `[packages]`\n   > - Created: `[faro init file path]`\n   > - Wired: first import in `[entry point]`\n   > - Filtered harmless browser errors (ResizeObserver, Script error, extension noise)\n   >   [if services detected:] - Excluded from network tracking: [service names] — auto-detected in your project\n   >   [if no router detected:] - Auto-navigation tracking enabled (`experimental.trackNavigation`) — no router found\n   \u003C!-- shared:noise-reduction:end -->\n4. Ask the user to do a quick sanity check **before** adding anything else (this is an early check — a final pre-PR verification happens in Step 5):\n   > **One quick check** — start your app and open DevTools → Network. Filter by `collect`. You should see POST requests to your collector within a few seconds.\n   >\n   > Seeing them? **y** to continue, **n** if not and I'll help debug.\n5. If **n**: run through the debug checklist in Step 5. Do not move forward until data is confirmed flowing.\n6. If **y**: present the fork:\n   > Faro is running. Want to go through a quick optional setup, or open the PR now?\n   >\n   > - **y** — I'll suggest a few things based on your project\n   > - **n \u002F PR** — skip straight to the PR\n\n---\n\n\u003C!-- shared:smart-suggestions:start -->\n\n# Step 4: Optional setup\n\nIf the user said **n \u002F PR** at the fork in Step 3: go directly to Step 5.\n\nIf the user said **y**:\n\n## 4-1. Present the setup menu\n\nShow a **single message** with all options:\n\n> Here's what else I can set up — pick any numbers, or say **PR** to skip all:\n>\n> 1. **Route tracking** — [if router detected: route patterns + view grouping] [if no router: one-flag auto-navigation]\n> 2. **User identity** — tag errors and sessions with who's logged in\n> 3. **More** — error boundary, cookie consent, cross-origin tracing, session settings, disable console capture, disable tracing\n\n## 4-2. Handle picks\n\nHandle one picked item at a time. After each, ask:\n\n> ✅ Done. Anything else from the list, or should I open the PR?\n\n**1 — Route tracking** → Read `advanced.md` section B.\n\n- Router detected: offer router integration (gives route patterns like `\u002Fusers\u002F:id`).\n- No router: enable auto-navigation with one flag:\n  ```ts\n  initializeFaro({\n    \u002F\u002F ... existing config ...\n    experimental: { trackNavigation: true },\n  });\n  ```\n  Note to user: captures actual URLs, not route patterns. Upgrade to router integration (advanced.md section B) when a router is added.\n\n**2 — User identity** → Read `advanced.md` section K.\n\n**3 — More** → show the expanded advanced menu:\n\n> Which of these? (pick numbers, or say PR)\n>\n> 1. Error boundary — catch component crashes (React only) (→ advanced.md section C)\n> 2. Cookie consent gate — delay tracking until consent accepted (→ advanced.md section G)\n> 3. Cross-origin tracing — trace headers for API calls on other domains (→ advanced.md section A)\n> 4. Session settings — persistence, inactivity timeout (→ advanced.md section F)\n> 5. Disable console log capture (→ advanced.md section L)\n> 6. Disable distributed tracing (→ advanced.md section M)\n> 7. Exclude additional errors — suppress app-specific error patterns (→ advanced.md section D)\n> 8. Exclude additional URLs — suppress more network domains (→ advanced.md section E)\n>    [if detected:] ⭐ Microfrontend coordination — found [framework] (→ advanced.md section J)\n>    [if detected:] ⭐ iFrame guidance — found cross-frame patterns (→ advanced.md section I)\n\nWhen the user picks an option from the More menu, read `advanced.md` and apply the matching section.\n\n**Session sampling rate:** Do NOT surface proactively. Only raise it if the user mentions high traffic or picks \"Session settings\". 100% is correct for most apps.\n\n\u003C!-- shared:smart-suggestions:end -->\n\n---\n\n# Step 5: Verify before PR\n\nBefore creating the PR, do a final end-to-end verification (separate from the early sanity check in Step 3). This confirms the full setup — including any router, user identity, or noise config added in Step 4 — is working correctly:\n\n> All changes are ready. Before I open the PR, run the app locally and verify Faro is sending data:\n>\n> 1. `[start command]` — run your app as usual\n> 2. Open **DevTools → Network tab**\n> 3. Filter by `collect` — you should see POST requests to `[COLLECTOR_URL]`\n> 4. Trigger a page navigation, click, or console.log — the request payload should update\n>\n> Seeing requests? Type **yes** to proceed with the PR. Not seeing them? Type **no** and I'll help debug.\n\nIf the user says **no**, run through the most common issues:\n\n- Is the Faro import the **first** import in the entry point? (Re-check the entry point file.)\n- Is the collector URL correct? (Log `faro.config?.url` in the browser console.)\n- Any Content Security Policy errors in the DevTools console blocking the request?\n- For Next.js: is `NEXT_PUBLIC_FARO_URL` set in `.env.local` and the dev server restarted?\n\nDo not proceed to Step 6 until the user confirms data is flowing.\n\n---\n\n# Step 6: Create a PR\n\nAfter all code changes are done, ask:\n\n> All changes are committed and ready. Should I open the PR for you, or would you prefer to do it yourself?\n>\n> - **y \u002F open it** — I'll create the branch, commit, push, and open the PR via `gh`\n> - **n \u002F I'll do it** — I'll show you the commands to run\n\nIf the user chooses **n \u002F I'll do it**, show the commands below and stop.\n\nIf the user chooses **y \u002F open it**, run the steps below.\n\n---\n\n1. Create a new branch:\n\n   ```\n   git checkout -b feat\u002Fadd-faro-instrumentation\n   ```\n\n2. Stage all modified and new files. Be specific — don't use `git add .` or `git add -A`. Stage only:\n   - The Faro init file (`src\u002Ffaro.ts`, `components\u002FFrontendObservability.tsx`, etc.)\n   - The modified entry point\n   - Any additional files created (error handler, etc.)\n   - `package.json` and the lock file (if packages were installed)\n   - `.env.local` or `.env.example` (if created\u002Fmodified, and ONLY if they don't contain secrets)\n\n3. Commit:\n\n   ```\n   git commit -m \"feat: add Grafana Faro Web SDK instrumentation\"\n   ```\n\n4. Push and create PR:\n\n   ```\n   git push -u origin feat\u002Fadd-faro-instrumentation\n   gh pr create --title \"feat: add Grafana Faro Web SDK instrumentation\" --body \"$(cat \u003C\u003C'EOF'\n   ## Summary\n   - Added [Grafana Faro Web SDK](https:\u002F\u002Fgithub.com\u002Fgrafana\u002Ffaro-web-sdk) for frontend observability\n   - Framework: [FRAMEWORK]\n   - Packages: [LIST PACKAGES INSTALLED]\n   - Init file: `[PATH TO FARO INIT FILE]`\n   - Entry point modified: `[PATH TO ENTRY POINT]`\n   [- Tracing: enabled (if applicable)]\n   [- Router instrumentation: enabled (if applicable)]\n   [- Error boundary: enabled (if applicable)]\n\n   ## How to verify\n   1. Run the app locally\n   2. Open browser DevTools → Network tab\n   3. Look for POST requests to the Faro collector URL\n   4. Check the Grafana Cloud Frontend Observability dashboard for incoming data\n\n   ## Links\n   - [Grafana Faro Web SDK docs](https:\u002F\u002Fgrafana.com\u002Fdocs\u002Fgrafana-cloud\u002Fmonitor-applications\u002Ffrontend-observability\u002F)\n   - [Faro Web SDK GitHub](https:\u002F\u002Fgithub.com\u002Fgrafana\u002Ffaro-web-sdk)\n   EOF\n   )\"\n   ```\n\nIf `gh` is not available or the push fails, show the user the commands to run manually.\n\n---\n\n# Step 7: Observability roadmap\n\nAfter the PR is open, show a summary of what's active and what can be added next.\n\nGenerate the checklist dynamically based on what was configured:\n\n> **Your Faro setup is ready. Here's what's enabled:**\n>\n> ✅ JavaScript error capture (automatic — errors, unhandled rejections, thrown exceptions)\n> ✅ Core Web Vitals — LCP, FID\u002FINP, CLS (automatic via `getWebInstrumentations()`)\n> ✅ Network request tracking — fetch and XHR timing and status codes\n> [✅ Console log capture — OR — ❌ Console log capture disabled (captureConsole: false)]\n> [✅ Distributed tracing — same-origin automatic; cross-origin if configured in advanced.md section A]\n> [✅ Session tracking: persistent — OR — ✅ Session tracking: default (per-tab)]\n> [✅ [N]% session sampling — OR — ✅ Session sampling: 100% (all sessions)]\n> [✅ User identity — set on load OR set dynamically after login — OR — ☐ User identity: not configured]\n> [✅ Navigation \u002F route tracking — OR — ☐ Navigation tracking: not configured]\n> [✅ React Error Boundary — OR — (omit for non-React)]\n> [✅ Cookie consent gate (paused mode) — OR — (omit if not configured)]\n> [✅ Microfrontend: host initializes Faro \u002F child uses faro.api — OR — (omit if not applicable)]\n>\n> **What you can add later:**\n>\n> ☐ **Custom events** — instrument meaningful user actions:\n> `faro.api?.pushEvent('feature_used', { feature: 'dark_mode' })`\n>\n> ☐ **Custom measurements** — track business metrics:\n> `faro.api?.pushMeasurement({ type: 'cart_value', values: { total: 99.99 } })`\n>\n> ☐ **Source map upload** — resolve minified stack traces to real source lines in production.\n> See: [Faro source maps docs](https:\u002F\u002Fgrafana.com\u002Fdocs\u002Fgrafana-cloud\u002Fmonitor-applications\u002Ffrontend-observability\u002Ffaro-web-sdk\u002Fupload-source-maps\u002F)\n>\n> ☐ **Alerting** — create alerts on error rate spikes or Web Vitals degradation from the Grafana Cloud Frontend Observability panel.\n>\n> ☐ **Backend correlation** — link frontend traces to backend spans. Already enabled for same-origin requests. Add `propagateTraceHeaderCorsUrls` for external APIs (advanced.md section A).\n",{"data":37,"body":51},{"name":4,"description":6,"version":38,"author":39,"license":28,"user-invocable":40,"allowed-tools":41,"compatibility":42},"0.1.0","Grafana Labs",true,"Read, Glob, Grep, Bash, Write, Edit",{"faro-web-sdk":43,"frameworks":44,"claude-code":50},"^2.0.0",{"react":45,"next":46,"angular":47,"vue":48,"svelte":49},">=16.8",">=13",">=14",">=3",">=4",">=1.0",{"type":52,"children":53},"root",[54,62,69,150,156,276,280,287,292,305,311,316,363,368,374,400,406,416,472,482,520,526,531,541,636,648,673,709,720,725,731,758,801,828,839,850,856,861,1122,1127,1133,1138,1146,1213,1221,1666,1671,1684,1742,1748,1753,1801,1806,1842,1847,1869,1897,1902,1917,1929,1937,1942,1945,1951,1956,1976,1981,2046,2056,2075,2098,2106,2165,2168,2174,2202,2214,2239,2242,2248,3117,3120,3126,3137,3146,3152,3164,3223,3229,3234,3242,3260,3372,3388,3398,3469,3481,3491,3494,3500,3505,3579,3590,3643,3648,3651,3657,3662,3699,3710,3720,3723,3848,3859,3862,3868,3873,3878,4047],{"type":55,"tag":56,"props":57,"children":58},"element","p",{},[59],{"type":60,"value":61},"text","You are a knowledgeable collaborator helping the user instrument their web app with Grafana Faro. Work through the phases below. The goal is to feel like pairing with a developer — not filling out a form.",{"type":55,"tag":63,"props":64,"children":66},"h2",{"id":65},"how-to-communicate",[67],{"type":60,"value":68},"How to communicate",{"type":55,"tag":70,"props":71,"children":72},"ul",{},[73,85,95,113,123,140],{"type":55,"tag":74,"props":75,"children":76},"li",{},[77,83],{"type":55,"tag":78,"props":79,"children":80},"strong",{},[81],{"type":60,"value":82},"One thing at a time.",{"type":60,"value":84}," Never ask multiple unrelated questions in one message. Ask one, wait for the answer, proceed.",{"type":55,"tag":74,"props":86,"children":87},{},[88,93],{"type":55,"tag":78,"props":89,"children":90},{},[91],{"type":60,"value":92},"Show your work briefly.",{"type":60,"value":94}," Before writing code, say what you're about to do in one sentence. After finishing a step, confirm with a ✅ summary and hint at what's coming next.",{"type":55,"tag":74,"props":96,"children":97},{},[98,103,105,111],{"type":55,"tag":78,"props":99,"children":100},{},[101],{"type":60,"value":102},"Lead with findings.",{"type":60,"value":104}," When you've detected something relevant, surface it naturally: ",{"type":55,"tag":106,"props":107,"children":108},"em",{},[109],{"type":60,"value":110},"\"I noticed you're using Hotjar — want me to exclude it from network tracking?\"",{"type":60,"value":112}," Don't wait for the user to ask.",{"type":55,"tag":74,"props":114,"children":115},{},[116,121],{"type":55,"tag":78,"props":117,"children":118},{},[119],{"type":60,"value":120},"Progression.",{"type":60,"value":122}," Step 2 = get Faro running. Step 3 = apply noise reduction defaults. Step 4 = add enhancements one suggestion at a time. Step 5 = verify data flows before the PR. Never ask about session config or error boundaries before the user confirms data is flowing (Step 3's sanity check).",{"type":55,"tag":74,"props":124,"children":125},{},[126,131,133,138],{"type":55,"tag":78,"props":127,"children":128},{},[129],{"type":60,"value":130},"Always offer an exit.",{"type":60,"value":132}," After completing any phase, offer: ",{"type":55,"tag":106,"props":134,"children":135},{},[136],{"type":60,"value":137},"\"Want to add more, or should I open the PR now?\"",{"type":60,"value":139}," The user can bail at any point.",{"type":55,"tag":74,"props":141,"children":142},{},[143,148],{"type":55,"tag":78,"props":144,"children":145},{},[146],{"type":60,"value":147},"Keep messages short.",{"type":60,"value":149}," One or two sentences per thought unless explaining something complex.",{"type":55,"tag":63,"props":151,"children":153},{"id":152},"code-rules-apply-throughout",[154],{"type":60,"value":155},"Code rules (apply throughout)",{"type":55,"tag":70,"props":157,"children":158},{},[159,169,179,189,230,240,258],{"type":55,"tag":74,"props":160,"children":161},{},[162,167],{"type":55,"tag":78,"props":163,"children":164},{},[165],{"type":60,"value":166},"Imports go at the top.",{"type":60,"value":168}," The Faro import must be the very first import in the entry point — before React, before the framework, before anything else. This ensures Faro captures errors from the moment the app loads.",{"type":55,"tag":74,"props":170,"children":171},{},[172,177],{"type":55,"tag":78,"props":173,"children":174},{},[175],{"type":60,"value":176},"One file per concern.",{"type":60,"value":178}," Faro init goes in its own file. Don't inline it in the entry point.",{"type":55,"tag":74,"props":180,"children":181},{},[182,187],{"type":55,"tag":78,"props":183,"children":184},{},[185],{"type":60,"value":186},"Preserve code style.",{"type":60,"value":188}," Match the project's indentation (tabs vs spaces), quote style, and semicolons.",{"type":55,"tag":74,"props":190,"children":191},{},[192,197,199,206,208,213,215,221,223,228],{"type":55,"tag":78,"props":193,"children":194},{},[195],{"type":60,"value":196},"Use the project's language.",{"type":60,"value":198}," ",{"type":55,"tag":200,"props":201,"children":203},"code",{"className":202},[],[204],{"type":60,"value":205},".js",{"type":60,"value":207}," project → create ",{"type":55,"tag":200,"props":209,"children":211},{"className":210},[],[212],{"type":60,"value":205},{"type":60,"value":214}," files. ",{"type":55,"tag":200,"props":216,"children":218},{"className":217},[],[219],{"type":60,"value":220},".tsx",{"type":60,"value":222}," → create ",{"type":55,"tag":200,"props":224,"children":226},{"className":225},[],[227],{"type":60,"value":220},{"type":60,"value":229},". Match what exists.",{"type":55,"tag":74,"props":231,"children":232},{},[233,238],{"type":55,"tag":78,"props":234,"children":235},{},[236],{"type":60,"value":237},"Don't modify code you don't understand.",{"type":60,"value":239}," If the entry point has unusual structure, ask the user where to wire the import.",{"type":55,"tag":74,"props":241,"children":242},{},[243,248,250,256],{"type":55,"tag":78,"props":244,"children":245},{},[246],{"type":60,"value":247},"Never hardcode secrets.",{"type":60,"value":249}," Collector URLs are not secrets (they're client-side), but treat ",{"type":55,"tag":200,"props":251,"children":253},{"className":252},[],[254],{"type":60,"value":255},".env.local",{"type":60,"value":257}," files carefully — check whether the file is gitignored before staging it.",{"type":55,"tag":74,"props":259,"children":260},{},[261,266,268,274],{"type":55,"tag":78,"props":262,"children":263},{},[264],{"type":60,"value":265},"Batch file edits.",{"type":60,"value":267}," Collect ALL config options before writing ",{"type":55,"tag":200,"props":269,"children":271},{"className":270},[],[272],{"type":60,"value":273},"src\u002Ffaro.ts",{"type":60,"value":275},". Write the final file once — not once per option.",{"type":55,"tag":277,"props":278,"children":279},"hr",{},[],{"type":55,"tag":281,"props":282,"children":284},"h1",{"id":283},"step-0-auto-detection",[285],{"type":60,"value":286},"Step 0: Auto-detection",{"type":55,"tag":56,"props":288,"children":289},{},[290],{"type":60,"value":291},"Silently gather project information. Do NOT ask the user anything yet.",{"type":55,"tag":56,"props":293,"children":294},{},[295,297,303],{"type":60,"value":296},"Read ",{"type":55,"tag":200,"props":298,"children":300},{"className":299},[],[301],{"type":60,"value":302},"package.json",{"type":60,"value":304},", lock files, and the entry point in parallel where possible to minimise latency.",{"type":55,"tag":63,"props":306,"children":308},{"id":307},"_0a-monorepo-detection",[309],{"type":60,"value":310},"0a. Monorepo detection",{"type":55,"tag":56,"props":312,"children":313},{},[314],{"type":60,"value":315},"Before anything else, check for a monorepo:",{"type":55,"tag":70,"props":317,"children":318},{},[319,337],{"type":55,"tag":74,"props":320,"children":321},{},[322,327,329,335],{"type":55,"tag":200,"props":323,"children":325},{"className":324},[],[326],{"type":60,"value":302},{"type":60,"value":328}," at the root has a ",{"type":55,"tag":200,"props":330,"children":332},{"className":331},[],[333],{"type":60,"value":334},"\"workspaces\"",{"type":60,"value":336}," field, OR",{"type":55,"tag":74,"props":338,"children":339},{},[340,342,347,349,355,357],{"type":60,"value":341},"Multiple ",{"type":55,"tag":200,"props":343,"children":345},{"className":344},[],[346],{"type":60,"value":302},{"type":60,"value":348}," files exist under ",{"type":55,"tag":200,"props":350,"children":352},{"className":351},[],[353],{"type":60,"value":354},"packages\u002F*\u002F",{"type":60,"value":356}," or ",{"type":55,"tag":200,"props":358,"children":360},{"className":359},[],[361],{"type":60,"value":362},"apps\u002F*\u002F",{"type":55,"tag":56,"props":364,"children":365},{},[366],{"type":60,"value":367},"If a monorepo is detected, ask the user which package\u002Fapp to instrument and use that subdirectory as the working directory for all subsequent steps.",{"type":55,"tag":63,"props":369,"children":371},{"id":370},"_0b-package-manager-and-framework",[372],{"type":60,"value":373},"0b. Package manager and framework",{"type":55,"tag":56,"props":375,"children":376},{},[377,378,383,385,390,392,398],{"type":60,"value":296},{"type":55,"tag":200,"props":379,"children":381},{"className":380},[],[382],{"type":60,"value":302},{"type":60,"value":384}," and lock files to determine the package manager and framework. If there's no ",{"type":55,"tag":200,"props":386,"children":388},{"className":387},[],[389],{"type":60,"value":302},{"type":60,"value":391},", look for ",{"type":55,"tag":200,"props":393,"children":395},{"className":394},[],[396],{"type":60,"value":397},".html",{"type":60,"value":399}," files — if found, treat as CDN install; if none, tell the user this doesn't look like a web project and stop.",{"type":55,"tag":63,"props":401,"children":403},{"id":402},"_0c-framework-specific-detection",[404],{"type":60,"value":405},"0c. Framework-specific detection",{"type":55,"tag":56,"props":407,"children":408},{},[409,414],{"type":55,"tag":78,"props":410,"children":411},{},[412],{"type":60,"value":413},"React projects",{"type":60,"value":415}," — check for React Router:",{"type":55,"tag":70,"props":417,"children":418},{},[419,439,459],{"type":55,"tag":74,"props":420,"children":421},{},[422,424,430,431,437],{"type":60,"value":423},"Look for ",{"type":55,"tag":200,"props":425,"children":427},{"className":426},[],[428],{"type":60,"value":429},"react-router-dom",{"type":60,"value":356},{"type":55,"tag":200,"props":432,"children":434},{"className":433},[],[435],{"type":60,"value":436},"react-router",{"type":60,"value":438}," in deps",{"type":55,"tag":74,"props":440,"children":441},{},[442,444,449,451,457],{"type":60,"value":443},"If present, read its version from ",{"type":55,"tag":200,"props":445,"children":447},{"className":446},[],[448],{"type":60,"value":302},{"type":60,"value":450}," (or ",{"type":55,"tag":200,"props":452,"children":454},{"className":453},[],[455],{"type":60,"value":456},"node_modules\u002Freact-router-dom\u002Fpackage.json",{"type":60,"value":458},") to determine v4\u002Fv5\u002Fv6\u002Fv7",{"type":55,"tag":74,"props":460,"children":461},{},[462,464,470],{"type":60,"value":463},"Search source files for ",{"type":55,"tag":200,"props":465,"children":467},{"className":466},[],[468],{"type":60,"value":469},"createBrowserRouter",{"type":60,"value":471}," — if found, it's a data router",{"type":55,"tag":56,"props":473,"children":474},{},[475,480],{"type":55,"tag":78,"props":476,"children":477},{},[478],{"type":60,"value":479},"Next.js projects",{"type":60,"value":481}," — determine router type:",{"type":55,"tag":70,"props":483,"children":484},{},[485,504,515],{"type":55,"tag":74,"props":486,"children":487},{},[488,494,496,502],{"type":55,"tag":200,"props":489,"children":491},{"className":490},[],[492],{"type":60,"value":493},"app\u002F",{"type":60,"value":495}," directory at project root or under ",{"type":55,"tag":200,"props":497,"children":499},{"className":498},[],[500],{"type":60,"value":501},"src\u002F",{"type":60,"value":503}," → App Router",{"type":55,"tag":74,"props":505,"children":506},{},[507,513],{"type":55,"tag":200,"props":508,"children":510},{"className":509},[],[511],{"type":60,"value":512},"pages\u002F",{"type":60,"value":514}," directory → Pages Router",{"type":55,"tag":74,"props":516,"children":517},{},[518],{"type":60,"value":519},"Both → App Router (it takes precedence)",{"type":55,"tag":63,"props":521,"children":523},{"id":522},"_0d-architecture-pattern-detection",[524],{"type":60,"value":525},"0d. Architecture pattern detection",{"type":55,"tag":56,"props":527,"children":528},{},[529],{"type":60,"value":530},"Detect special architectural patterns that require specific Faro wiring.",{"type":55,"tag":56,"props":532,"children":533},{},[534,539],{"type":55,"tag":78,"props":535,"children":536},{},[537],{"type":60,"value":538},"Microfrontend detection",{"type":60,"value":540}," — check for:",{"type":55,"tag":70,"props":542,"children":543},{},[544,610],{"type":55,"tag":74,"props":545,"children":546},{},[547,552,554,560,562,568,569,575,576,582,583,589,590,596,597,603,604],{"type":55,"tag":200,"props":548,"children":550},{"className":549},[],[551],{"type":60,"value":302},{"type":60,"value":553}," deps: ",{"type":55,"tag":200,"props":555,"children":557},{"className":556},[],[558],{"type":60,"value":559},"single-spa",{"type":60,"value":561},", ",{"type":55,"tag":200,"props":563,"children":565},{"className":564},[],[566],{"type":60,"value":567},"@single-spa\u002Frecommended-layout",{"type":60,"value":561},{"type":55,"tag":200,"props":570,"children":572},{"className":571},[],[573],{"type":60,"value":574},"@single-spa\u002Fparcel",{"type":60,"value":561},{"type":55,"tag":200,"props":577,"children":579},{"className":578},[],[580],{"type":60,"value":581},"@module-federation\u002Fruntime",{"type":60,"value":561},{"type":55,"tag":200,"props":584,"children":586},{"className":585},[],[587],{"type":60,"value":588},"@module-federation\u002Fenhanced",{"type":60,"value":561},{"type":55,"tag":200,"props":591,"children":593},{"className":592},[],[594],{"type":60,"value":595},"qiankun",{"type":60,"value":561},{"type":55,"tag":200,"props":598,"children":600},{"className":599},[],[601],{"type":60,"value":602},"garfish",{"type":60,"value":561},{"type":55,"tag":200,"props":605,"children":607},{"className":606},[],[608],{"type":60,"value":609},"wujie",{"type":55,"tag":74,"props":611,"children":612},{},[613,615,621,622,628,630],{"type":60,"value":614},"Webpack config files (",{"type":55,"tag":200,"props":616,"children":618},{"className":617},[],[619],{"type":60,"value":620},"webpack.config.js",{"type":60,"value":561},{"type":55,"tag":200,"props":623,"children":625},{"className":624},[],[626],{"type":60,"value":627},"webpack.config.ts",{"type":60,"value":629},"): grep for ",{"type":55,"tag":200,"props":631,"children":633},{"className":632},[],[634],{"type":60,"value":635},"ModuleFederationPlugin",{"type":55,"tag":56,"props":637,"children":638},{},[639,641,646],{"type":60,"value":640},"If found, record: ",{"type":55,"tag":78,"props":642,"children":643},{},[644],{"type":60,"value":645},"microfrontend framework detected",{"type":60,"value":647}," (and which one).",{"type":55,"tag":56,"props":649,"children":650},{},[651,656,658,663,665,671],{"type":55,"tag":78,"props":652,"children":653},{},[654],{"type":60,"value":655},"iFrame \u002F embedded app detection",{"type":60,"value":657}," — scan ",{"type":55,"tag":200,"props":659,"children":661},{"className":660},[],[662],{"type":60,"value":501},{"type":60,"value":664}," source files (",{"type":55,"tag":200,"props":666,"children":668},{"className":667},[],[669],{"type":60,"value":670},".js,.ts,.jsx,.tsx,.vue,.svelte",{"type":60,"value":672},") for:",{"type":55,"tag":70,"props":674,"children":675},{},[676,687,698],{"type":55,"tag":74,"props":677,"children":678},{},[679,685],{"type":55,"tag":200,"props":680,"children":682},{"className":681},[],[683],{"type":60,"value":684},"window\\.parent",{"type":60,"value":686}," — this app may run inside or communicate with a parent frame",{"type":55,"tag":74,"props":688,"children":689},{},[690,696],{"type":55,"tag":200,"props":691,"children":693},{"className":692},[],[694],{"type":60,"value":695},"window\\.top",{"type":60,"value":697}," — checking iframe context at runtime",{"type":55,"tag":74,"props":699,"children":700},{},[701,707],{"type":55,"tag":200,"props":702,"children":704},{"className":703},[],[705],{"type":60,"value":706},"\\.postMessage\\(",{"type":60,"value":708}," — cross-frame messaging",{"type":55,"tag":56,"props":710,"children":711},{},[712,713,718],{"type":60,"value":640},{"type":55,"tag":78,"props":714,"children":715},{},[716],{"type":60,"value":717},"cross-frame communication patterns detected",{"type":60,"value":719},".",{"type":55,"tag":56,"props":721,"children":722},{},[723],{"type":60,"value":724},"Do not surface these yet — add them to the Step 0h summary.",{"type":55,"tag":63,"props":726,"children":728},{"id":727},"_0e-check-for-existing-faro",[729],{"type":60,"value":730},"0e. Check for existing Faro",{"type":55,"tag":56,"props":732,"children":733},{},[734,736,742,743,749,751,756],{"type":60,"value":735},"Check if ",{"type":55,"tag":200,"props":737,"children":739},{"className":738},[],[740],{"type":60,"value":741},"@grafana\u002Ffaro-web-sdk",{"type":60,"value":356},{"type":55,"tag":200,"props":744,"children":746},{"className":745},[],[747],{"type":60,"value":748},"@grafana\u002Ffaro-react",{"type":60,"value":750}," is already in ",{"type":55,"tag":200,"props":752,"children":754},{"className":753},[],[755],{"type":60,"value":302},{"type":60,"value":757}," dependencies. If found, present three options before continuing:",{"type":55,"tag":759,"props":760,"children":761},"blockquote",{},[762,767],{"type":55,"tag":56,"props":763,"children":764},{},[765],{"type":60,"value":766},"Faro is already installed. What would you like to do?",{"type":55,"tag":768,"props":769,"children":770},"ol",{},[771,781,791],{"type":55,"tag":74,"props":772,"children":773},{},[774,779],{"type":55,"tag":78,"props":775,"children":776},{},[777],{"type":60,"value":778},"Add more options",{"type":60,"value":780}," — set up route tracking, user identity, cookie consent, or other advanced features",{"type":55,"tag":74,"props":782,"children":783},{},[784,789],{"type":55,"tag":78,"props":785,"children":786},{},[787],{"type":60,"value":788},"Reconfigure",{"type":60,"value":790}," — re-run the full setup from scratch",{"type":55,"tag":74,"props":792,"children":793},{},[794,799],{"type":55,"tag":78,"props":795,"children":796},{},[797],{"type":60,"value":798},"Stop",{"type":60,"value":800}," — nothing to do here",{"type":55,"tag":56,"props":802,"children":803},{},[804,806,811,813,819,821,826],{"type":60,"value":805},"If ",{"type":55,"tag":78,"props":807,"children":808},{},[809],{"type":60,"value":810},"1 (Add more)",{"type":60,"value":812},": skip Steps 0c, 0d, 0f, 0g, 0h and Steps 1–3. Instead, silently locate the existing Faro init file (search for files containing ",{"type":55,"tag":200,"props":814,"children":816},{"className":815},[],[817],{"type":60,"value":818},"initializeFaro",{"type":60,"value":820}," in ",{"type":55,"tag":200,"props":822,"children":824},{"className":823},[],[825],{"type":60,"value":501},{"type":60,"value":827},") and use the framework already detected in Step 0b as context. Then jump directly to Step 4's setup menu.",{"type":55,"tag":56,"props":829,"children":830},{},[831,832,837],{"type":60,"value":805},{"type":55,"tag":78,"props":833,"children":834},{},[835],{"type":60,"value":836},"2 (Reconfigure)",{"type":60,"value":838},": continue with the rest of Step 0 as normal.",{"type":55,"tag":56,"props":840,"children":841},{},[842,843,848],{"type":60,"value":805},{"type":55,"tag":78,"props":844,"children":845},{},[846],{"type":60,"value":847},"3 (Stop)",{"type":60,"value":849},": exit.",{"type":55,"tag":63,"props":851,"children":853},{"id":852},"_0f-find-entry-points",[854],{"type":60,"value":855},"0f. Find entry points",{"type":55,"tag":56,"props":857,"children":858},{},[859],{"type":60,"value":860},"Locate the main entry file:",{"type":55,"tag":70,"props":862,"children":863},{},[864,915,951,987,1008,1029,1049,1098],{"type":55,"tag":74,"props":865,"children":866},{},[867,872,874,880,881,887,888,894,895,901,902,908,909],{"type":55,"tag":78,"props":868,"children":869},{},[870],{"type":60,"value":871},"React",{"type":60,"value":873},": ",{"type":55,"tag":200,"props":875,"children":877},{"className":876},[],[878],{"type":60,"value":879},"src\u002Fmain.tsx",{"type":60,"value":561},{"type":55,"tag":200,"props":882,"children":884},{"className":883},[],[885],{"type":60,"value":886},"src\u002Fmain.ts",{"type":60,"value":561},{"type":55,"tag":200,"props":889,"children":891},{"className":890},[],[892],{"type":60,"value":893},"src\u002Findex.tsx",{"type":60,"value":561},{"type":55,"tag":200,"props":896,"children":898},{"className":897},[],[899],{"type":60,"value":900},"src\u002Findex.ts",{"type":60,"value":561},{"type":55,"tag":200,"props":903,"children":905},{"className":904},[],[906],{"type":60,"value":907},"src\u002Fmain.jsx",{"type":60,"value":561},{"type":55,"tag":200,"props":910,"children":912},{"className":911},[],[913],{"type":60,"value":914},"src\u002Findex.jsx",{"type":55,"tag":74,"props":916,"children":917},{},[918,923,924,930,931,937,938,944,945],{"type":55,"tag":78,"props":919,"children":920},{},[921],{"type":60,"value":922},"Next.js App Router",{"type":60,"value":873},{"type":55,"tag":200,"props":925,"children":927},{"className":926},[],[928],{"type":60,"value":929},"app\u002Flayout.tsx",{"type":60,"value":561},{"type":55,"tag":200,"props":932,"children":934},{"className":933},[],[935],{"type":60,"value":936},"app\u002Flayout.jsx",{"type":60,"value":561},{"type":55,"tag":200,"props":939,"children":941},{"className":940},[],[942],{"type":60,"value":943},"src\u002Fapp\u002Flayout.tsx",{"type":60,"value":561},{"type":55,"tag":200,"props":946,"children":948},{"className":947},[],[949],{"type":60,"value":950},"src\u002Fapp\u002Flayout.jsx",{"type":55,"tag":74,"props":952,"children":953},{},[954,959,960,966,967,973,974,980,981],{"type":55,"tag":78,"props":955,"children":956},{},[957],{"type":60,"value":958},"Next.js Pages Router",{"type":60,"value":873},{"type":55,"tag":200,"props":961,"children":963},{"className":962},[],[964],{"type":60,"value":965},"pages\u002F_app.tsx",{"type":60,"value":561},{"type":55,"tag":200,"props":968,"children":970},{"className":969},[],[971],{"type":60,"value":972},"pages\u002F_app.jsx",{"type":60,"value":561},{"type":55,"tag":200,"props":975,"children":977},{"className":976},[],[978],{"type":60,"value":979},"src\u002Fpages\u002F_app.tsx",{"type":60,"value":561},{"type":55,"tag":200,"props":982,"children":984},{"className":983},[],[985],{"type":60,"value":986},"src\u002Fpages\u002F_app.jsx",{"type":55,"tag":74,"props":988,"children":989},{},[990,995,996,1002,1003],{"type":55,"tag":78,"props":991,"children":992},{},[993],{"type":60,"value":994},"Angular",{"type":60,"value":873},{"type":55,"tag":200,"props":997,"children":999},{"className":998},[],[1000],{"type":60,"value":1001},"src\u002Fapp\u002Fapp.module.ts",{"type":60,"value":561},{"type":55,"tag":200,"props":1004,"children":1006},{"className":1005},[],[1007],{"type":60,"value":886},{"type":55,"tag":74,"props":1009,"children":1010},{},[1011,1016,1017,1022,1023],{"type":55,"tag":78,"props":1012,"children":1013},{},[1014],{"type":60,"value":1015},"Vue",{"type":60,"value":873},{"type":55,"tag":200,"props":1018,"children":1020},{"className":1019},[],[1021],{"type":60,"value":886},{"type":60,"value":561},{"type":55,"tag":200,"props":1024,"children":1026},{"className":1025},[],[1027],{"type":60,"value":1028},"src\u002Fmain.js",{"type":55,"tag":74,"props":1030,"children":1031},{},[1032,1037,1038,1043,1044],{"type":55,"tag":78,"props":1033,"children":1034},{},[1035],{"type":60,"value":1036},"Svelte",{"type":60,"value":873},{"type":55,"tag":200,"props":1039,"children":1041},{"className":1040},[],[1042],{"type":60,"value":886},{"type":60,"value":561},{"type":55,"tag":200,"props":1045,"children":1047},{"className":1046},[],[1048],{"type":60,"value":1028},{"type":55,"tag":74,"props":1050,"children":1051},{},[1052,1057,1058,1063,1064,1069,1070,1075,1076,1082,1083,1089,1090,1096],{"type":55,"tag":78,"props":1053,"children":1054},{},[1055],{"type":60,"value":1056},"Vanilla JS",{"type":60,"value":873},{"type":55,"tag":200,"props":1059,"children":1061},{"className":1060},[],[1062],{"type":60,"value":886},{"type":60,"value":561},{"type":55,"tag":200,"props":1065,"children":1067},{"className":1066},[],[1068],{"type":60,"value":1028},{"type":60,"value":561},{"type":55,"tag":200,"props":1071,"children":1073},{"className":1072},[],[1074],{"type":60,"value":900},{"type":60,"value":561},{"type":55,"tag":200,"props":1077,"children":1079},{"className":1078},[],[1080],{"type":60,"value":1081},"src\u002Findex.js",{"type":60,"value":561},{"type":55,"tag":200,"props":1084,"children":1086},{"className":1085},[],[1087],{"type":60,"value":1088},"index.js",{"type":60,"value":561},{"type":55,"tag":200,"props":1091,"children":1093},{"className":1092},[],[1094],{"type":60,"value":1095},"app.js",{"type":60,"value":1097}," or similar",{"type":55,"tag":74,"props":1099,"children":1100},{},[1101,1106,1107,1113,1114,1120],{"type":55,"tag":78,"props":1102,"children":1103},{},[1104],{"type":60,"value":1105},"Plain HTML",{"type":60,"value":873},{"type":55,"tag":200,"props":1108,"children":1110},{"className":1109},[],[1111],{"type":60,"value":1112},"index.html",{"type":60,"value":561},{"type":55,"tag":200,"props":1115,"children":1117},{"className":1116},[],[1118],{"type":60,"value":1119},"*.html",{"type":60,"value":1121}," in root",{"type":55,"tag":56,"props":1123,"children":1124},{},[1125],{"type":60,"value":1126},"Read the entry point file so you understand its current structure.",{"type":55,"tag":63,"props":1128,"children":1130},{"id":1129},"_0g-scan-for-3rd-party-noise",[1131],{"type":60,"value":1132},"0g. Scan for 3rd party noise",{"type":55,"tag":56,"props":1134,"children":1135},{},[1136],{"type":60,"value":1137},"Silently scan the project for analytics, tracking, and session recording scripts that would generate noise in Faro's network instrumentation. Do NOT ask the user anything yet — collect candidates only.",{"type":55,"tag":56,"props":1139,"children":1140},{},[1141],{"type":55,"tag":78,"props":1142,"children":1143},{},[1144],{"type":60,"value":1145},"Scan locations:",{"type":55,"tag":768,"props":1147,"children":1148},{},[1149,1162,1172],{"type":55,"tag":74,"props":1150,"children":1151},{},[1152,1154,1160],{"type":60,"value":1153},"HTML files — look for ",{"type":55,"tag":200,"props":1155,"children":1157},{"className":1156},[],[1158],{"type":60,"value":1159},"\u003Cscript src=\"...\">",{"type":60,"value":1161}," attributes pointing to external domains.",{"type":55,"tag":74,"props":1163,"children":1164},{},[1165,1170],{"type":55,"tag":200,"props":1166,"children":1168},{"className":1167},[],[1169],{"type":60,"value":302},{"type":60,"value":1171}," — look for known packages in dependencies\u002FdevDependencies.",{"type":55,"tag":74,"props":1173,"children":1174},{},[1175,1177,1182,1184,1189,1191,1197,1198,1204,1206,1212],{"type":60,"value":1176},"Source files — grep for known 3rd party domain strings in ",{"type":55,"tag":200,"props":1178,"children":1180},{"className":1179},[],[1181],{"type":60,"value":670},{"type":60,"value":1183}," files under ",{"type":55,"tag":200,"props":1185,"children":1187},{"className":1186},[],[1188],{"type":60,"value":501},{"type":60,"value":1190}," only, up to 3 levels deep. Do NOT scan ",{"type":55,"tag":200,"props":1192,"children":1194},{"className":1193},[],[1195],{"type":60,"value":1196},"node_modules\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":1199,"children":1201},{"className":1200},[],[1202],{"type":60,"value":1203},"dist\u002F",{"type":60,"value":1205},", or ",{"type":55,"tag":200,"props":1207,"children":1209},{"className":1208},[],[1210],{"type":60,"value":1211},"build\u002F",{"type":60,"value":719},{"type":55,"tag":56,"props":1214,"children":1215},{},[1216],{"type":55,"tag":78,"props":1217,"children":1218},{},[1219],{"type":60,"value":1220},"Known 3rd party signals:",{"type":55,"tag":1222,"props":1223,"children":1224},"table",{},[1225,1244],{"type":55,"tag":1226,"props":1227,"children":1228},"thead",{},[1229],{"type":55,"tag":1230,"props":1231,"children":1232},"tr",{},[1233,1239],{"type":55,"tag":1234,"props":1235,"children":1236},"th",{},[1237],{"type":60,"value":1238},"Package \u002F Domain",{"type":55,"tag":1234,"props":1240,"children":1241},{},[1242],{"type":60,"value":1243},"Service",{"type":55,"tag":1245,"props":1246,"children":1247},"tbody",{},[1248,1287,1318,1349,1387,1418,1449,1480,1504,1556,1587,1611,1642],{"type":55,"tag":1230,"props":1249,"children":1250},{},[1251,1282],{"type":55,"tag":1252,"props":1253,"children":1254},"td",{},[1255,1261,1262,1268,1269,1275,1276],{"type":55,"tag":200,"props":1256,"children":1258},{"className":1257},[],[1259],{"type":60,"value":1260},"@segment\u002Fanalytics-next",{"type":60,"value":561},{"type":55,"tag":200,"props":1263,"children":1265},{"className":1264},[],[1266],{"type":60,"value":1267},"analytics.js",{"type":60,"value":561},{"type":55,"tag":200,"props":1270,"children":1272},{"className":1271},[],[1273],{"type":60,"value":1274},"cdn.segment.com",{"type":60,"value":561},{"type":55,"tag":200,"props":1277,"children":1279},{"className":1278},[],[1280],{"type":60,"value":1281},"api.segment.io",{"type":55,"tag":1252,"props":1283,"children":1284},{},[1285],{"type":60,"value":1286},"Segment",{"type":55,"tag":1230,"props":1288,"children":1289},{},[1290,1313],{"type":55,"tag":1252,"props":1291,"children":1292},{},[1293,1299,1300,1306,1307],{"type":55,"tag":200,"props":1294,"children":1296},{"className":1295},[],[1297],{"type":60,"value":1298},"posthog-js",{"type":60,"value":561},{"type":55,"tag":200,"props":1301,"children":1303},{"className":1302},[],[1304],{"type":60,"value":1305},"app.posthog.com",{"type":60,"value":561},{"type":55,"tag":200,"props":1308,"children":1310},{"className":1309},[],[1311],{"type":60,"value":1312},"eu.posthog.com",{"type":55,"tag":1252,"props":1314,"children":1315},{},[1316],{"type":60,"value":1317},"PostHog",{"type":55,"tag":1230,"props":1319,"children":1320},{},[1321,1344],{"type":55,"tag":1252,"props":1322,"children":1323},{},[1324,1330,1331,1337,1338],{"type":55,"tag":200,"props":1325,"children":1327},{"className":1326},[],[1328],{"type":60,"value":1329},"mixpanel-browser",{"type":60,"value":561},{"type":55,"tag":200,"props":1332,"children":1334},{"className":1333},[],[1335],{"type":60,"value":1336},"api.mixpanel.com",{"type":60,"value":561},{"type":55,"tag":200,"props":1339,"children":1341},{"className":1340},[],[1342],{"type":60,"value":1343},"cdn.mxpnl.com",{"type":55,"tag":1252,"props":1345,"children":1346},{},[1347],{"type":60,"value":1348},"Mixpanel",{"type":55,"tag":1230,"props":1350,"children":1351},{},[1352,1382],{"type":55,"tag":1252,"props":1353,"children":1354},{},[1355,1361,1362,1368,1369,1375,1376],{"type":55,"tag":200,"props":1356,"children":1358},{"className":1357},[],[1359],{"type":60,"value":1360},"amplitude-js",{"type":60,"value":561},{"type":55,"tag":200,"props":1363,"children":1365},{"className":1364},[],[1366],{"type":60,"value":1367},"@amplitude\u002Fanalytics-browser",{"type":60,"value":561},{"type":55,"tag":200,"props":1370,"children":1372},{"className":1371},[],[1373],{"type":60,"value":1374},"api2.amplitude.com",{"type":60,"value":561},{"type":55,"tag":200,"props":1377,"children":1379},{"className":1378},[],[1380],{"type":60,"value":1381},"cdn.amplitude.com",{"type":55,"tag":1252,"props":1383,"children":1384},{},[1385],{"type":60,"value":1386},"Amplitude",{"type":55,"tag":1230,"props":1388,"children":1389},{},[1390,1413],{"type":55,"tag":1252,"props":1391,"children":1392},{},[1393,1399,1400,1406,1407],{"type":55,"tag":200,"props":1394,"children":1396},{"className":1395},[],[1397],{"type":60,"value":1398},"@hotjar\u002Fbrowser",{"type":60,"value":561},{"type":55,"tag":200,"props":1401,"children":1403},{"className":1402},[],[1404],{"type":60,"value":1405},"static.hotjar.com",{"type":60,"value":561},{"type":55,"tag":200,"props":1408,"children":1410},{"className":1409},[],[1411],{"type":60,"value":1412},"script.hotjar.com",{"type":55,"tag":1252,"props":1414,"children":1415},{},[1416],{"type":60,"value":1417},"Hotjar",{"type":55,"tag":1230,"props":1419,"children":1420},{},[1421,1444],{"type":55,"tag":1252,"props":1422,"children":1423},{},[1424,1430,1431,1437,1438],{"type":55,"tag":200,"props":1425,"children":1427},{"className":1426},[],[1428],{"type":60,"value":1429},"@fullstory\u002Fbrowser",{"type":60,"value":561},{"type":55,"tag":200,"props":1432,"children":1434},{"className":1433},[],[1435],{"type":60,"value":1436},"fullstory.com",{"type":60,"value":561},{"type":55,"tag":200,"props":1439,"children":1441},{"className":1440},[],[1442],{"type":60,"value":1443},"rs.fullstory.com",{"type":55,"tag":1252,"props":1445,"children":1446},{},[1447],{"type":60,"value":1448},"FullStory",{"type":55,"tag":1230,"props":1450,"children":1451},{},[1452,1475],{"type":55,"tag":1252,"props":1453,"children":1454},{},[1455,1461,1462,1468,1469],{"type":55,"tag":200,"props":1456,"children":1458},{"className":1457},[],[1459],{"type":60,"value":1460},"@intercom\u002Fmessenger-js-sdk",{"type":60,"value":561},{"type":55,"tag":200,"props":1463,"children":1465},{"className":1464},[],[1466],{"type":60,"value":1467},"widget.intercom.io",{"type":60,"value":561},{"type":55,"tag":200,"props":1470,"children":1472},{"className":1471},[],[1473],{"type":60,"value":1474},"api-iam.intercom.io",{"type":55,"tag":1252,"props":1476,"children":1477},{},[1478],{"type":60,"value":1479},"Intercom",{"type":55,"tag":1230,"props":1481,"children":1482},{},[1483,1499],{"type":55,"tag":1252,"props":1484,"children":1485},{},[1486,1492,1493],{"type":55,"tag":200,"props":1487,"children":1489},{"className":1488},[],[1490],{"type":60,"value":1491},"@datadog\u002Fbrowser-rum",{"type":60,"value":561},{"type":55,"tag":200,"props":1494,"children":1496},{"className":1495},[],[1497],{"type":60,"value":1498},"browser-intake-datadoghq.com",{"type":55,"tag":1252,"props":1500,"children":1501},{},[1502],{"type":60,"value":1503},"Datadog RUM",{"type":55,"tag":1230,"props":1505,"children":1506},{},[1507,1551],{"type":55,"tag":1252,"props":1508,"children":1509},{},[1510,1516,1517,1523,1524,1530,1531,1537,1538,1544,1545],{"type":55,"tag":200,"props":1511,"children":1513},{"className":1512},[],[1514],{"type":60,"value":1515},"react-ga",{"type":60,"value":561},{"type":55,"tag":200,"props":1518,"children":1520},{"className":1519},[],[1521],{"type":60,"value":1522},"react-ga4",{"type":60,"value":561},{"type":55,"tag":200,"props":1525,"children":1527},{"className":1526},[],[1528],{"type":60,"value":1529},"vue-gtag",{"type":60,"value":561},{"type":55,"tag":200,"props":1532,"children":1534},{"className":1533},[],[1535],{"type":60,"value":1536},"google-analytics.com",{"type":60,"value":561},{"type":55,"tag":200,"props":1539,"children":1541},{"className":1540},[],[1542],{"type":60,"value":1543},"googletagmanager.com",{"type":60,"value":561},{"type":55,"tag":200,"props":1546,"children":1548},{"className":1547},[],[1549],{"type":60,"value":1550},"analytics.google.com",{"type":55,"tag":1252,"props":1552,"children":1553},{},[1554],{"type":60,"value":1555},"Google Analytics \u002F GTM",{"type":55,"tag":1230,"props":1557,"children":1558},{},[1559,1582],{"type":55,"tag":1252,"props":1560,"children":1561},{},[1562,1568,1569,1575,1576],{"type":55,"tag":200,"props":1563,"children":1565},{"className":1564},[],[1566],{"type":60,"value":1567},"drift",{"type":60,"value":561},{"type":55,"tag":200,"props":1570,"children":1572},{"className":1571},[],[1573],{"type":60,"value":1574},"js.driftt.com",{"type":60,"value":561},{"type":55,"tag":200,"props":1577,"children":1579},{"className":1578},[],[1580],{"type":60,"value":1581},"api.drift.com",{"type":55,"tag":1252,"props":1583,"children":1584},{},[1585],{"type":60,"value":1586},"Drift",{"type":55,"tag":1230,"props":1588,"children":1589},{},[1590,1606],{"type":55,"tag":1252,"props":1591,"children":1592},{},[1593,1599,1600],{"type":55,"tag":200,"props":1594,"children":1596},{"className":1595},[],[1597],{"type":60,"value":1598},"crisp-sdk-web",{"type":60,"value":561},{"type":55,"tag":200,"props":1601,"children":1603},{"className":1602},[],[1604],{"type":60,"value":1605},"client.crisp.chat",{"type":55,"tag":1252,"props":1607,"children":1608},{},[1609],{"type":60,"value":1610},"Crisp",{"type":55,"tag":1230,"props":1612,"children":1613},{},[1614,1637],{"type":55,"tag":1252,"props":1615,"children":1616},{},[1617,1623,1624,1630,1631],{"type":55,"tag":200,"props":1618,"children":1620},{"className":1619},[],[1621],{"type":60,"value":1622},"logrocket",{"type":60,"value":561},{"type":55,"tag":200,"props":1625,"children":1627},{"className":1626},[],[1628],{"type":60,"value":1629},"cdn.logrocket.io",{"type":60,"value":561},{"type":55,"tag":200,"props":1632,"children":1634},{"className":1633},[],[1635],{"type":60,"value":1636},"r.lr-ingest.io",{"type":55,"tag":1252,"props":1638,"children":1639},{},[1640],{"type":60,"value":1641},"LogRocket",{"type":55,"tag":1230,"props":1643,"children":1644},{},[1645,1661],{"type":55,"tag":1252,"props":1646,"children":1647},{},[1648,1654,1655],{"type":55,"tag":200,"props":1649,"children":1651},{"className":1650},[],[1652],{"type":60,"value":1653},"connect.facebook.net",{"type":60,"value":561},{"type":55,"tag":200,"props":1656,"children":1658},{"className":1657},[],[1659],{"type":60,"value":1660},"facebook.com\u002Ftr",{"type":55,"tag":1252,"props":1662,"children":1663},{},[1664],{"type":60,"value":1665},"Facebook Pixel",{"type":55,"tag":56,"props":1667,"children":1668},{},[1669],{"type":60,"value":1670},"For each match, record: the service name, the matched signal (package or domain), and where it was found (file path).",{"type":55,"tag":56,"props":1672,"children":1673},{},[1674,1676,1682],{"type":60,"value":1675},"Also collect universally noisy browser errors to suggest for ",{"type":55,"tag":200,"props":1677,"children":1679},{"className":1678},[],[1680],{"type":60,"value":1681},"ignoreErrors",{"type":60,"value":1683},":",{"type":55,"tag":70,"props":1685,"children":1686},{},[1687,1698,1709,1729],{"type":55,"tag":74,"props":1688,"children":1689},{},[1690,1696],{"type":55,"tag":200,"props":1691,"children":1693},{"className":1692},[],[1694],{"type":60,"value":1695},"ResizeObserver loop limit exceeded",{"type":60,"value":1697}," — a harmless browser quirk, not a real error",{"type":55,"tag":74,"props":1699,"children":1700},{},[1701,1707],{"type":55,"tag":200,"props":1702,"children":1704},{"className":1703},[],[1705],{"type":60,"value":1706},"ResizeObserver loop completed with undelivered notifications",{"type":60,"value":1708}," — same",{"type":55,"tag":74,"props":1710,"children":1711},{},[1712,1714,1720,1721,1727],{"type":60,"value":1713},"Chrome\u002FFirefox extension interference: errors from ",{"type":55,"tag":200,"props":1715,"children":1717},{"className":1716},[],[1718],{"type":60,"value":1719},"chrome-extension:\u002F\u002F",{"type":60,"value":356},{"type":55,"tag":200,"props":1722,"children":1724},{"className":1723},[],[1725],{"type":60,"value":1726},"moz-extension:\u002F\u002F",{"type":60,"value":1728}," URLs",{"type":55,"tag":74,"props":1730,"children":1731},{},[1732,1734,1740],{"type":60,"value":1733},"Script errors from cross-origin scripts with no stack: ",{"type":55,"tag":200,"props":1735,"children":1737},{"className":1736},[],[1738],{"type":60,"value":1739},"Script error.",{"type":60,"value":1741}," with empty stack",{"type":55,"tag":63,"props":1743,"children":1745},{"id":1744},"_0h-present-summary-and-confirm",[1746],{"type":60,"value":1747},"0h. Present summary and confirm",{"type":55,"tag":56,"props":1749,"children":1750},{},[1751],{"type":60,"value":1752},"Show a one-line summary of what was detected and ask the user to confirm:",{"type":55,"tag":759,"props":1754,"children":1755},{},[1756],{"type":55,"tag":56,"props":1757,"children":1758},{},[1759,1761,1767,1768,1773,1775,1780,1781,1786,1787,1792,1794,1800],{"type":60,"value":1760},"Detected: ",{"type":55,"tag":1762,"props":1763,"children":1764},"span",{},[1765],{"type":60,"value":1766},"Framework",{"type":60,"value":198},{"type":55,"tag":1762,"props":1769,"children":1770},{},[1771],{"type":60,"value":1772},"version if relevant",{"type":60,"value":1774}," + ",{"type":55,"tag":1762,"props":1776,"children":1777},{},[1778],{"type":60,"value":1779},"Router if applicable",{"type":60,"value":561},{"type":55,"tag":1762,"props":1782,"children":1783},{},[1784],{"type":60,"value":1785},"Package manager",{"type":60,"value":561},{"type":55,"tag":1762,"props":1788,"children":1789},{},[1790],{"type":60,"value":1791},"Faro status: \"no Faro yet\" or \"Faro already installed\"",{"type":60,"value":1793},". Entry point: ",{"type":55,"tag":200,"props":1795,"children":1797},{"className":1796},[],[1798],{"type":60,"value":1799},"[path]",{"type":60,"value":719},{"type":55,"tag":56,"props":1802,"children":1803},{},[1804],{"type":60,"value":1805},"If 3rd party libraries were found in 0g, mention them in the summary (but do NOT configure them yet — that happens after the base setup):",{"type":55,"tag":759,"props":1807,"children":1808},{},[1809],{"type":55,"tag":56,"props":1810,"children":1811},{},[1812,1814,1819,1821,1827,1829,1834,1835,1840],{"type":60,"value":1813},"Also found: Hotjar (",{"type":55,"tag":200,"props":1815,"children":1817},{"className":1816},[],[1818],{"type":60,"value":1405},{"type":60,"value":1820},") in ",{"type":55,"tag":200,"props":1822,"children":1824},{"className":1823},[],[1825],{"type":60,"value":1826},"public\u002Findex.html",{"type":60,"value":1828},", Segment (",{"type":55,"tag":200,"props":1830,"children":1832},{"className":1831},[],[1833],{"type":60,"value":1260},{"type":60,"value":1820},{"type":55,"tag":200,"props":1836,"children":1838},{"className":1837},[],[1839],{"type":60,"value":302},{"type":60,"value":1841}," — I'll suggest excluding these from network tracking after the base setup.",{"type":55,"tag":56,"props":1843,"children":1844},{},[1845],{"type":60,"value":1846},"If architecture patterns were found in 0d, note them prominently — users need to know their setup is recognized:",{"type":55,"tag":759,"props":1848,"children":1849},{},[1850],{"type":55,"tag":56,"props":1851,"children":1852},{},[1853,1855,1860,1862,1867],{"type":60,"value":1854},"⚠️ ",{"type":55,"tag":78,"props":1856,"children":1857},{},[1858],{"type":60,"value":1859},"Microfrontend framework detected",{"type":60,"value":1861}," (",{"type":55,"tag":200,"props":1863,"children":1865},{"className":1864},[],[1866],{"type":60,"value":559},{"type":60,"value":1868},"). Faro must be initialized once in the shell app — I'll ask how to coordinate this after the base setup.",{"type":55,"tag":759,"props":1870,"children":1871},{},[1872],{"type":55,"tag":56,"props":1873,"children":1874},{},[1875,1876,1881,1882,1888,1889,1895],{"type":60,"value":1854},{"type":55,"tag":78,"props":1877,"children":1878},{},[1879],{"type":60,"value":1880},"Cross-frame communication patterns detected",{"type":60,"value":1861},{"type":55,"tag":200,"props":1883,"children":1885},{"className":1884},[],[1886],{"type":60,"value":1887},"window.parent",{"type":60,"value":561},{"type":55,"tag":200,"props":1890,"children":1892},{"className":1891},[],[1893],{"type":60,"value":1894},"postMessage",{"type":60,"value":1896},"). Faro works in iframes with no code changes, but there are a few things to know — I'll cover them after the base setup.",{"type":55,"tag":56,"props":1898,"children":1899},{},[1900],{"type":60,"value":1901},"If the project has a React\u002FVue\u002FSvelte\u002FNext.js SPA with a router, call it out:",{"type":55,"tag":759,"props":1903,"children":1904},{},[1905],{"type":55,"tag":56,"props":1906,"children":1907},{},[1908,1910,1915],{"type":60,"value":1909},"This is a ",{"type":55,"tag":78,"props":1911,"children":1912},{},[1913],{"type":60,"value":1914},"Single Page Application",{"type":60,"value":1916},". Route tracking is strongly recommended — without it, all errors, logs, and performance data appear under a single \"\u002F\" view in Grafana, making it hard to isolate page-specific issues. I'll offer this in the advanced setup.",{"type":55,"tag":56,"props":1918,"children":1919},{},[1920,1922,1927],{"type":60,"value":1921},"If the project is a React\u002FVue\u002FSvelte\u002FNext.js SPA but ",{"type":55,"tag":78,"props":1923,"children":1924},{},[1925],{"type":60,"value":1926},"no router was detected",{"type":60,"value":1928}," (or the detected router has no supported Faro integration), call it out:",{"type":55,"tag":759,"props":1930,"children":1931},{},[1932],{"type":55,"tag":56,"props":1933,"children":1934},{},[1935],{"type":60,"value":1936},"No router found — I'll enable auto-navigation tracking as part of the base setup so you still get URL change and timing data.",{"type":55,"tag":56,"props":1938,"children":1939},{},[1940],{"type":60,"value":1941},"If anything looks wrong, let the user correct it before proceeding.",{"type":55,"tag":277,"props":1943,"children":1944},{},[],{"type":55,"tag":281,"props":1946,"children":1948},{"id":1947},"step-1-collector-url",[1949],{"type":60,"value":1950},"Step 1: Collector URL",{"type":55,"tag":56,"props":1952,"children":1953},{},[1954],{"type":60,"value":1955},"Ask the user:",{"type":55,"tag":759,"props":1957,"children":1958},{},[1959,1964],{"type":55,"tag":56,"props":1960,"children":1961},{},[1962],{"type":60,"value":1963},"Do you have the snippet from the Grafana Cloud wizard, or just the collector URL? Paste either one.",{"type":55,"tag":56,"props":1965,"children":1966},{},[1967,1969,1974],{"type":60,"value":1968},"If you haven't created a Frontend Observability app yet, go to ",{"type":55,"tag":78,"props":1970,"children":1971},{},[1972],{"type":60,"value":1973},"Grafana Cloud → Observability → Frontend → Create new",{"type":60,"value":1975},", copy the snippet, and come back.",{"type":55,"tag":56,"props":1977,"children":1978},{},[1979],{"type":60,"value":1980},"Handle the response:",{"type":55,"tag":70,"props":1982,"children":1983},{},[1984,2018,2036],{"type":55,"tag":74,"props":1985,"children":1986},{},[1987,2000,2002,2008,2010,2016],{"type":55,"tag":78,"props":1988,"children":1989},{},[1990,1992,1998],{"type":60,"value":1991},"Full ",{"type":55,"tag":200,"props":1993,"children":1995},{"className":1994},[],[1996],{"type":60,"value":1997},"initializeFaro({...})",{"type":60,"value":1999}," snippet pasted",{"type":60,"value":2001},": extract the ",{"type":55,"tag":200,"props":2003,"children":2005},{"className":2004},[],[2006],{"type":60,"value":2007},"url",{"type":60,"value":2009}," value and ",{"type":55,"tag":200,"props":2011,"children":2013},{"className":2012},[],[2014],{"type":60,"value":2015},"app.name",{"type":60,"value":2017}," value. Skip to Step 1b confirmation.",{"type":55,"tag":74,"props":2019,"children":2020},{},[2021,2026,2028,2034],{"type":55,"tag":78,"props":2022,"children":2023},{},[2024],{"type":60,"value":2025},"URL pasted",{"type":60,"value":2027}," (starts with ",{"type":55,"tag":200,"props":2029,"children":2031},{"className":2030},[],[2032],{"type":60,"value":2033},"https:\u002F\u002F",{"type":60,"value":2035},"): use it as the collector URL. Proceed to Q2.",{"type":55,"tag":74,"props":2037,"children":2038},{},[2039,2044],{"type":55,"tag":78,"props":2040,"children":2041},{},[2042],{"type":60,"value":2043},"Neither",{"type":60,"value":2045},": wait. Tell them you need a collector URL to proceed.",{"type":55,"tag":56,"props":2047,"children":2048},{},[2049,2054],{"type":55,"tag":78,"props":2050,"children":2051},{},[2052],{"type":60,"value":2053},"Q2 — App name",{"type":60,"value":2055}," (only if not extracted from a snippet):",{"type":55,"tag":56,"props":2057,"children":2058},{},[2059,2060,2066,2068,2073],{"type":60,"value":296},{"type":55,"tag":200,"props":2061,"children":2063},{"className":2062},[],[2064],{"type":60,"value":2065},"name",{"type":60,"value":2067}," from ",{"type":55,"tag":200,"props":2069,"children":2071},{"className":2070},[],[2072],{"type":60,"value":302},{"type":60,"value":2074}," if available, and offer it as default:",{"type":55,"tag":759,"props":2076,"children":2077},{},[2078],{"type":55,"tag":56,"props":2079,"children":2080},{},[2081,2083,2089,2091,2096],{"type":60,"value":2082},"What should the app be called in Faro? Detected: ",{"type":55,"tag":200,"props":2084,"children":2086},{"className":2085},[],[2087],{"type":60,"value":2088},"[package.json name]",{"type":60,"value":2090},". Reply ",{"type":55,"tag":78,"props":2092,"children":2093},{},[2094],{"type":60,"value":2095},"y",{"type":60,"value":2097}," to confirm or type a new name.",{"type":55,"tag":56,"props":2099,"children":2100},{},[2101],{"type":55,"tag":78,"props":2102,"children":2103},{},[2104],{"type":60,"value":2105},"Step 1b — Confirm before generating code:",{"type":55,"tag":759,"props":2107,"children":2108},{},[2109,2114,2160],{"type":55,"tag":56,"props":2110,"children":2111},{},[2112],{"type":60,"value":2113},"Ready to instrument with:",{"type":55,"tag":70,"props":2115,"children":2116},{},[2117,2128,2139,2150],{"type":55,"tag":74,"props":2118,"children":2119},{},[2120,2122],{"type":60,"value":2121},"Collector: ",{"type":55,"tag":200,"props":2123,"children":2125},{"className":2124},[],[2126],{"type":60,"value":2127},"[URL]",{"type":55,"tag":74,"props":2129,"children":2130},{},[2131,2133],{"type":60,"value":2132},"App name: ",{"type":55,"tag":200,"props":2134,"children":2136},{"className":2135},[],[2137],{"type":60,"value":2138},"[name]",{"type":55,"tag":74,"props":2140,"children":2141},{},[2142,2144],{"type":60,"value":2143},"Framework: ",{"type":55,"tag":200,"props":2145,"children":2147},{"className":2146},[],[2148],{"type":60,"value":2149},"[detected framework]",{"type":55,"tag":74,"props":2151,"children":2152},{},[2153,2155],{"type":60,"value":2154},"Entry point: ",{"type":55,"tag":200,"props":2156,"children":2158},{"className":2157},[],[2159],{"type":60,"value":1799},{"type":55,"tag":56,"props":2161,"children":2162},{},[2163],{"type":60,"value":2164},"Proceed?",{"type":55,"tag":277,"props":2166,"children":2167},{},[],{"type":55,"tag":281,"props":2169,"children":2171},{"id":2170},"step-2-base-implementation",[2172],{"type":60,"value":2173},"Step 2: Base implementation",{"type":55,"tag":56,"props":2175,"children":2176},{},[2177,2178,2184,2186,2192,2194,2200],{"type":60,"value":296},{"type":55,"tag":200,"props":2179,"children":2181},{"className":2180},[],[2182],{"type":60,"value":2183},"frameworks.md",{"type":60,"value":2185}," now. Use the section matching the detected framework for install commands, init file content, and entry point wiring. Replace ",{"type":55,"tag":200,"props":2187,"children":2189},{"className":2188},[],[2190],{"type":60,"value":2191},"\u003CCOLLECTOR_URL>",{"type":60,"value":2193}," and ",{"type":55,"tag":200,"props":2195,"children":2197},{"className":2196},[],[2198],{"type":60,"value":2199},"\u003CAPP_NAME>",{"type":60,"value":2201}," with the values from Step 1.",{"type":55,"tag":56,"props":2203,"children":2204},{},[2205,2207,2212],{"type":60,"value":2206},"Run the package install command from the matching ",{"type":55,"tag":200,"props":2208,"children":2210},{"className":2209},[],[2211],{"type":60,"value":2183},{"type":60,"value":2213}," section (skip for CDN projects).",{"type":55,"tag":56,"props":2215,"children":2216},{},[2217,2218,2222,2224,2230,2232,2237],{"type":60,"value":805},{"type":55,"tag":78,"props":2219,"children":2220},{},[2221],{"type":60,"value":1926},{"type":60,"value":2223}," or the detected router has no supported Faro integration, add ",{"type":55,"tag":200,"props":2225,"children":2227},{"className":2226},[],[2228],{"type":60,"value":2229},"experimental: { trackNavigation: true }",{"type":60,"value":2231}," to the ",{"type":55,"tag":200,"props":2233,"children":2235},{"className":2234},[],[2236],{"type":60,"value":818},{"type":60,"value":2238}," call in the init file. Do NOT ask — apply it silently as part of the base config. This captures URL changes and navigation timing without a router.",{"type":55,"tag":277,"props":2240,"children":2241},{},[],{"type":55,"tag":281,"props":2243,"children":2245},{"id":2244},"step-3-noise-reduction-defaults",[2246],{"type":60,"value":2247},"Step 3: Noise reduction defaults",{"type":55,"tag":768,"props":2249,"children":2250},{},[2251,2484,2933,3016,3067,3077],{"type":55,"tag":74,"props":2252,"children":2253},{},[2254,2256,2261,2263],{"type":60,"value":2255},"Silently add ",{"type":55,"tag":200,"props":2257,"children":2259},{"className":2258},[],[2260],{"type":60,"value":1681},{"type":60,"value":2262}," for universal browser noise. Skip for CDN projects. Do NOT ask — these are always correct:",{"type":55,"tag":2264,"props":2265,"children":2270},"pre",{"className":2266,"code":2267,"language":2268,"meta":2269,"style":2269},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","ignoreErrors: [\n  \u002F\u002F Layout quirks — harmless, not real errors\n  \u002F^ResizeObserver loop limit exceeded$\u002F,\n  \u002F^ResizeObserver loop completed with undelivered notifications$\u002F,\n  \u002F\u002F Cross-origin scripts with no useful stack\n  \u002F^Script error\\.$\u002F,\n  \u002F\u002F Browser extension interference\n  \u002Fchrome-extension:\\\u002F\\\u002F\u002F,\n  \u002Fmoz-extension:\\\u002F\\\u002F\u002F,\n],\n","ts","",[2271],{"type":55,"tag":200,"props":2272,"children":2273},{"__ignoreMap":2269},[2274,2295,2305,2340,2368,2377,2411,2420,2446,2471],{"type":55,"tag":1762,"props":2275,"children":2278},{"class":2276,"line":2277},"line",1,[2279,2284,2289],{"type":55,"tag":1762,"props":2280,"children":2282},{"style":2281},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[2283],{"type":60,"value":1681},{"type":55,"tag":1762,"props":2285,"children":2287},{"style":2286},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[2288],{"type":60,"value":1683},{"type":55,"tag":1762,"props":2290,"children":2292},{"style":2291},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[2293],{"type":60,"value":2294}," [\n",{"type":55,"tag":1762,"props":2296,"children":2298},{"class":2276,"line":2297},2,[2299],{"type":55,"tag":1762,"props":2300,"children":2302},{"style":2301},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[2303],{"type":60,"value":2304},"  \u002F\u002F Layout quirks — harmless, not real errors\n",{"type":55,"tag":1762,"props":2306,"children":2308},{"class":2276,"line":2307},3,[2309,2314,2320,2325,2330,2335],{"type":55,"tag":1762,"props":2310,"children":2311},{"style":2286},[2312],{"type":60,"value":2313},"  \u002F",{"type":55,"tag":1762,"props":2315,"children":2317},{"style":2316},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[2318],{"type":60,"value":2319},"^",{"type":55,"tag":1762,"props":2321,"children":2323},{"style":2322},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[2324],{"type":60,"value":1695},{"type":55,"tag":1762,"props":2326,"children":2327},{"style":2316},[2328],{"type":60,"value":2329},"$",{"type":55,"tag":1762,"props":2331,"children":2332},{"style":2286},[2333],{"type":60,"value":2334},"\u002F",{"type":55,"tag":1762,"props":2336,"children":2337},{"style":2286},[2338],{"type":60,"value":2339},",\n",{"type":55,"tag":1762,"props":2341,"children":2343},{"class":2276,"line":2342},4,[2344,2348,2352,2356,2360,2364],{"type":55,"tag":1762,"props":2345,"children":2346},{"style":2286},[2347],{"type":60,"value":2313},{"type":55,"tag":1762,"props":2349,"children":2350},{"style":2316},[2351],{"type":60,"value":2319},{"type":55,"tag":1762,"props":2353,"children":2354},{"style":2322},[2355],{"type":60,"value":1706},{"type":55,"tag":1762,"props":2357,"children":2358},{"style":2316},[2359],{"type":60,"value":2329},{"type":55,"tag":1762,"props":2361,"children":2362},{"style":2286},[2363],{"type":60,"value":2334},{"type":55,"tag":1762,"props":2365,"children":2366},{"style":2286},[2367],{"type":60,"value":2339},{"type":55,"tag":1762,"props":2369,"children":2371},{"class":2276,"line":2370},5,[2372],{"type":55,"tag":1762,"props":2373,"children":2374},{"style":2301},[2375],{"type":60,"value":2376},"  \u002F\u002F Cross-origin scripts with no useful stack\n",{"type":55,"tag":1762,"props":2378,"children":2380},{"class":2276,"line":2379},6,[2381,2385,2389,2394,2399,2403,2407],{"type":55,"tag":1762,"props":2382,"children":2383},{"style":2286},[2384],{"type":60,"value":2313},{"type":55,"tag":1762,"props":2386,"children":2387},{"style":2316},[2388],{"type":60,"value":2319},{"type":55,"tag":1762,"props":2390,"children":2391},{"style":2322},[2392],{"type":60,"value":2393},"Script error",{"type":55,"tag":1762,"props":2395,"children":2396},{"style":2291},[2397],{"type":60,"value":2398},"\\.",{"type":55,"tag":1762,"props":2400,"children":2401},{"style":2316},[2402],{"type":60,"value":2329},{"type":55,"tag":1762,"props":2404,"children":2405},{"style":2286},[2406],{"type":60,"value":2334},{"type":55,"tag":1762,"props":2408,"children":2409},{"style":2286},[2410],{"type":60,"value":2339},{"type":55,"tag":1762,"props":2412,"children":2414},{"class":2276,"line":2413},7,[2415],{"type":55,"tag":1762,"props":2416,"children":2417},{"style":2301},[2418],{"type":60,"value":2419},"  \u002F\u002F Browser extension interference\n",{"type":55,"tag":1762,"props":2421,"children":2423},{"class":2276,"line":2422},8,[2424,2428,2433,2438,2442],{"type":55,"tag":1762,"props":2425,"children":2426},{"style":2286},[2427],{"type":60,"value":2313},{"type":55,"tag":1762,"props":2429,"children":2430},{"style":2322},[2431],{"type":60,"value":2432},"chrome-extension:",{"type":55,"tag":1762,"props":2434,"children":2435},{"style":2291},[2436],{"type":60,"value":2437},"\\\u002F\\\u002F",{"type":55,"tag":1762,"props":2439,"children":2440},{"style":2286},[2441],{"type":60,"value":2334},{"type":55,"tag":1762,"props":2443,"children":2444},{"style":2286},[2445],{"type":60,"value":2339},{"type":55,"tag":1762,"props":2447,"children":2449},{"class":2276,"line":2448},9,[2450,2454,2459,2463,2467],{"type":55,"tag":1762,"props":2451,"children":2452},{"style":2286},[2453],{"type":60,"value":2313},{"type":55,"tag":1762,"props":2455,"children":2456},{"style":2322},[2457],{"type":60,"value":2458},"moz-extension:",{"type":55,"tag":1762,"props":2460,"children":2461},{"style":2291},[2462],{"type":60,"value":2437},{"type":55,"tag":1762,"props":2464,"children":2465},{"style":2286},[2466],{"type":60,"value":2334},{"type":55,"tag":1762,"props":2468,"children":2469},{"style":2286},[2470],{"type":60,"value":2339},{"type":55,"tag":1762,"props":2472,"children":2474},{"class":2276,"line":2473},10,[2475,2480],{"type":55,"tag":1762,"props":2476,"children":2477},{"style":2291},[2478],{"type":60,"value":2479},"]",{"type":55,"tag":1762,"props":2481,"children":2482},{"style":2286},[2483],{"type":60,"value":2339},{"type":55,"tag":74,"props":2485,"children":2486},{},[2487,2489,2495,2497],{"type":60,"value":2488},"If 3rd party services were detected in Step 0g, silently add ",{"type":55,"tag":200,"props":2490,"children":2492},{"className":2491},[],[2493],{"type":60,"value":2494},"ignoreUrls",{"type":60,"value":2496}," to the faro init file for all detected services. Do NOT ask — apply all of them. Use this table to determine the domains:",{"type":55,"tag":1222,"props":2498,"children":2499},{},[2500,2515],{"type":55,"tag":1226,"props":2501,"children":2502},{},[2503],{"type":55,"tag":1230,"props":2504,"children":2505},{},[2506,2510],{"type":55,"tag":1234,"props":2507,"children":2508},{},[2509],{"type":60,"value":1243},{"type":55,"tag":1234,"props":2511,"children":2512},{},[2513],{"type":60,"value":2514},"Regex patterns to add",{"type":55,"tag":1245,"props":2516,"children":2517},{},[2518,2541,2564,2587,2610,2633,2656,2679,2695,2725,2748,2764,2787,2810,2827,2851,2875,2899,2916],{"type":55,"tag":1230,"props":2519,"children":2520},{},[2521,2525],{"type":55,"tag":1252,"props":2522,"children":2523},{},[2524],{"type":60,"value":1286},{"type":55,"tag":1252,"props":2526,"children":2527},{},[2528,2534,2535],{"type":55,"tag":200,"props":2529,"children":2531},{"className":2530},[],[2532],{"type":60,"value":2533},"\u002Fcdn\\.segment\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2536,"children":2538},{"className":2537},[],[2539],{"type":60,"value":2540},"\u002Fapi\\.segment\\.io\u002F",{"type":55,"tag":1230,"props":2542,"children":2543},{},[2544,2548],{"type":55,"tag":1252,"props":2545,"children":2546},{},[2547],{"type":60,"value":1317},{"type":55,"tag":1252,"props":2549,"children":2550},{},[2551,2557,2558],{"type":55,"tag":200,"props":2552,"children":2554},{"className":2553},[],[2555],{"type":60,"value":2556},"\u002Fapp\\.posthog\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2559,"children":2561},{"className":2560},[],[2562],{"type":60,"value":2563},"\u002Feu\\.posthog\\.com\u002F",{"type":55,"tag":1230,"props":2565,"children":2566},{},[2567,2571],{"type":55,"tag":1252,"props":2568,"children":2569},{},[2570],{"type":60,"value":1348},{"type":55,"tag":1252,"props":2572,"children":2573},{},[2574,2580,2581],{"type":55,"tag":200,"props":2575,"children":2577},{"className":2576},[],[2578],{"type":60,"value":2579},"\u002Fapi\\.mixpanel\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2582,"children":2584},{"className":2583},[],[2585],{"type":60,"value":2586},"\u002Fcdn\\.mxpnl\\.com\u002F",{"type":55,"tag":1230,"props":2588,"children":2589},{},[2590,2594],{"type":55,"tag":1252,"props":2591,"children":2592},{},[2593],{"type":60,"value":1386},{"type":55,"tag":1252,"props":2595,"children":2596},{},[2597,2603,2604],{"type":55,"tag":200,"props":2598,"children":2600},{"className":2599},[],[2601],{"type":60,"value":2602},"\u002Fapi2\\.amplitude\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2605,"children":2607},{"className":2606},[],[2608],{"type":60,"value":2609},"\u002Fcdn\\.amplitude\\.com\u002F",{"type":55,"tag":1230,"props":2611,"children":2612},{},[2613,2617],{"type":55,"tag":1252,"props":2614,"children":2615},{},[2616],{"type":60,"value":1417},{"type":55,"tag":1252,"props":2618,"children":2619},{},[2620,2626,2627],{"type":55,"tag":200,"props":2621,"children":2623},{"className":2622},[],[2624],{"type":60,"value":2625},"\u002Fstatic\\.hotjar\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2628,"children":2630},{"className":2629},[],[2631],{"type":60,"value":2632},"\u002Fscript\\.hotjar\\.com\u002F",{"type":55,"tag":1230,"props":2634,"children":2635},{},[2636,2640],{"type":55,"tag":1252,"props":2637,"children":2638},{},[2639],{"type":60,"value":1448},{"type":55,"tag":1252,"props":2641,"children":2642},{},[2643,2649,2650],{"type":55,"tag":200,"props":2644,"children":2646},{"className":2645},[],[2647],{"type":60,"value":2648},"\u002Ffullstory\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2651,"children":2653},{"className":2652},[],[2654],{"type":60,"value":2655},"\u002Frs\\.fullstory\\.com\u002F",{"type":55,"tag":1230,"props":2657,"children":2658},{},[2659,2663],{"type":55,"tag":1252,"props":2660,"children":2661},{},[2662],{"type":60,"value":1479},{"type":55,"tag":1252,"props":2664,"children":2665},{},[2666,2672,2673],{"type":55,"tag":200,"props":2667,"children":2669},{"className":2668},[],[2670],{"type":60,"value":2671},"\u002Fwidget\\.intercom\\.io\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2674,"children":2676},{"className":2675},[],[2677],{"type":60,"value":2678},"\u002Fapi-iam\\.intercom\\.io\u002F",{"type":55,"tag":1230,"props":2680,"children":2681},{},[2682,2686],{"type":55,"tag":1252,"props":2683,"children":2684},{},[2685],{"type":60,"value":1503},{"type":55,"tag":1252,"props":2687,"children":2688},{},[2689],{"type":55,"tag":200,"props":2690,"children":2692},{"className":2691},[],[2693],{"type":60,"value":2694},"\u002Fbrowser-intake-datadoghq\\.com\u002F",{"type":55,"tag":1230,"props":2696,"children":2697},{},[2698,2702],{"type":55,"tag":1252,"props":2699,"children":2700},{},[2701],{"type":60,"value":1555},{"type":55,"tag":1252,"props":2703,"children":2704},{},[2705,2711,2712,2718,2719],{"type":55,"tag":200,"props":2706,"children":2708},{"className":2707},[],[2709],{"type":60,"value":2710},"\u002Fgoogletagmanager\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2713,"children":2715},{"className":2714},[],[2716],{"type":60,"value":2717},"\u002Fanalytics\\.google\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2720,"children":2722},{"className":2721},[],[2723],{"type":60,"value":2724},"\u002Fwww\\.google-analytics\\.com\u002F",{"type":55,"tag":1230,"props":2726,"children":2727},{},[2728,2732],{"type":55,"tag":1252,"props":2729,"children":2730},{},[2731],{"type":60,"value":1586},{"type":55,"tag":1252,"props":2733,"children":2734},{},[2735,2741,2742],{"type":55,"tag":200,"props":2736,"children":2738},{"className":2737},[],[2739],{"type":60,"value":2740},"\u002Fjs\\.driftt\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2743,"children":2745},{"className":2744},[],[2746],{"type":60,"value":2747},"\u002Fapi\\.drift\\.com\u002F",{"type":55,"tag":1230,"props":2749,"children":2750},{},[2751,2755],{"type":55,"tag":1252,"props":2752,"children":2753},{},[2754],{"type":60,"value":1610},{"type":55,"tag":1252,"props":2756,"children":2757},{},[2758],{"type":55,"tag":200,"props":2759,"children":2761},{"className":2760},[],[2762],{"type":60,"value":2763},"\u002Fclient\\.crisp\\.chat\u002F",{"type":55,"tag":1230,"props":2765,"children":2766},{},[2767,2771],{"type":55,"tag":1252,"props":2768,"children":2769},{},[2770],{"type":60,"value":1641},{"type":55,"tag":1252,"props":2772,"children":2773},{},[2774,2780,2781],{"type":55,"tag":200,"props":2775,"children":2777},{"className":2776},[],[2778],{"type":60,"value":2779},"\u002Fcdn\\.logrocket\\.io\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2782,"children":2784},{"className":2783},[],[2785],{"type":60,"value":2786},"\u002Fr\\.lr-ingest\\.io\u002F",{"type":55,"tag":1230,"props":2788,"children":2789},{},[2790,2794],{"type":55,"tag":1252,"props":2791,"children":2792},{},[2793],{"type":60,"value":1665},{"type":55,"tag":1252,"props":2795,"children":2796},{},[2797,2803,2804],{"type":55,"tag":200,"props":2798,"children":2800},{"className":2799},[],[2801],{"type":60,"value":2802},"\u002Fconnect\\.facebook\\.net\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2805,"children":2807},{"className":2806},[],[2808],{"type":60,"value":2809},"\u002Ffacebook\\.com\\\u002Ftr\u002F",{"type":55,"tag":1230,"props":2811,"children":2812},{},[2813,2818],{"type":55,"tag":1252,"props":2814,"children":2815},{},[2816],{"type":60,"value":2817},"Microsoft Clarity",{"type":55,"tag":1252,"props":2819,"children":2820},{},[2821],{"type":55,"tag":200,"props":2822,"children":2824},{"className":2823},[],[2825],{"type":60,"value":2826},"\u002Fclarity\\.ms\u002F",{"type":55,"tag":1230,"props":2828,"children":2829},{},[2830,2835],{"type":55,"tag":1252,"props":2831,"children":2832},{},[2833],{"type":60,"value":2834},"Pendo",{"type":55,"tag":1252,"props":2836,"children":2837},{},[2838,2844,2845],{"type":55,"tag":200,"props":2839,"children":2841},{"className":2840},[],[2842],{"type":60,"value":2843},"\u002Fcdn\\.pendo\\.io\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2846,"children":2848},{"className":2847},[],[2849],{"type":60,"value":2850},"\u002Fapp\\.pendo\\.io\u002F",{"type":55,"tag":1230,"props":2852,"children":2853},{},[2854,2859],{"type":55,"tag":1252,"props":2855,"children":2856},{},[2857],{"type":60,"value":2858},"Heap",{"type":55,"tag":1252,"props":2860,"children":2861},{},[2862,2868,2869],{"type":55,"tag":200,"props":2863,"children":2865},{"className":2864},[],[2866],{"type":60,"value":2867},"\u002Fcdn\\.heapanalytics\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2870,"children":2872},{"className":2871},[],[2873],{"type":60,"value":2874},"\u002Fheapanalytics\\.com\u002F",{"type":55,"tag":1230,"props":2876,"children":2877},{},[2878,2883],{"type":55,"tag":1252,"props":2879,"children":2880},{},[2881],{"type":60,"value":2882},"Rudderstack",{"type":55,"tag":1252,"props":2884,"children":2885},{},[2886,2892,2893],{"type":55,"tag":200,"props":2887,"children":2889},{"className":2888},[],[2890],{"type":60,"value":2891},"\u002Fcdn\\.rudderlabs\\.com\u002F",{"type":60,"value":561},{"type":55,"tag":200,"props":2894,"children":2896},{"className":2895},[],[2897],{"type":60,"value":2898},"\u002Fapi\\.rudderstack\\.com\u002F",{"type":55,"tag":1230,"props":2900,"children":2901},{},[2902,2907],{"type":55,"tag":1252,"props":2903,"children":2904},{},[2905],{"type":60,"value":2906},"Plausible",{"type":55,"tag":1252,"props":2908,"children":2909},{},[2910],{"type":55,"tag":200,"props":2911,"children":2913},{"className":2912},[],[2914],{"type":60,"value":2915},"\u002Fplausible\\.io\u002F",{"type":55,"tag":1230,"props":2917,"children":2918},{},[2919,2924],{"type":55,"tag":1252,"props":2920,"children":2921},{},[2922],{"type":60,"value":2923},"Fathom",{"type":55,"tag":1252,"props":2925,"children":2926},{},[2927],{"type":55,"tag":200,"props":2928,"children":2930},{"className":2929},[],[2931],{"type":60,"value":2932},"\u002Fcdn\\.usefathom\\.com\u002F",{"type":55,"tag":74,"props":2934,"children":2935},{},[2936,2938],{"type":60,"value":2937},"Confirm what was done with a short ✅ summary:",{"type":55,"tag":759,"props":2939,"children":2940},{},[2941,2946],{"type":55,"tag":56,"props":2942,"children":2943},{},[2944],{"type":60,"value":2945},"✅ Done! Here's what was set up:",{"type":55,"tag":70,"props":2947,"children":2948},{},[2949,2960,2971,2982],{"type":55,"tag":74,"props":2950,"children":2951},{},[2952,2954],{"type":60,"value":2953},"Installed: ",{"type":55,"tag":200,"props":2955,"children":2957},{"className":2956},[],[2958],{"type":60,"value":2959},"[packages]",{"type":55,"tag":74,"props":2961,"children":2962},{},[2963,2965],{"type":60,"value":2964},"Created: ",{"type":55,"tag":200,"props":2966,"children":2968},{"className":2967},[],[2969],{"type":60,"value":2970},"[faro init file path]",{"type":55,"tag":74,"props":2972,"children":2973},{},[2974,2976],{"type":60,"value":2975},"Wired: first import in ",{"type":55,"tag":200,"props":2977,"children":2979},{"className":2978},[],[2980],{"type":60,"value":2981},"[entry point]",{"type":55,"tag":74,"props":2983,"children":2984},{},[2985,2987,2992,2994,2999,3001,3006,3008,3014],{"type":60,"value":2986},"Filtered harmless browser errors (ResizeObserver, Script error, extension noise)\n",{"type":55,"tag":1762,"props":2988,"children":2989},{},[2990],{"type":60,"value":2991},"if services detected:",{"type":60,"value":2993}," - Excluded from network tracking: ",{"type":55,"tag":1762,"props":2995,"children":2996},{},[2997],{"type":60,"value":2998},"service names",{"type":60,"value":3000}," — auto-detected in your project\n",{"type":55,"tag":1762,"props":3002,"children":3003},{},[3004],{"type":60,"value":3005},"if no router detected:",{"type":60,"value":3007}," - Auto-navigation tracking enabled (",{"type":55,"tag":200,"props":3009,"children":3011},{"className":3010},[],[3012],{"type":60,"value":3013},"experimental.trackNavigation",{"type":60,"value":3015},") — no router found",{"type":55,"tag":74,"props":3017,"children":3018},{},[3019,3021,3026,3028],{"type":60,"value":3020},"Ask the user to do a quick sanity check ",{"type":55,"tag":78,"props":3022,"children":3023},{},[3024],{"type":60,"value":3025},"before",{"type":60,"value":3027}," adding anything else (this is an early check — a final pre-PR verification happens in Step 5):",{"type":55,"tag":759,"props":3029,"children":3030},{},[3031,3049],{"type":55,"tag":56,"props":3032,"children":3033},{},[3034,3039,3041,3047],{"type":55,"tag":78,"props":3035,"children":3036},{},[3037],{"type":60,"value":3038},"One quick check",{"type":60,"value":3040}," — start your app and open DevTools → Network. Filter by ",{"type":55,"tag":200,"props":3042,"children":3044},{"className":3043},[],[3045],{"type":60,"value":3046},"collect",{"type":60,"value":3048},". You should see POST requests to your collector within a few seconds.",{"type":55,"tag":56,"props":3050,"children":3051},{},[3052,3054,3058,3060,3065],{"type":60,"value":3053},"Seeing them? ",{"type":55,"tag":78,"props":3055,"children":3056},{},[3057],{"type":60,"value":2095},{"type":60,"value":3059}," to continue, ",{"type":55,"tag":78,"props":3061,"children":3062},{},[3063],{"type":60,"value":3064},"n",{"type":60,"value":3066}," if not and I'll help debug.",{"type":55,"tag":74,"props":3068,"children":3069},{},[3070,3071,3075],{"type":60,"value":805},{"type":55,"tag":78,"props":3072,"children":3073},{},[3074],{"type":60,"value":3064},{"type":60,"value":3076},": run through the debug checklist in Step 5. Do not move forward until data is confirmed flowing.",{"type":55,"tag":74,"props":3078,"children":3079},{},[3080,3081,3085,3087],{"type":60,"value":805},{"type":55,"tag":78,"props":3082,"children":3083},{},[3084],{"type":60,"value":2095},{"type":60,"value":3086},": present the fork:",{"type":55,"tag":759,"props":3088,"children":3089},{},[3090,3095],{"type":55,"tag":56,"props":3091,"children":3092},{},[3093],{"type":60,"value":3094},"Faro is running. Want to go through a quick optional setup, or open the PR now?",{"type":55,"tag":70,"props":3096,"children":3097},{},[3098,3107],{"type":55,"tag":74,"props":3099,"children":3100},{},[3101,3105],{"type":55,"tag":78,"props":3102,"children":3103},{},[3104],{"type":60,"value":2095},{"type":60,"value":3106}," — I'll suggest a few things based on your project",{"type":55,"tag":74,"props":3108,"children":3109},{},[3110,3115],{"type":55,"tag":78,"props":3111,"children":3112},{},[3113],{"type":60,"value":3114},"n \u002F PR",{"type":60,"value":3116}," — skip straight to the PR",{"type":55,"tag":277,"props":3118,"children":3119},{},[],{"type":55,"tag":281,"props":3121,"children":3123},{"id":3122},"step-4-optional-setup",[3124],{"type":60,"value":3125},"Step 4: Optional setup",{"type":55,"tag":56,"props":3127,"children":3128},{},[3129,3131,3135],{"type":60,"value":3130},"If the user said ",{"type":55,"tag":78,"props":3132,"children":3133},{},[3134],{"type":60,"value":3114},{"type":60,"value":3136}," at the fork in Step 3: go directly to Step 5.",{"type":55,"tag":56,"props":3138,"children":3139},{},[3140,3141,3145],{"type":60,"value":3130},{"type":55,"tag":78,"props":3142,"children":3143},{},[3144],{"type":60,"value":2095},{"type":60,"value":1683},{"type":55,"tag":63,"props":3147,"children":3149},{"id":3148},"_4-1-present-the-setup-menu",[3150],{"type":60,"value":3151},"4-1. Present the setup menu",{"type":55,"tag":56,"props":3153,"children":3154},{},[3155,3157,3162],{"type":60,"value":3156},"Show a ",{"type":55,"tag":78,"props":3158,"children":3159},{},[3160],{"type":60,"value":3161},"single message",{"type":60,"value":3163}," with all options:",{"type":55,"tag":759,"props":3165,"children":3166},{},[3167,3179],{"type":55,"tag":56,"props":3168,"children":3169},{},[3170,3172,3177],{"type":60,"value":3171},"Here's what else I can set up — pick any numbers, or say ",{"type":55,"tag":78,"props":3173,"children":3174},{},[3175],{"type":60,"value":3176},"PR",{"type":60,"value":3178}," to skip all:",{"type":55,"tag":768,"props":3180,"children":3181},{},[3182,3203,3213],{"type":55,"tag":74,"props":3183,"children":3184},{},[3185,3190,3192,3197,3198],{"type":55,"tag":78,"props":3186,"children":3187},{},[3188],{"type":60,"value":3189},"Route tracking",{"type":60,"value":3191}," — ",{"type":55,"tag":1762,"props":3193,"children":3194},{},[3195],{"type":60,"value":3196},"if router detected: route patterns + view grouping",{"type":60,"value":198},{"type":55,"tag":1762,"props":3199,"children":3200},{},[3201],{"type":60,"value":3202},"if no router: one-flag auto-navigation",{"type":55,"tag":74,"props":3204,"children":3205},{},[3206,3211],{"type":55,"tag":78,"props":3207,"children":3208},{},[3209],{"type":60,"value":3210},"User identity",{"type":60,"value":3212}," — tag errors and sessions with who's logged in",{"type":55,"tag":74,"props":3214,"children":3215},{},[3216,3221],{"type":55,"tag":78,"props":3217,"children":3218},{},[3219],{"type":60,"value":3220},"More",{"type":60,"value":3222}," — error boundary, cookie consent, cross-origin tracing, session settings, disable console capture, disable tracing",{"type":55,"tag":63,"props":3224,"children":3226},{"id":3225},"_4-2-handle-picks",[3227],{"type":60,"value":3228},"4-2. Handle picks",{"type":55,"tag":56,"props":3230,"children":3231},{},[3232],{"type":60,"value":3233},"Handle one picked item at a time. After each, ask:",{"type":55,"tag":759,"props":3235,"children":3236},{},[3237],{"type":55,"tag":56,"props":3238,"children":3239},{},[3240],{"type":60,"value":3241},"✅ Done. Anything else from the list, or should I open the PR?",{"type":55,"tag":56,"props":3243,"children":3244},{},[3245,3250,3252,3258],{"type":55,"tag":78,"props":3246,"children":3247},{},[3248],{"type":60,"value":3249},"1 — Route tracking",{"type":60,"value":3251}," → Read ",{"type":55,"tag":200,"props":3253,"children":3255},{"className":3254},[],[3256],{"type":60,"value":3257},"advanced.md",{"type":60,"value":3259}," section B.",{"type":55,"tag":70,"props":3261,"children":3262},{},[3263,3276],{"type":55,"tag":74,"props":3264,"children":3265},{},[3266,3268,3274],{"type":60,"value":3267},"Router detected: offer router integration (gives route patterns like ",{"type":55,"tag":200,"props":3269,"children":3271},{"className":3270},[],[3272],{"type":60,"value":3273},"\u002Fusers\u002F:id",{"type":60,"value":3275},").",{"type":55,"tag":74,"props":3277,"children":3278},{},[3279,3281,3370],{"type":60,"value":3280},"No router: enable auto-navigation with one flag:\n",{"type":55,"tag":2264,"props":3282,"children":3284},{"className":2266,"code":3283,"language":2268,"meta":2269,"style":2269},"initializeFaro({\n  \u002F\u002F ... existing config ...\n  experimental: { trackNavigation: true },\n});\n",[3285],{"type":55,"tag":200,"props":3286,"children":3287},{"__ignoreMap":2269},[3288,3306,3314,3352],{"type":55,"tag":1762,"props":3289,"children":3290},{"class":2276,"line":2277},[3291,3296,3301],{"type":55,"tag":1762,"props":3292,"children":3294},{"style":3293},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[3295],{"type":60,"value":818},{"type":55,"tag":1762,"props":3297,"children":3298},{"style":2291},[3299],{"type":60,"value":3300},"(",{"type":55,"tag":1762,"props":3302,"children":3303},{"style":2286},[3304],{"type":60,"value":3305},"{\n",{"type":55,"tag":1762,"props":3307,"children":3308},{"class":2276,"line":2297},[3309],{"type":55,"tag":1762,"props":3310,"children":3311},{"style":2301},[3312],{"type":60,"value":3313},"  \u002F\u002F ... existing config ...\n",{"type":55,"tag":1762,"props":3315,"children":3316},{"class":2276,"line":2307},[3317,3323,3327,3332,3337,3341,3347],{"type":55,"tag":1762,"props":3318,"children":3320},{"style":3319},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[3321],{"type":60,"value":3322},"  experimental",{"type":55,"tag":1762,"props":3324,"children":3325},{"style":2286},[3326],{"type":60,"value":1683},{"type":55,"tag":1762,"props":3328,"children":3329},{"style":2286},[3330],{"type":60,"value":3331}," {",{"type":55,"tag":1762,"props":3333,"children":3334},{"style":3319},[3335],{"type":60,"value":3336}," trackNavigation",{"type":55,"tag":1762,"props":3338,"children":3339},{"style":2286},[3340],{"type":60,"value":1683},{"type":55,"tag":1762,"props":3342,"children":3344},{"style":3343},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[3345],{"type":60,"value":3346}," true",{"type":55,"tag":1762,"props":3348,"children":3349},{"style":2286},[3350],{"type":60,"value":3351}," },\n",{"type":55,"tag":1762,"props":3353,"children":3354},{"class":2276,"line":2342},[3355,3360,3365],{"type":55,"tag":1762,"props":3356,"children":3357},{"style":2286},[3358],{"type":60,"value":3359},"}",{"type":55,"tag":1762,"props":3361,"children":3362},{"style":2291},[3363],{"type":60,"value":3364},")",{"type":55,"tag":1762,"props":3366,"children":3367},{"style":2286},[3368],{"type":60,"value":3369},";\n",{"type":60,"value":3371},"\nNote to user: captures actual URLs, not route patterns. Upgrade to router integration (advanced.md section B) when a router is added.",{"type":55,"tag":56,"props":3373,"children":3374},{},[3375,3380,3381,3386],{"type":55,"tag":78,"props":3376,"children":3377},{},[3378],{"type":60,"value":3379},"2 — User identity",{"type":60,"value":3251},{"type":55,"tag":200,"props":3382,"children":3384},{"className":3383},[],[3385],{"type":60,"value":3257},{"type":60,"value":3387}," section K.",{"type":55,"tag":56,"props":3389,"children":3390},{},[3391,3396],{"type":55,"tag":78,"props":3392,"children":3393},{},[3394],{"type":60,"value":3395},"3 — More",{"type":60,"value":3397}," → show the expanded advanced menu:",{"type":55,"tag":759,"props":3399,"children":3400},{},[3401,3406],{"type":55,"tag":56,"props":3402,"children":3403},{},[3404],{"type":60,"value":3405},"Which of these? (pick numbers, or say PR)",{"type":55,"tag":768,"props":3407,"children":3408},{},[3409,3414,3419,3424,3429,3434,3439,3444],{"type":55,"tag":74,"props":3410,"children":3411},{},[3412],{"type":60,"value":3413},"Error boundary — catch component crashes (React only) (→ advanced.md section C)",{"type":55,"tag":74,"props":3415,"children":3416},{},[3417],{"type":60,"value":3418},"Cookie consent gate — delay tracking until consent accepted (→ advanced.md section G)",{"type":55,"tag":74,"props":3420,"children":3421},{},[3422],{"type":60,"value":3423},"Cross-origin tracing — trace headers for API calls on other domains (→ advanced.md section A)",{"type":55,"tag":74,"props":3425,"children":3426},{},[3427],{"type":60,"value":3428},"Session settings — persistence, inactivity timeout (→ advanced.md section F)",{"type":55,"tag":74,"props":3430,"children":3431},{},[3432],{"type":60,"value":3433},"Disable console log capture (→ advanced.md section L)",{"type":55,"tag":74,"props":3435,"children":3436},{},[3437],{"type":60,"value":3438},"Disable distributed tracing (→ advanced.md section M)",{"type":55,"tag":74,"props":3440,"children":3441},{},[3442],{"type":60,"value":3443},"Exclude additional errors — suppress app-specific error patterns (→ advanced.md section D)",{"type":55,"tag":74,"props":3445,"children":3446},{},[3447,3449,3454,3456,3461,3463,3467],{"type":60,"value":3448},"Exclude additional URLs — suppress more network domains (→ advanced.md section E)\n",{"type":55,"tag":1762,"props":3450,"children":3451},{},[3452],{"type":60,"value":3453},"if detected:",{"type":60,"value":3455}," ⭐ Microfrontend coordination — found ",{"type":55,"tag":1762,"props":3457,"children":3458},{},[3459],{"type":60,"value":3460},"framework",{"type":60,"value":3462}," (→ advanced.md section J)\n",{"type":55,"tag":1762,"props":3464,"children":3465},{},[3466],{"type":60,"value":3453},{"type":60,"value":3468}," ⭐ iFrame guidance — found cross-frame patterns (→ advanced.md section I)",{"type":55,"tag":56,"props":3470,"children":3471},{},[3472,3474,3479],{"type":60,"value":3473},"When the user picks an option from the More menu, read ",{"type":55,"tag":200,"props":3475,"children":3477},{"className":3476},[],[3478],{"type":60,"value":3257},{"type":60,"value":3480}," and apply the matching section.",{"type":55,"tag":56,"props":3482,"children":3483},{},[3484,3489],{"type":55,"tag":78,"props":3485,"children":3486},{},[3487],{"type":60,"value":3488},"Session sampling rate:",{"type":60,"value":3490}," Do NOT surface proactively. Only raise it if the user mentions high traffic or picks \"Session settings\". 100% is correct for most apps.",{"type":55,"tag":277,"props":3492,"children":3493},{},[],{"type":55,"tag":281,"props":3495,"children":3497},{"id":3496},"step-5-verify-before-pr",[3498],{"type":60,"value":3499},"Step 5: Verify before PR",{"type":55,"tag":56,"props":3501,"children":3502},{},[3503],{"type":60,"value":3504},"Before creating the PR, do a final end-to-end verification (separate from the early sanity check in Step 3). This confirms the full setup — including any router, user identity, or noise config added in Step 4 — is working correctly:",{"type":55,"tag":759,"props":3506,"children":3507},{},[3508,3513,3560],{"type":55,"tag":56,"props":3509,"children":3510},{},[3511],{"type":60,"value":3512},"All changes are ready. Before I open the PR, run the app locally and verify Faro is sending data:",{"type":55,"tag":768,"props":3514,"children":3515},{},[3516,3527,3537,3555],{"type":55,"tag":74,"props":3517,"children":3518},{},[3519,3525],{"type":55,"tag":200,"props":3520,"children":3522},{"className":3521},[],[3523],{"type":60,"value":3524},"[start command]",{"type":60,"value":3526}," — run your app as usual",{"type":55,"tag":74,"props":3528,"children":3529},{},[3530,3532],{"type":60,"value":3531},"Open ",{"type":55,"tag":78,"props":3533,"children":3534},{},[3535],{"type":60,"value":3536},"DevTools → Network tab",{"type":55,"tag":74,"props":3538,"children":3539},{},[3540,3542,3547,3549],{"type":60,"value":3541},"Filter by ",{"type":55,"tag":200,"props":3543,"children":3545},{"className":3544},[],[3546],{"type":60,"value":3046},{"type":60,"value":3548}," — you should see POST requests to ",{"type":55,"tag":200,"props":3550,"children":3552},{"className":3551},[],[3553],{"type":60,"value":3554},"[COLLECTOR_URL]",{"type":55,"tag":74,"props":3556,"children":3557},{},[3558],{"type":60,"value":3559},"Trigger a page navigation, click, or console.log — the request payload should update",{"type":55,"tag":56,"props":3561,"children":3562},{},[3563,3565,3570,3572,3577],{"type":60,"value":3564},"Seeing requests? Type ",{"type":55,"tag":78,"props":3566,"children":3567},{},[3568],{"type":60,"value":3569},"yes",{"type":60,"value":3571}," to proceed with the PR. Not seeing them? Type ",{"type":55,"tag":78,"props":3573,"children":3574},{},[3575],{"type":60,"value":3576},"no",{"type":60,"value":3578}," and I'll help debug.",{"type":55,"tag":56,"props":3580,"children":3581},{},[3582,3584,3588],{"type":60,"value":3583},"If the user says ",{"type":55,"tag":78,"props":3585,"children":3586},{},[3587],{"type":60,"value":3576},{"type":60,"value":3589},", run through the most common issues:",{"type":55,"tag":70,"props":3591,"children":3592},{},[3593,3605,3618,3623],{"type":55,"tag":74,"props":3594,"children":3595},{},[3596,3598,3603],{"type":60,"value":3597},"Is the Faro import the ",{"type":55,"tag":78,"props":3599,"children":3600},{},[3601],{"type":60,"value":3602},"first",{"type":60,"value":3604}," import in the entry point? (Re-check the entry point file.)",{"type":55,"tag":74,"props":3606,"children":3607},{},[3608,3610,3616],{"type":60,"value":3609},"Is the collector URL correct? (Log ",{"type":55,"tag":200,"props":3611,"children":3613},{"className":3612},[],[3614],{"type":60,"value":3615},"faro.config?.url",{"type":60,"value":3617}," in the browser console.)",{"type":55,"tag":74,"props":3619,"children":3620},{},[3621],{"type":60,"value":3622},"Any Content Security Policy errors in the DevTools console blocking the request?",{"type":55,"tag":74,"props":3624,"children":3625},{},[3626,3628,3634,3636,3641],{"type":60,"value":3627},"For Next.js: is ",{"type":55,"tag":200,"props":3629,"children":3631},{"className":3630},[],[3632],{"type":60,"value":3633},"NEXT_PUBLIC_FARO_URL",{"type":60,"value":3635}," set in ",{"type":55,"tag":200,"props":3637,"children":3639},{"className":3638},[],[3640],{"type":60,"value":255},{"type":60,"value":3642}," and the dev server restarted?",{"type":55,"tag":56,"props":3644,"children":3645},{},[3646],{"type":60,"value":3647},"Do not proceed to Step 6 until the user confirms data is flowing.",{"type":55,"tag":277,"props":3649,"children":3650},{},[],{"type":55,"tag":281,"props":3652,"children":3654},{"id":3653},"step-6-create-a-pr",[3655],{"type":60,"value":3656},"Step 6: Create a PR",{"type":55,"tag":56,"props":3658,"children":3659},{},[3660],{"type":60,"value":3661},"After all code changes are done, ask:",{"type":55,"tag":759,"props":3663,"children":3664},{},[3665,3670],{"type":55,"tag":56,"props":3666,"children":3667},{},[3668],{"type":60,"value":3669},"All changes are committed and ready. Should I open the PR for you, or would you prefer to do it yourself?",{"type":55,"tag":70,"props":3671,"children":3672},{},[3673,3689],{"type":55,"tag":74,"props":3674,"children":3675},{},[3676,3681,3683],{"type":55,"tag":78,"props":3677,"children":3678},{},[3679],{"type":60,"value":3680},"y \u002F open it",{"type":60,"value":3682}," — I'll create the branch, commit, push, and open the PR via ",{"type":55,"tag":200,"props":3684,"children":3686},{"className":3685},[],[3687],{"type":60,"value":3688},"gh",{"type":55,"tag":74,"props":3690,"children":3691},{},[3692,3697],{"type":55,"tag":78,"props":3693,"children":3694},{},[3695],{"type":60,"value":3696},"n \u002F I'll do it",{"type":60,"value":3698}," — I'll show you the commands to run",{"type":55,"tag":56,"props":3700,"children":3701},{},[3702,3704,3708],{"type":60,"value":3703},"If the user chooses ",{"type":55,"tag":78,"props":3705,"children":3706},{},[3707],{"type":60,"value":3696},{"type":60,"value":3709},", show the commands below and stop.",{"type":55,"tag":56,"props":3711,"children":3712},{},[3713,3714,3718],{"type":60,"value":3703},{"type":55,"tag":78,"props":3715,"children":3716},{},[3717],{"type":60,"value":3680},{"type":60,"value":3719},", run the steps below.",{"type":55,"tag":277,"props":3721,"children":3722},{},[],{"type":55,"tag":768,"props":3724,"children":3725},{},[3726,3741,3820,3834],{"type":55,"tag":74,"props":3727,"children":3728},{},[3729,3731],{"type":60,"value":3730},"Create a new branch:",{"type":55,"tag":2264,"props":3732,"children":3736},{"className":3733,"code":3735,"language":60},[3734],"language-text","git checkout -b feat\u002Fadd-faro-instrumentation\n",[3737],{"type":55,"tag":200,"props":3738,"children":3739},{"__ignoreMap":2269},[3740],{"type":60,"value":3735},{"type":55,"tag":74,"props":3742,"children":3743},{},[3744,3746,3752,3753,3759,3761],{"type":60,"value":3745},"Stage all modified and new files. Be specific — don't use ",{"type":55,"tag":200,"props":3747,"children":3749},{"className":3748},[],[3750],{"type":60,"value":3751},"git add .",{"type":60,"value":356},{"type":55,"tag":200,"props":3754,"children":3756},{"className":3755},[],[3757],{"type":60,"value":3758},"git add -A",{"type":60,"value":3760},". Stage only:",{"type":55,"tag":70,"props":3762,"children":3763},{},[3764,3783,3788,3793,3803],{"type":55,"tag":74,"props":3765,"children":3766},{},[3767,3769,3774,3775,3781],{"type":60,"value":3768},"The Faro init file (",{"type":55,"tag":200,"props":3770,"children":3772},{"className":3771},[],[3773],{"type":60,"value":273},{"type":60,"value":561},{"type":55,"tag":200,"props":3776,"children":3778},{"className":3777},[],[3779],{"type":60,"value":3780},"components\u002FFrontendObservability.tsx",{"type":60,"value":3782},", etc.)",{"type":55,"tag":74,"props":3784,"children":3785},{},[3786],{"type":60,"value":3787},"The modified entry point",{"type":55,"tag":74,"props":3789,"children":3790},{},[3791],{"type":60,"value":3792},"Any additional files created (error handler, etc.)",{"type":55,"tag":74,"props":3794,"children":3795},{},[3796,3801],{"type":55,"tag":200,"props":3797,"children":3799},{"className":3798},[],[3800],{"type":60,"value":302},{"type":60,"value":3802}," and the lock file (if packages were installed)",{"type":55,"tag":74,"props":3804,"children":3805},{},[3806,3811,3812,3818],{"type":55,"tag":200,"props":3807,"children":3809},{"className":3808},[],[3810],{"type":60,"value":255},{"type":60,"value":356},{"type":55,"tag":200,"props":3813,"children":3815},{"className":3814},[],[3816],{"type":60,"value":3817},".env.example",{"type":60,"value":3819}," (if created\u002Fmodified, and ONLY if they don't contain secrets)",{"type":55,"tag":74,"props":3821,"children":3822},{},[3823,3825],{"type":60,"value":3824},"Commit:",{"type":55,"tag":2264,"props":3826,"children":3829},{"className":3827,"code":3828,"language":60},[3734],"git commit -m \"feat: add Grafana Faro Web SDK instrumentation\"\n",[3830],{"type":55,"tag":200,"props":3831,"children":3832},{"__ignoreMap":2269},[3833],{"type":60,"value":3828},{"type":55,"tag":74,"props":3835,"children":3836},{},[3837,3839],{"type":60,"value":3838},"Push and create PR:",{"type":55,"tag":2264,"props":3840,"children":3843},{"className":3841,"code":3842,"language":60},[3734],"git push -u origin feat\u002Fadd-faro-instrumentation\ngh pr create --title \"feat: add Grafana Faro Web SDK instrumentation\" --body \"$(cat \u003C\u003C'EOF'\n## Summary\n- Added [Grafana Faro Web SDK](https:\u002F\u002Fgithub.com\u002Fgrafana\u002Ffaro-web-sdk) for frontend observability\n- Framework: [FRAMEWORK]\n- Packages: [LIST PACKAGES INSTALLED]\n- Init file: `[PATH TO FARO INIT FILE]`\n- Entry point modified: `[PATH TO ENTRY POINT]`\n[- Tracing: enabled (if applicable)]\n[- Router instrumentation: enabled (if applicable)]\n[- Error boundary: enabled (if applicable)]\n\n## How to verify\n1. Run the app locally\n2. Open browser DevTools → Network tab\n3. Look for POST requests to the Faro collector URL\n4. Check the Grafana Cloud Frontend Observability dashboard for incoming data\n\n## Links\n- [Grafana Faro Web SDK docs](https:\u002F\u002Fgrafana.com\u002Fdocs\u002Fgrafana-cloud\u002Fmonitor-applications\u002Ffrontend-observability\u002F)\n- [Faro Web SDK GitHub](https:\u002F\u002Fgithub.com\u002Fgrafana\u002Ffaro-web-sdk)\nEOF\n)\"\n",[3844],{"type":55,"tag":200,"props":3845,"children":3846},{"__ignoreMap":2269},[3847],{"type":60,"value":3842},{"type":55,"tag":56,"props":3849,"children":3850},{},[3851,3852,3857],{"type":60,"value":805},{"type":55,"tag":200,"props":3853,"children":3855},{"className":3854},[],[3856],{"type":60,"value":3688},{"type":60,"value":3858}," is not available or the push fails, show the user the commands to run manually.",{"type":55,"tag":277,"props":3860,"children":3861},{},[],{"type":55,"tag":281,"props":3863,"children":3865},{"id":3864},"step-7-observability-roadmap",[3866],{"type":60,"value":3867},"Step 7: Observability roadmap",{"type":55,"tag":56,"props":3869,"children":3870},{},[3871],{"type":60,"value":3872},"After the PR is open, show a summary of what's active and what can be added next.",{"type":55,"tag":56,"props":3874,"children":3875},{},[3876],{"type":60,"value":3877},"Generate the checklist dynamically based on what was configured:",{"type":55,"tag":759,"props":3879,"children":3880},{},[3881,3889,3954,3962,3980,3997,4017,4028],{"type":55,"tag":56,"props":3882,"children":3883},{},[3884],{"type":55,"tag":78,"props":3885,"children":3886},{},[3887],{"type":60,"value":3888},"Your Faro setup is ready. Here's what's enabled:",{"type":55,"tag":56,"props":3890,"children":3891},{},[3892,3894,3900,3902,3907,3912,3917,3929,3934,3939,3944,3949],{"type":60,"value":3893},"✅ JavaScript error capture (automatic — errors, unhandled rejections, thrown exceptions)\n✅ Core Web Vitals — LCP, FID\u002FINP, CLS (automatic via ",{"type":55,"tag":200,"props":3895,"children":3897},{"className":3896},[],[3898],{"type":60,"value":3899},"getWebInstrumentations()",{"type":60,"value":3901},")\n✅ Network request tracking — fetch and XHR timing and status codes\n",{"type":55,"tag":1762,"props":3903,"children":3904},{},[3905],{"type":60,"value":3906},"✅ Console log capture — OR — ❌ Console log capture disabled (captureConsole: false)",{"type":55,"tag":1762,"props":3908,"children":3909},{},[3910],{"type":60,"value":3911},"✅ Distributed tracing — same-origin automatic; cross-origin if configured in advanced.md section A",{"type":55,"tag":1762,"props":3913,"children":3914},{},[3915],{"type":60,"value":3916},"✅ Session tracking: persistent — OR — ✅ Session tracking: default (per-tab)",{"type":55,"tag":1762,"props":3918,"children":3919},{},[3920,3922,3927],{"type":60,"value":3921},"✅ ",{"type":55,"tag":1762,"props":3923,"children":3924},{},[3925],{"type":60,"value":3926},"N",{"type":60,"value":3928},"% session sampling — OR — ✅ Session sampling: 100% (all sessions)",{"type":55,"tag":1762,"props":3930,"children":3931},{},[3932],{"type":60,"value":3933},"✅ User identity — set on load OR set dynamically after login — OR — ☐ User identity: not configured",{"type":55,"tag":1762,"props":3935,"children":3936},{},[3937],{"type":60,"value":3938},"✅ Navigation \u002F route tracking — OR — ☐ Navigation tracking: not configured",{"type":55,"tag":1762,"props":3940,"children":3941},{},[3942],{"type":60,"value":3943},"✅ React Error Boundary — OR — (omit for non-React)",{"type":55,"tag":1762,"props":3945,"children":3946},{},[3947],{"type":60,"value":3948},"✅ Cookie consent gate (paused mode) — OR — (omit if not configured)",{"type":55,"tag":1762,"props":3950,"children":3951},{},[3952],{"type":60,"value":3953},"✅ Microfrontend: host initializes Faro \u002F child uses faro.api — OR — (omit if not applicable)",{"type":55,"tag":56,"props":3955,"children":3956},{},[3957],{"type":55,"tag":78,"props":3958,"children":3959},{},[3960],{"type":60,"value":3961},"What you can add later:",{"type":55,"tag":56,"props":3963,"children":3964},{},[3965,3967,3972,3974],{"type":60,"value":3966},"☐ ",{"type":55,"tag":78,"props":3968,"children":3969},{},[3970],{"type":60,"value":3971},"Custom events",{"type":60,"value":3973}," — instrument meaningful user actions:\n",{"type":55,"tag":200,"props":3975,"children":3977},{"className":3976},[],[3978],{"type":60,"value":3979},"faro.api?.pushEvent('feature_used', { feature: 'dark_mode' })",{"type":55,"tag":56,"props":3981,"children":3982},{},[3983,3984,3989,3991],{"type":60,"value":3966},{"type":55,"tag":78,"props":3985,"children":3986},{},[3987],{"type":60,"value":3988},"Custom measurements",{"type":60,"value":3990}," — track business metrics:\n",{"type":55,"tag":200,"props":3992,"children":3994},{"className":3993},[],[3995],{"type":60,"value":3996},"faro.api?.pushMeasurement({ type: 'cart_value', values: { total: 99.99 } })",{"type":55,"tag":56,"props":3998,"children":3999},{},[4000,4001,4006,4008],{"type":60,"value":3966},{"type":55,"tag":78,"props":4002,"children":4003},{},[4004],{"type":60,"value":4005},"Source map upload",{"type":60,"value":4007}," — resolve minified stack traces to real source lines in production.\nSee: ",{"type":55,"tag":4009,"props":4010,"children":4014},"a",{"href":4011,"rel":4012},"https:\u002F\u002Fgrafana.com\u002Fdocs\u002Fgrafana-cloud\u002Fmonitor-applications\u002Ffrontend-observability\u002Ffaro-web-sdk\u002Fupload-source-maps\u002F",[4013],"nofollow",[4015],{"type":60,"value":4016},"Faro source maps docs",{"type":55,"tag":56,"props":4018,"children":4019},{},[4020,4021,4026],{"type":60,"value":3966},{"type":55,"tag":78,"props":4022,"children":4023},{},[4024],{"type":60,"value":4025},"Alerting",{"type":60,"value":4027}," — create alerts on error rate spikes or Web Vitals degradation from the Grafana Cloud Frontend Observability panel.",{"type":55,"tag":56,"props":4029,"children":4030},{},[4031,4032,4037,4039,4045],{"type":60,"value":3966},{"type":55,"tag":78,"props":4033,"children":4034},{},[4035],{"type":60,"value":4036},"Backend correlation",{"type":60,"value":4038}," — link frontend traces to backend spans. Already enabled for same-origin requests. Add ",{"type":55,"tag":200,"props":4040,"children":4042},{"className":4041},[],[4043],{"type":60,"value":4044},"propagateTraceHeaderCorsUrls",{"type":60,"value":4046}," for external APIs (advanced.md section A).",{"type":55,"tag":4048,"props":4049,"children":4050},"style",{},[4051],{"type":60,"value":4052},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":4054,"total":4232},[4055,4062,4081,4101,4116,4132,4145,4160,4177,4192,4205,4220],{"slug":4,"name":4,"fn":5,"description":6,"org":4056,"tags":4057,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4058,4059,4060,4061],{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15},{"slug":4063,"name":4063,"fn":4064,"description":4065,"org":4066,"tags":4067,"stars":4078,"repoUrl":4079,"updatedAt":4080},"configuring-yesoreyeram-infinity-datasource","configure Grafana Infinity data source","Configure the Infinity data source — base URL and allowed hosts, the authentication methods (basic, bearer token, API key, digest, OAuth passthrough, OAuth 2.0 client credentials\u002FJWT, Azure, Azure Blob, AWS), TLS, custom HTTP headers, network and security settings, the custom health check, and provisioning with a config file. Use when a user asks how to set up, configure, or change settings for the Infinity data source; how to authenticate to an API; how to allow hosts; how to provision it as YAML; or how to troubleshoot connection, authentication, or health-check issues.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4068,4071,4074,4077],{"name":4069,"slug":4070,"type":15},"API Development","api-development",{"name":4072,"slug":4073,"type":15},"Authentication","authentication",{"name":4075,"slug":4076,"type":15},"Configuration","configuration",{"name":9,"slug":8,"type":15},1056,"https:\u002F\u002Fgithub.com\u002Fgrafana\u002Fgrafana-infinity-datasource","2026-07-12T07:43:25.939136",{"slug":4082,"name":4082,"fn":4083,"description":4084,"org":4085,"tags":4086,"stars":4078,"repoUrl":4079,"updatedAt":4100},"querying-yesoreyeram-infinity-datasource","query data with Infinity datasource","Build queries with the Infinity data source — the query types (JSON, CSV, TSV, XML, GraphQL, HTML, UQL, GROQ, Google Sheets, Series, Transformations), the parsers (Frontend\u002Fsimple, Backend JSONata, JQ, UQL, GROQ) and which support alerting, the sources (URL, Inline, Reference, Azure Blob, Random walk), output formats (table, timeseries, logs, trace, node graph, dataframe), root selector and columns, computed columns\u002Ffilters\u002Fsummarize, pagination, and template variables. Use when a user asks how to query Infinity; how to fetch JSON\u002FCSV\u002FXML\u002FGraphQL\u002FHTML from a URL or inline; how to select rows and columns; how to transform data with UQL\u002FGROQ\u002FJSONata\u002FJQ; how to make a query work with alerting; how to paginate; or how to use variables in a query.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4087,4090,4093,4094,4097],{"name":4088,"slug":4089,"type":15},"CSV","csv",{"name":4091,"slug":4092,"type":15},"Data Analysis","data-analysis",{"name":9,"slug":8,"type":15},{"name":4095,"slug":4096,"type":15},"GraphQL","graphql",{"name":4098,"slug":4099,"type":15},"JSON","json","2026-07-15T05:34:05.773947",{"slug":4102,"name":4102,"fn":4103,"description":4104,"org":4105,"tags":4106,"stars":4113,"repoUrl":4114,"updatedAt":4115},"agento11y","manage Grafana Agent Observability resources","Inspects and manages Grafana Agent Observability resources via gcx: conversations, generations, evaluators, rules, scores, and templates. Use when the user wants to list or search conversations, inspect generations, manage evaluators (upsert, test, delete), set up evaluation rules, check scores, or browse evaluator templates. Trigger on phrases like \"list conversations\", \"search generations\", \"what did the agent do\", \"debug LLM conversation\", \"create evaluator\", \"set up evaluation rule\", \"test evaluator\", \"check scores\", \"evaluate generation quality\", or \"set up online evaluation\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4107,4110,4111,4112],{"name":4108,"slug":4109,"type":15},"Agents","agents",{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15},430,"https:\u002F\u002Fgithub.com\u002Fgrafana\u002Fgcx","2026-07-25T05:30:40.29622",{"slug":4117,"name":4117,"fn":4118,"description":4119,"org":4120,"tags":4121,"stars":4113,"repoUrl":4114,"updatedAt":4131},"agento11y-instrument","instrument LLM apps for agent observability","Sets up and instruments a developer's own LLM app or agent to send generations and agentic workflow to Grafana Agent Observability (the Agent Observability SDKs) — greenfield setup, fixing broken instrumentation, or filling gaps in existing instrumentation. Uses gcx for the parts a static prompt can't do: `gcx login` \u002F `gcx cloud stacks` to find the stack, and `gcx agento11y agents|conversations|generations` to VERIFY that data actually lands — so it iterates (instrument → run → verify → fix) until generations arrive, not blindly. Reads the app's code, detects language\u002Fframework, classifies instrumentation state (none \u002F partial \u002F broken), then runs a fixed gap checklist whose #1 item is the silent failure no other prompt catches: the SDK emits OTel spans\u002Fmetrics but never creates a TracerProvider\u002FMeterProvider, so without them all metrics go to a no-op and are lost. Also checks agent_version (required for per-version Performance charts), set_result completeness, SYNC vs STREAM, parent_generation_ids DAG links, and workflow-step coverage. Recommends changes citing file:line and, only with explicit confirmation, applies minimal diffs that don't change app behavior. Pulls SDK reference from agento11y's llms.txt rather than restating it, and hands off to `agento11y-test-starter` once data flows. It does NOT write test suites or set up tenant evaluations, rules, or guards — offline test suites are `agento11y-test-starter`, tenant eval rules + guards are `agento11y-prod-setup`; does NOT install coding-agent telemetry plugins (that is llms.txt \"Path A\"); does NOT mint or store credentials or invent endpoints. Trigger on phrases like \"instrument my app\", \"send my agent's traces to Grafana\", \"set up AI observability for my app\", \"my generations aren't showing up\", \"why is Performance empty\", \"add Agent Observability to my code\", \"fix my instrumentation\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4122,4123,4124,4127,4130],{"name":4108,"slug":4109,"type":15},{"name":9,"slug":8,"type":15},{"name":4125,"slug":4126,"type":15},"Instrumentation","instrumentation",{"name":4128,"slug":4129,"type":15},"LLM","llm",{"name":13,"slug":14,"type":15},"2026-07-31T05:53:52.580237",{"slug":4133,"name":4133,"fn":4134,"description":4135,"org":4136,"tags":4137,"stars":4113,"repoUrl":4114,"updatedAt":4144},"agento11y-prod-setup","setup production evaluation for AI agents","Sets up production evaluation and guardrails for a DEPLOYED AI agent in Grafana Agent Observability, grounded in the agent's own code and its real ingested traffic. The judgment layer on top of the `agento11y` skill: it reads the agent's source (system prompt, tools, entrypoint) AND samples its live traffic via gcx, checks what evaluators\u002Frules\u002Fguards already exist, then recommends only what's missing — online eval rules (score live conversations for regressions) and guards (warn-first request-path policies that redact \u002F tool-filter and may later be promoted to deny). It drafts reviewable YAML and, only with explicit confirmation, applies via `gcx agento11y`. New guards are drafted in warn mode (safe on live traffic — warn records but never blocks). It DOES create stack-level objects — that is the point — but every write is confirmed. It never rewrites or redeploys the agent. Trigger on phrases like \"set up production evaluation\", \"my agent is in prod what should I evaluate\", \"catch quality regressions\", \"add guardrails to my agent\", \"redact PII from my agent\", \"block dangerous tools\", \"set up online evals and guards\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4138,4139,4142,4143],{"name":4108,"slug":4109,"type":15},{"name":4140,"slug":4141,"type":15},"Evals","evals",{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},"2026-07-31T05:53:53.576347",{"slug":4146,"name":4146,"fn":4147,"description":4148,"org":4149,"tags":4150,"stars":4113,"repoUrl":4114,"updatedAt":4159},"agento11y-test-starter","build and run agent test suites","Use early in an AI-agent project — before ship, before real traffic — to build a starter test suite for the agent and run it offline. Reads the agent's own code (system prompt, tools, task), writes a labeled draft suite of test cases (happy\u002Fedge\u002Fadversarial) grounded in real lines, and recommends how to score each case (the evaluators\u002Fjudges the offline runner uses). Assesses how runnable the agent is: for an easily-invoked agent it generates a runner stub (run_experiment.py) with two holes to fill and can optionally run it (only with permission, only against the endpoint the developer configured); for agents needing a harness or full runtime it points to the existing eval infra. It runs OFFLINE and never creates tenant-level evaluators, rules, or guards — that is `agento11y-prod-setup`, for a deployed agent with real traffic. Trigger on phrases like \"how do I test my agent before shipping\", \"write test cases for my agent\", \"set up tests for my agent\", \"check my agent before prod\", \"I have no traffic yet, how do I evaluate it\", \"test my agent offline\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4151,4152,4153,4156],{"name":4108,"slug":4109,"type":15},{"name":9,"slug":8,"type":15},{"name":4154,"slug":4155,"type":15},"QA","qa",{"name":4157,"slug":4158,"type":15},"Testing","testing","2026-07-31T05:53:51.62785",{"slug":4161,"name":4161,"fn":4162,"description":4163,"org":4164,"tags":4165,"stars":4113,"repoUrl":4114,"updatedAt":4176},"create-dashboard","create Grafana dashboards with gcx","Designs and creates Grafana dashboards with gcx, using `gcx dashboards snapshot` as a visual feedback loop. Use when the user wants to create a new Grafana dashboard, add panels, variables, or annotations to an existing dashboard, design dashboard panels, variables, queries, or layout, or make a material visual redesign. Triggers on \"create dashboard\", \"new dashboard\", \"build dashboard\", \"dashboard for \u003Cservice>\", \"add panels\", \"add variable\", \"add annotation\", \"improve this dashboard\", or \"iterate on a dashboard\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4166,4169,4172,4175],{"name":4167,"slug":4168,"type":15},"Dashboards","dashboards",{"name":4170,"slug":4171,"type":15},"Data Visualization","data-visualization",{"name":4173,"slug":4174,"type":15},"Design","design",{"name":9,"slug":8,"type":15},"2026-07-25T05:30:46.289717",{"slug":4178,"name":4178,"fn":4179,"description":4180,"org":4181,"tags":4182,"stars":4113,"repoUrl":4114,"updatedAt":4191},"debug-with-grafana","investigate application issues with Grafana","Structured workflow for investigating application problems with Grafana observability data (metrics, logs, traces) via gcx. Covers live firefighting AND retrospective incident analysis: incident triage, root-cause analysis, blast-radius checks (did an incident spill into other services), verifying whether a deployment or rollout triggered an incident, finding which service, endpoint, or path owns the most errors or slow requests, checking whether retries or queue backlogs piled up, and quantifying error or latency shares over a time window. Trigger on: \"my API is returning 500 errors\", \"latency is spiking\", \"investigate why requests are failing\", \"triage the incident\", \"blast radius\", \"root cause\", \"did the rollout cause it\", \"which endpoint owns the most 5xx\", \"did retries pile up\", or any request to analyse an earlier incident window using telemetry. For authoring dashboards use create-dashboard; for dashboard inventory use manage-dashboards.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4183,4186,4187,4190],{"name":4184,"slug":4185,"type":15},"Debugging","debugging",{"name":9,"slug":8,"type":15},{"name":4188,"slug":4189,"type":15},"Incident Response","incident-response",{"name":13,"slug":14,"type":15},"2026-07-18T05:11:10.445428",{"slug":4193,"name":4193,"fn":4194,"description":4195,"org":4196,"tags":4197,"stars":4113,"repoUrl":4114,"updatedAt":4204},"diagnose-entity-graph","diagnose Grafana Entity Graph issues","Diagnose Entity Graph problems: missing entities, missing edges, disconnected clusters, or filtering issues. Use when the user reports that Entity Graph doesn't look right, services are missing, edges aren't appearing, or environments can't be filtered. Triggers for: \"entity graph is empty\", \"services missing from entity graph\", \"no edges in entity graph\", \"disconnected services\", \"can't filter entity graph\", \"entity graph not working\", \"diagnose entity graph\", \"debug knowledge graph\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4198,4199,4200,4203],{"name":4184,"slug":4185,"type":15},{"name":9,"slug":8,"type":15},{"name":4201,"slug":4202,"type":15},"Graph Analysis","graph-analysis",{"name":13,"slug":14,"type":15},"2026-07-25T05:30:39.380934",{"slug":4206,"name":4206,"fn":4207,"description":4208,"org":4209,"tags":4210,"stars":4113,"repoUrl":4114,"updatedAt":4219},"gcx","manage Grafana Cloud resources via gcx","Manages Grafana Cloud resources via the gcx CLI. Trigger when the user wants to inspect, create, update, delete, query, or automate any Grafana resource - dashboards, datasources, alerts, SLOs, synthetic checks, oncall, incidents, fleet, k6, knowledge graph, or adaptive telemetry.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4211,4214,4215,4216],{"name":4212,"slug":4213,"type":15},"CLI","cli",{"name":9,"slug":8,"type":15},{"name":17,"slug":18,"type":15},{"name":4217,"slug":4218,"type":15},"Operations","operations","2026-07-31T05:53:50.587304",{"slug":4221,"name":4221,"fn":4222,"description":4223,"org":4224,"tags":4225,"stars":4113,"repoUrl":4114,"updatedAt":4231},"gcx-demo","present gcx demo tours","Run a narrated, read-only demo tour of gcx for customer or colleague presentations. Showcases the breadth of gcx across every Grafana Cloud product area — resources, datasources, metrics, logs, traces, SLOs, alerts, synthetic monitoring, IRM, k6, fleet, and more. All commands are strictly read-only. Trigger when the user says \"demo gcx\", \"show off gcx\", \"customer demo\", \"gcx tour\", or \"\u002Fgcx-demo\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4226,4227,4228],{"name":4212,"slug":4213,"type":15},{"name":9,"slug":8,"type":15},{"name":4229,"slug":4230,"type":15},"Presentations","presentations","2026-07-25T05:30:45.282458",80,{"items":4234,"total":2277},[4235],{"slug":4,"name":4,"fn":5,"description":6,"org":4236,"tags":4237,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4238,4239,4240,4241],{"name":20,"slug":21,"type":15},{"name":23,"slug":24,"type":15},{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15}]