Files
zeekay a31783cabd Send the first-party stream for every visitor; take the new banner
@hanzo/event 0.3.61 runs its own stream whatever the visitor chose, and
consent gates the third parties alone, so the provider is no longer
switched off until Analytics is allowed: a pageview reaches /v1/event
before any choice, and GA4 and the Pixel still wait for Accept all.
@hanzo/ui 8.29.14 is the banner with the new copy and no Reject button.

Its preferences sheet draws icons through react-native-svg, which picks
its web build by the extension list alone; Turbopack applies that list
only to transpiled packages, so react-native-svg is transpiled.
2026-10-25 22:22:03 -07:00

75 lines
2.6 KiB
TypeScript

'use client'
import { useEffect, type ReactNode } from 'react'
import { startTags } from '@hanzo/event'
import { AnalyticsProvider, usePageview } from '@hanzo/event/react'
import { Consent } from '@hanzo/ui/consent'
import { usePathname } from 'next/navigation'
/** The one Hanzo Cloud telemetry front door: POST api.hanzo.ai/v1/event. */
const HOST = 'https://api.hanzo.ai'
/**
* This site's project key, cloud project `hanzo-help`. A `pk-` is publishable: it
* names the project an event is filed under and the tag set cloud serves, and
* it mints no reader. @hanzo/event derives a key from the host only for the
* hosts in its SITE_KEY table, and hanzo.help is not one, so it is stated here.
*/
const KEY = 'pk-B4YArKNlP3fjT7EYOCHLsTSRYbraQnTDkXumIxm66gg'
/** The sites one visit can cross; GA4 keeps it one session across them. */
const DOMAINS = [
'hanzo.ai',
'docs.hanzo.ai',
'hanzo.id',
'hanzo.build',
'platform.hanzo.ai',
'hanzo.app',
'hanzo.chat',
'pay.hanzo.ai',
]
/**
* One client. @hanzo/ui's components report through @hanzogui/telemetry, whose
* ambient client sends its own pageview under the host's org key, or none: a
* second stream beside the provider's, misfiled or refused. It is switched off
* here, at module scope, because it is built on first use during render.
*/
if (typeof globalThis !== 'undefined') {
const g = globalThis as { __HANZO_TELEMETRY__?: { enabled?: boolean } }
g.__HANZO_TELEMETRY__ = { ...g.__HANZO_TELEMETRY__, enabled: false }
}
function Pageview() {
usePageview(usePathname())
return null
}
/**
* The ad tags. `startTags` fetches this site's tag set from cloud (GA4 and the
* Pixel are configuration there, never ids in this repo) and the consent rule
* for this visitor's region, and loads only what consent allows.
*/
function Tags() {
useEffect(() => startTags({ key: KEY, domains: [window.location.hostname, ...DOMAINS] }), [])
return null
}
/**
* Telemetry for hanzo.help, mounted once in the root layout, inside <Hanzo> so the
* banner is themed. The provider owns the one @hanzo/event client: the first
* pageview, error capture and the unload flush; <Pageview> adds one per route
* change. The stream is first party and runs for every visitor; consent gates
* the third parties alone (startTags), and <Consent> is the one banner that asks.
*/
export function Analytics({ children }: { children: ReactNode }) {
return (
<AnalyticsProvider config={{ product: 'site', host: HOST, ingestKey: KEY }}>
<Tags />
<Pageview />
{children}
<Consent />
</AnalyticsProvider>
)
}