Skip to content

Add c15t consent management#1009

Open
tannerlinsley wants to merge 1 commit into
mainfrom
taren/c15t-consent-management
Open

Add c15t consent management#1009
tannerlinsley wants to merge 1 commit into
mainfrom
taren/c15t-consent-management

Conversation

@tannerlinsley

@tannerlinsley tannerlinsley commented Jun 26, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Added a centralized consent manager experience for privacy controls and consent prompts.
    • Added a “Privacy Settings” link in the footer for easier access to consent preferences.
    • Updated the app to include the latest consent management styling.
  • Bug Fixes

    • Improved page load behavior so consent UI is mounted more reliably without affecting initial rendering.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
tanstack-com 23d52ee Commit Preview URL

Branch Preview URL
Jun 26 2026, 06:49 PM

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds c15t consent-manager support to the app shell, introduces a new ConsentManager wrapper and footer privacy-settings link, updates client bundling and styles for c15t, and removes the prior Google Analytics head bootstrap from the root route.

Changes

c15t consent manager integration

Layer / File(s) Summary
Runtime setup
package.json, src/styles/app.css, src/utils/analytics/providers/google.ts, vite.config.ts
Adds @c15t/react and @c15t/scripts, imports @c15t/react/styles.css, expands Worker bundling for c15t packages, and updates the Google Analytics window typings.
ConsentManager component
src/components/ConsentManager.tsx
Adds ConsentManager, which builds hosted consent options, waits for hydration before rendering the provider, and conditionally renders ConsentBanner and ConsentDialog around children.
Root shell integration
src/routes/__root.tsx
Imports ConsentManager, removes the prior Google Analytics bootstrap constants and head script entry, and wraps the root providers and content under ConsentManager with showControls={!hasBaseParent}.
Footer privacy link
src/components/Footer.tsx
Adds FooterConsentSettingsLink, which waits until mount before rendering a ConsentDialogLink labeled “Privacy Settings” in the footer link grid.

Sequence Diagram(s)

sequenceDiagram
  participant RootRoute as src/routes/__root.tsx
  participant ConsentManager
  participant ConsentBanner
  participant ConsentDialog
  RootRoute->>ConsentManager: render with showControls={!hasBaseParent}
  ConsentManager->>ConsentManager: wait for hydration
  ConsentManager->>ConsentBanner: render when showControls is true
  ConsentManager->>ConsentDialog: render when showControls is true
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • LadyBluenotes

Poem

I hopped through code and sniffed the air,
A consent box bloomed with bunny care.
Privacy settings twinkled bright,
I nibbled CSS by moonlit night.
Hoppy days! 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding c15t-based consent management support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch taren/c15t-consent-management

Comment @coderabbitai help to get the list of available commands.

@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​c15t/​scripts@​2.1.0871009694100
Added@​c15t/​react@​2.1.0921008797100

View full report

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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/components/ConsentManager.tsx`:
- Around line 54-58: `ConsentManagerProvider` is returning early until after
hydration, which delays c15t initialization and the Google Tag `alwaysLoad`
setup. Keep `ConsentManagerProvider` mounted on the first render and move only
the hydration-stability workaround out of this path, ideally into
`ConsentBanner` and `ConsentDialog` or by using c15t’s SSR data path. Preserve
the provider’s setup logic so the runtime starts immediately while still
avoiding hydration mismatch.
🪄 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: d9392cbb-116f-4dcf-bbaf-554c522087ec

📥 Commits

Reviewing files that changed from the base of the PR and between 992f158 and 23d52ee.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • package.json
  • src/components/ConsentManager.tsx
  • src/components/Footer.tsx
  • src/routes/__root.tsx
  • src/styles/app.css
  • src/utils/analytics/providers/google.ts
  • vite.config.ts

Comment on lines +54 to +58
// c15t injects runtime theme styles; mount after hydration so Start's SSR
// markup stays byte-stable.
if (!hasMounted) {
return <>{children}</>
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect relevant files and surrounding context.
git ls-files 'src/components/ConsentManager.tsx' 'src/routes/__root.tsx' 'src/components/*Consent*' 'src/**/*Consent*' | sed -n '1,200p'

printf '\n--- ConsentManager outline ---\n'
ast-grep outline src/components/ConsentManager.tsx --view expanded || true

printf '\n--- root outline ---\n'
ast-grep outline src/routes/__root.tsx --view expanded || true

printf '\n--- ConsentManager excerpt ---\n'
nl -ba src/components/ConsentManager.tsx | sed -n '1,220p'

printf '\n--- root excerpt ---\n'
nl -ba src/routes/__root.tsx | sed -n '1,260p'

Repository: TanStack/tanstack.com

Length of output: 1290


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for c15t usage and any provider placement.
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' 'ConsentManagerProvider|c15t|gtag|ConsentBanner|ConsentDialog|alwaysLoad' src . || true

Repository: TanStack/tanstack.com

Length of output: 6447


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check for c15t integration docs or comments that clarify expected bootstrap timing.
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' 'c15t|ConsentManagerProvider|alwaysLoad|hydration|SSR|bootstr' README* docs src package.json . || true

Repository: TanStack/tanstack.com

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# If the repo has package metadata, identify c15t package versions to reason about runtime expectations.
cat package.json 2>/dev/null | sed -n '1,220p' || true

Repository: TanStack/tanstack.com

Length of output: 5647


🌐 Web query:

c15t React provider mount first render consent manager hydration gtag alwaysLoad docs

💡 Result:

In the c15t consent manager system, the 'alwaysLoad' option is used for third-party scripts that must be present from the start of the page load, such as Google Tag Manager or gtag.js [1][2][3]. When 'alwaysLoad' is set to true, the script is injected into the DOM immediately, regardless of the user's current consent state [1][2]. Regarding the behavior during mount and hydration: 1. Consent Initialization: When the ConsentManagerProvider mounts, it creates a cached consent runtime and reads stored consent from the browser (e.g., localStorage/cookies) [4]. 2. Google Tag Handling: For 'alwaysLoad' integrations like gtag.js, c15t automatically initializes the vendor with Consent Mode v2 defaults set to 'denied' before any user interaction occurs [2][3]. This ensures that while the script is present, data transmission is suppressed until explicit consent is granted [2][3]. 3. Hydration and First Render: To prevent hydration mismatches or consent banner flashes, it is recommended to use server-side utilities to fetch initial consent data (e.g., 'fetchSSRData' or 'fetchInitialData') and pass this as a promise to the provider's 'ssrData' option [5][6][7]. This allows the provider to initialize with the correct state on the first render rather than waiting for a client-side API fetch [4][7]. 4. Stability: Mounting the provider as high as possible in the React tree is advised to avoid remounting during client-side navigation, which keeps the consent state stable [8]. You do not need to manually wrap calls to vendor SDKs (like gtag) in consent checks if they are correctly integrated via 'alwaysLoad', as the vendor's internal Consent Mode API handles the suppression [2][3]. If the integration is not 'alwaysLoad', the script will remain blocked until the relevant consent category is granted [1][9].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the relevant file sections with a fallback that does not rely on nl.
sed -n '1,140p' src/components/ConsentManager.tsx
printf '\n---\n'
sed -n '220,320p' src/routes/__root.tsx
printf '\n---\n'
sed -n '1,140p' src/server.ts

Repository: TanStack/tanstack.com

Length of output: 8987


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect c15t docs in local dependency references if present in lockfile or package metadata.
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' 'alwaysLoad|ssrData|fetchSSRData|fetchInitialData|ConsentManagerProvider' pnpm-lock.yaml package.json src docs .agents || true

Repository: TanStack/tanstack.com

Length of output: 386


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '320,430p' src/routes/__root.tsx
printf '\n---\n'
sed -n '1,120p' src/utils/analytics/providers/google.ts

Repository: TanStack/tanstack.com

Length of output: 2079


Keep ConsentManagerProvider mounted from the first render. The early return defers c15t initialization until after hydration, so the consent runtime and Google Tag alwaysLoad setup start late. Move only the hydration-specific workaround into ConsentBanner/ConsentDialog, or use c15t’s SSR data path.

🤖 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/components/ConsentManager.tsx` around lines 54 - 58,
`ConsentManagerProvider` is returning early until after hydration, which delays
c15t initialization and the Google Tag `alwaysLoad` setup. Keep
`ConsentManagerProvider` mounted on the first render and move only the
hydration-stability workaround out of this path, ideally into `ConsentBanner`
and `ConsentDialog` or by using c15t’s SSR data path. Preserve the provider’s
setup logic so the runtime starts immediately while still avoiding hydration
mismatch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant