From f16a5254952a8deefd42b35aa091227669cbb50d Mon Sep 17 00:00:00 2001 From: "DESKTOP-738DBED\\tomsl" Date: Wed, 25 Feb 2026 20:40:51 +0100 Subject: [PATCH] Add Vercel Speed Insights Runs unconditionally as it collects only anonymised Web Vitals with no cookies and no user identifiers. Privacy page updated to document this distinction from consent-gated Analytics. Co-Authored-By: Claude Sonnet 4.6 --- package-lock.json | 43 ++++++++++++++++++++++++++++++++++++---- package.json | 1 + src/app/layout.tsx | 2 ++ src/app/privacy/page.tsx | 12 +++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd1f114..ffad289 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@prisma/adapter-pg": "^7.4.0", "@prisma/client": "^7.4.0", "@vercel/analytics": "^1.6.1", + "@vercel/speed-insights": "^1.3.1", "class-variance-authority": "^0.7.1", "lucide-react": "^0.564.0", "next": "16.1.6", @@ -320,7 +321,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -330,7 +331,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -364,7 +365,7 @@ "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.29.0" @@ -456,7 +457,7 @@ "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -3822,6 +3823,40 @@ } } }, + "node_modules/@vercel/speed-insights": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@vercel/speed-insights/-/speed-insights-1.3.1.tgz", + "integrity": "sha512-PbEr7FrMkUrGYvlcLHGkXdCkxnylCWePx7lPxxq36DNdfo9mcUjLOmqOyPDHAOgnfqgGGdmE3XI9L/4+5fr+vQ==", + "license": "Apache-2.0", + "peerDependencies": { + "@sveltejs/kit": "^1 || ^2", + "next": ">= 13", + "react": "^18 || ^19 || ^19.0.0-rc", + "svelte": ">= 4", + "vue": "^3", + "vue-router": "^4" + }, + "peerDependenciesMeta": { + "@sveltejs/kit": { + "optional": true + }, + "next": { + "optional": true + }, + "react": { + "optional": true + }, + "svelte": { + "optional": true + }, + "vue": { + "optional": true + }, + "vue-router": { + "optional": true + } + } + }, "node_modules/@vitejs/plugin-react": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", diff --git a/package.json b/package.json index f7da9ce..01832f8 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@prisma/adapter-pg": "^7.4.0", "@prisma/client": "^7.4.0", "@vercel/analytics": "^1.6.1", + "@vercel/speed-insights": "^1.3.1", "class-variance-authority": "^0.7.1", "lucide-react": "^0.564.0", "next": "16.1.6", diff --git a/src/app/layout.tsx b/src/app/layout.tsx index c2b0954..41f6482 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,6 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; +import { SpeedInsights } from "@vercel/speed-insights/next"; import Header from "@/components/layout/Header"; import Footer from "@/components/layout/Footer"; import ConsentProvider from "@/components/layout/ConsentProvider"; @@ -68,6 +69,7 @@ export default function RootLayout({