interface OpenPanelAnalyticsProps {
clientId: string
nonce?: string
}
const OPENPANEL_QUEUE_SNIPPET =
'window.op=window.op||function(){var n=[];return new Proxy(function(){arguments.length&&n.push([].slice.call(arguments))},{get:function(t,r){return"q"===r?n:function(){n.push([r].concat([].slice.call(arguments)))}},has:function(t,r){return"q"===r}})}();'
/**
* Server-rendered OpenPanel Analytics component that uses a proxy route to
* avoid ad blockers. Renders raw {@link HTMLScriptElement} tags with the CSP
* nonce so the browser allows the inline init code on first paint.
*
* @param props - Component properties
* @param props.clientId - OpenPanel client ID from the dashboard
* @param props.nonce - CSP nonce for inline scripts
* @returns Script elements for OpenPanel init and SDK, or null if no clientId
*/
export function OpenPanelAnalyticsComponent({ clientId, nonce }: OpenPanelAnalyticsProps) {
if (!clientId) {
return null
}
const initOptions = JSON.stringify({
clientId,
trackScreenViews: true,
trackOutgoingLinks: true,
trackAttributes: true,
apiUrl: '/api/op',
sdk: 'nextjs',
sdkVersion: '1.3.0'
})
const globalProps = JSON.stringify({
environment: process.env.NODE_ENV ?? 'development'
})
const initScript = [
OPENPANEL_QUEUE_SNIPPET,
`window.op('init',${initOptions});`,
`window.op('setGlobalProperties',${globalProps});`
].join('\n')
return (
<>
>
)
}