diff --git a/bun.lock b/bun.lock
index 345c980c..0dedebb7 100644
--- a/bun.lock
+++ b/bun.lock
@@ -30,6 +30,7 @@
"@tanstack/react-router": "1.170.16",
"@tanstack/react-start": "1.168.26",
"@vercel/analytics": "2.0.1",
+ "@vercel/speed-insights": "2.0.0",
"class-variance-authority": "0.7.1",
"clawhub-schema": "workspace:0.0.2",
"clsx": "2.1.1",
@@ -924,6 +925,8 @@
"@vercel/analytics": ["@vercel/analytics@2.0.1", "", { "peerDependencies": { "@remix-run/react": "^2", "@sveltejs/kit": "^1 || ^2", "next": ">= 13", "nuxt": ">= 3", "react": "^18 || ^19 || ^19.0.0-rc", "svelte": ">= 4", "vue": "^3", "vue-router": "^4" }, "optionalPeers": ["@remix-run/react", "@sveltejs/kit", "next", "nuxt", "react", "svelte", "vue", "vue-router"] }, "sha512-MTQG6V9qQrt1tsDeF+2Uoo5aPjqbVPys1xvnIftXSJYG2SrwXRHnqEvVoYID7BTruDz4lCd2Z7rM1BdkUehk2g=="],
+ "@vercel/speed-insights": ["@vercel/speed-insights@2.0.0", "", { "peerDependencies": { "@sveltejs/kit": "^1 || ^2", "next": ">= 13", "nuxt": ">= 3", "react": "^18 || ^19 || ^19.0.0-rc", "svelte": ">= 4", "vue": "^3", "vue-router": "^4" }, "optionalPeers": ["@sveltejs/kit", "next", "nuxt", "react", "svelte", "vue", "vue-router"] }, "sha512-jwkNcrTeafWxjmWq4AHBaptSqZiJkYU5adLC9QBSqeim0GcqDMgN5Ievh8OG1rJ6W3A4l1oiP7qr9CWxGuzu3w=="],
+
"@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.2", "", { "dependencies": { "@rolldown/pluginutils": "^1.0.0" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg=="],
"@vitest/coverage-v8": ["@vitest/coverage-v8@4.1.9", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.9", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.2.0", "magicast": "^0.5.2", "obug": "^2.1.1", "std-env": "^4.0.0-rc.1", "tinyrainbow": "^3.1.0" }, "peerDependencies": { "@vitest/browser": "4.1.9", "vitest": "4.1.9" }, "optionalPeers": ["@vitest/browser"] }, "sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g=="],
diff --git a/package.json b/package.json
index bee0b48a..27660498 100644
--- a/package.json
+++ b/package.json
@@ -96,6 +96,7 @@
"@tanstack/react-router": "1.170.16",
"@tanstack/react-start": "1.168.26",
"@vercel/analytics": "2.0.1",
+ "@vercel/speed-insights": "2.0.0",
"class-variance-authority": "0.7.1",
"clawhub-schema": "workspace:0.0.2",
"clsx": "2.1.1",
diff --git a/src/__tests__/ui-design-contract.test.ts b/src/__tests__/ui-design-contract.test.ts
index 4dd5ad21..1933e4cf 100644
--- a/src/__tests__/ui-design-contract.test.ts
+++ b/src/__tests__/ui-design-contract.test.ts
@@ -60,6 +60,7 @@ function contrastRatio(foreground: string, background: string) {
}
describe("restored UI design contract", () => {
+ const rootRoute = () => read("src/routes/__root.tsx");
const header = () => read("src/components/Header.tsx");
const footer = () => read("src/components/Footer.tsx");
const home = () => read("src/routes/index.tsx");
@@ -68,6 +69,17 @@ describe("restored UI design contract", () => {
const styles = () => read("src/styles.css");
const theme = () => read("src/lib/theme.ts");
+ it("keeps Vercel browser instrumentation mounted outside local dev", () => {
+ const rootSource = rootRoute();
+
+ expect(rootSource).toContain('import { Analytics } from "@vercel/analytics/react";');
+ expect(rootSource).toContain('import { SpeedInsights } from "@vercel/speed-insights/react";');
+ expect(rootSource).toContain('!["localhost", "127.0.0.1", "::1"].includes');
+ expect(rootSource).toContain("{showAnalytics ? (");
+ expect(rootSource).toContain("");
+ expect(rootSource).toContain("");
+ });
+
it("requires the responsive header rail, search overlay, and theme controls", () => {
const headerSource = header();
const navSource = navItems();
diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx
index 2fc29e91..cf4ac66a 100644
--- a/src/routes/__root.tsx
+++ b/src/routes/__root.tsx
@@ -6,6 +6,7 @@ import {
useLocation,
} from "@tanstack/react-router";
import { Analytics } from "@vercel/analytics/react";
+import { SpeedInsights } from "@vercel/speed-insights/react";
import { useEffect } from "react";
import { Toaster } from "sonner";
import { AppProviders } from "../components/AppProviders";
@@ -196,7 +197,14 @@ function RootDocument({ children }: { children: React.ReactNode }) {
},
}}
/>
- {showAnalytics ? : null}
+
+ {showAnalytics ? (
+ <>
+
+
+ >
+ ) : null}
+