mirror of
https://github.com/hanzoai/help-site.git
synced 2026-10-30 14:39:12 +00:00
@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.
75 lines
2.6 KiB
TypeScript
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>
|
|
)
|
|
}
|