feat: add HubSpot tracking with consent-based loading (#10885)

Co-authored-by: Roo Code <roomote@roocode.com>
This commit is contained in:
roomote[bot] 2026-01-21 22:54:07 -05:00 • committed by GitHub
parent 971885d8e7
commit 21bd7609a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 84 additions and 9 deletions

View file

@ -100,6 +100,19 @@ export default function CookiePolicy() {
<td className="border border-border px-4 py-3">1 year</td>
<td className="border border-border px-4 py-3 font-mono text-sm">ph_*</td>
</tr>
<tr>
<td className="border border-border px-4 py-3 font-medium">HubSpot</td>
<td className="border border-border px-4 py-3">
Marketing automation and visitor tracking
</td>
<td className="border border-border px-4 py-3">
Analytics (only with your consent)
</td>
<td className="border border-border px-4 py-3">13 months</td>
<td className="border border-border px-4 py-3 font-mono text-sm">
hubspotutk, __hstc, __hssrc, __hssc
</td>
</tr>
</tbody>
</table>
</div>
@ -122,6 +135,15 @@ export default function CookiePolicy() {
PostHog Privacy Policy
</a>
</p>
<p>
<a
href="https://legal.hubspot.com/privacy-policy"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline">
HubSpot Privacy Policy
</a>
</p>
<h2 className="mt-12 text-2xl font-bold">Essential cookies</h2>
<p>
@ -133,10 +155,10 @@ export default function CookiePolicy() {
<h2 className="mt-12 text-2xl font-bold">Analytics cookies</h2>
<p>
We use PostHog analytics cookies to understand how visitors interact with our website. This
helps us improve our services and user experience. Analytics cookies are placed only if you give
consent through our cookie banner. The lawful basis for processing these cookies is your
consent, which you can withdraw at any time.
We use PostHog and HubSpot analytics cookies to understand how visitors interact with our
website. This helps us improve our services, user experience, and marketing efforts. Analytics
cookies are placed only if you give consent through our cookie banner. The lawful basis for
processing these cookies is your consent, which you can withdraw at any time.
</p>
<h2 className="mt-12 text-2xl font-bold">Third-party services</h2>

View file

@ -0,0 +1,50 @@
"use client"
import { useEffect, useState } from "react"
import Script from "next/script"
import { hasConsent, onConsentChange } from "@/lib/analytics/consent-manager"
// HubSpot Account ID
const HUBSPOT_ID = "243714031"
/**
* HubSpot Tracking Provider
* Loads HubSpot tracking script only after user consent is given, following GDPR requirements
*/
export function HubSpotProvider({ children }: { children: React.ReactNode }) {
const [shouldLoad, setShouldLoad] = useState(false)
useEffect(() => {
// Check initial consent status
if (hasConsent()) {
setShouldLoad(true)
}
// Listen for consent changes
const unsubscribe = onConsentChange((consented) => {
if (consented) {
setShouldLoad(true)
}
})
return unsubscribe
}, [])
return (
<>
{shouldLoad && (
<>
{/* HubSpot Embed Code */}
<Script
id="hs-script-loader"
src={`//js-na2.hs-scripts.com/${HUBSPOT_ID}.js`}
strategy="afterInteractive"
async
defer
/>
</>
)}
{children}
</>
)
}

View file

@ -4,6 +4,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { ThemeProvider } from "next-themes"
import { GoogleTagManagerProvider } from "./google-tag-manager-provider"
import { HubSpotProvider } from "./hubspot-provider"
import { PostHogProvider } from "./posthog-provider"
const queryClient = new QueryClient()
@ -12,11 +13,13 @@ export const Providers = ({ children }: { children: React.ReactNode }) => {
return (
<QueryClientProvider client={queryClient}>
<GoogleTagManagerProvider>
<PostHogProvider>
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem={false}>
{children}
</ThemeProvider>
</PostHogProvider>
<HubSpotProvider>
<PostHogProvider>
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem={false}>
{children}
</ThemeProvider>
</PostHogProvider>
</HubSpotProvider>
</GoogleTagManagerProvider>
</QueryClientProvider>
)