Optional Gizmo Analytics integration (cookieless web analytics)#54
Optional Gizmo Analytics integration (cookieless web analytics)#54sudomichael wants to merge 2 commits into
Conversation
Cookieless web analytics, gated on NEXT_PUBLIC_GIZMO_KEY so it's fully opt-in. Leaving the env var unset disables the integration entirely — no script renders, no network request. - src/env.ts: NEXT_PUBLIC_GIZMO_KEY as z.string().optional() in the client schema + runtimeEnv - src/app/layout.tsx: <Script> mounted only when the key is set; uses afterInteractive strategy - .env.sample: new section with explanatory comment No new dependencies (script loads from CDN). No required config. https://gizmoanalytics.io
|
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR adds optional Gizmo Analytics integration: ChangesGizmo Analytics Integration
Sequence Diagram(s)sequenceDiagram
participant Browser
participant NextLayout
participant RuntimeEnv
participant GizmoCDN
Browser->>NextLayout: load page (client)
NextLayout->>RuntimeEnv: read NEXT_PUBLIC_GIZMO_KEY
alt key present
NextLayout->>GizmoCDN: inject <Script src="https://gizmoanalytics.io/script.js">
GizmoCDN-->>Browser: deliver analytics script
else key absent
NextLayout-->>Browser: do not inject script
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/app/layout.tsx (2)
87-87: ⚡ Quick winConsider
lazyOnloadstrategy for non-critical analytics.The
afterInteractivestrategy loads the script after the page becomes interactive, which can still impact Core Web Vitals. For analytics that don't need immediate execution,strategy="lazyOnload"defers loading until browser idle time, improving performance metrics. This is a common pattern for third-party analytics.⚡ Proposed optimization
- strategy="afterInteractive" + strategy="lazyOnload"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/layout.tsx` at line 87, The analytics Script currently uses strategy="afterInteractive" which can affect Core Web Vitals; locate the Script element in src/app/layout.tsx (the one with strategy="afterInteractive") and change its strategy prop to "lazyOnload" so the analytics script is deferred until the browser is idle; ensure the Script import/usage (Script component and its strategy prop) is updated accordingly and verify that any analytics that require immediate execution are not relying on this script before switching.
84-89: Consider adding Subresource Integrity (SRI) verification to the external analytics script.The script is loaded from
gizmoanalytics.io, which is confirmed as the official domain for Gizmo Analytics, a privacy-friendly, cookieless analytics service. However, the script lacks Subresource Integrity (SRI) verification. While not critical for analytics, adding an integrity hash would improve security against potential CDN compromise. If feasible, retrieve the expected hash from Gizmo Analytics and add anintegrityattribute to the Script component.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/layout.tsx` around lines 84 - 89, The external <Script> inclusion of Gizmo Analytics in layout.tsx lacks Subresource Integrity: update the Script JSX (the Script component that uses src="https://gizmoanalytics.io/script.js" and data-key={env.NEXT_PUBLIC_GIZMO_KEY}) to include an integrity attribute with the official SRI hash from Gizmo Analytics and add crossorigin="anonymous" so the browser can verify the resource; obtain the correct SHA384/sha256 SRI value from Gizmo Analytics/CSP provider and add it as integrity="sha...".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/env.ts`:
- Line 35: The env schema currently allows empty strings for
NEXT_PUBLIC_GIZMO_KEY because it uses z.string().optional(); update the
validation for the NEXT_PUBLIC_GIZMO_KEY field in the schema (in src/env.ts) to
require a non-empty string when present (e.g., change to a string with min(1)
and keep optional) so empty values are rejected and you won't render a Script
with an empty data-key.
---
Nitpick comments:
In `@src/app/layout.tsx`:
- Line 87: The analytics Script currently uses strategy="afterInteractive" which
can affect Core Web Vitals; locate the Script element in src/app/layout.tsx (the
one with strategy="afterInteractive") and change its strategy prop to
"lazyOnload" so the analytics script is deferred until the browser is idle;
ensure the Script import/usage (Script component and its strategy prop) is
updated accordingly and verify that any analytics that require immediate
execution are not relying on this script before switching.
- Around line 84-89: The external <Script> inclusion of Gizmo Analytics in
layout.tsx lacks Subresource Integrity: update the Script JSX (the Script
component that uses src="https://gizmoanalytics.io/script.js" and
data-key={env.NEXT_PUBLIC_GIZMO_KEY}) to include an integrity attribute with the
official SRI hash from Gizmo Analytics and add crossorigin="anonymous" so the
browser can verify the resource; obtain the correct SHA384/sha256 SRI value from
Gizmo Analytics/CSP provider and add it as integrity="sha...".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b53d4c99-811e-4249-93a8-b5e809cd89e5
📒 Files selected for processing (3)
.env.samplesrc/app/layout.tsxsrc/env.ts
z.string().optional() allowed empty strings through, which would render <Script data-key="" />. Tighten to .min(1).optional() so an explicitly-empty key is rejected; absent key remains the disable path. Suggested by CodeRabbit on webdevcody#54.
|
Thanks for the review @coderabbitai — addressed: 1. Reject empty 2. 3. SRI integrity hash: skipping intentionally. |
|
Tip For best results, initiate chat on the files or code changes.
All three points are well resolved. The PR looks good to me! 🐇 |
Heads up
Noticed the README's note about not adding things without prior approval — happy to close this if it's not a fit. Keeping the surface minimal: 3 files, ~15 lines, no new dependencies (script loads from CDN), and fully opt-in (gated on
NEXT_PUBLIC_GIZMO_KEY— leaving it unset disables the integration entirely).Summary
Adds Gizmo Analytics as a second analytics option alongside PostHog. Gizmo is cookieless and privacy-friendly, so no cookie banner is required under CNIL / EDPB guidance — useful as a complement to PostHog for kits where the user wants basic traffic analytics without consent infrastructure.
Changes
src/env.ts—NEXT_PUBLIC_GIZMO_KEYregistered asz.string().optional()in the client schema + runtimeEnv, following the existing t3-env pattern.src/app/layout.tsx—<Script>mounted conditionally whenenv.NEXT_PUBLIC_GIZMO_KEYis present. UsesafterInteractivestrategy so it doesn't compete with LCP..env.sample— New section with comment + signup link.Test plan
pnpm buildsucceeds, type check cleanHappy to adjust naming, placement, or close this if it's outside the kit's scope.
Summary by CodeRabbit