feat: integrate Google Analytics event tracking and update CSP for script sources (#30365)

Co-authored-by: CodingOnStar <hanxujiang@dify.ai>
This commit is contained in:
Coding On Star
2025-12-30 18:06:47 +08:00
committed by GitHub
parent bf76f10653
commit 6ca44eea28
6 changed files with 125 additions and 24 deletions

View File

@ -68,6 +68,7 @@ const AmplitudeProvider: FC<IAmplitudeProps> = ({
pageViews: true,
formInteractions: true,
fileDownloads: true,
attribution: true,
},
})

View File

@ -1,3 +1,4 @@
import type { UnsafeUnwrappedHeaders } from 'next/headers'
import type { FC } from 'react'
import { headers } from 'next/headers'
import Script from 'next/script'
@ -18,45 +19,54 @@ export type IGAProps = {
gaType: GaType
}
const GA: FC<IGAProps> = async ({
const extractNonceFromCSP = (cspHeader: string | null): string | undefined => {
if (!cspHeader)
return undefined
const nonceMatch = cspHeader.match(/'nonce-([^']+)'/)
return nonceMatch ? nonceMatch[1] : undefined
}
const GA: FC<IGAProps> = ({
gaType,
}) => {
if (IS_CE_EDITION)
return null
const nonce = process.env.NODE_ENV === 'production' ? (await headers()).get('x-nonce') ?? '' : ''
const cspHeader = process.env.NODE_ENV === 'production'
? (headers() as unknown as UnsafeUnwrappedHeaders).get('content-security-policy')
: null
const nonce = extractNonceFromCSP(cspHeader)
return (
<>
<Script
strategy="beforeInteractive"
async
src={`https://www.googletagmanager.com/gtag/js?id=${gaIdMaps[gaType]}`}
nonce={nonce ?? undefined}
>
</Script>
{/* Initialize dataLayer first */}
<Script
id="ga-init"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gaIdMaps[gaType]}');
window.dataLayer = window.dataLayer || [];
window.gtag = function gtag(){window.dataLayer.push(arguments);};
window.gtag('js', new Date());
window.gtag('config', '${gaIdMaps[gaType]}');
`,
}}
nonce={nonce ?? undefined}
>
</Script>
nonce={nonce}
/>
{/* Load GA script */}
<Script
strategy="afterInteractive"
src={`https://www.googletagmanager.com/gtag/js?id=${gaIdMaps[gaType]}`}
nonce={nonce}
/>
{/* Cookie banner */}
<Script
id="cookieyes"
strategy="lazyOnload"
src="https://cdn-cookieyes.com/client_data/2a645945fcae53f8e025a2b1/script.js"
nonce={nonce ?? undefined}
>
</Script>
nonce={nonce}
/>
</>
)
}
export default React.memo(GA)