Files
kovakyazilim/components/consent-init.tsx
T
Ege Can Komur 69f0c857ec fix: next/script yerine dangerouslySetInnerHTML kullan (React 19 uyumu)
Sorun:
React 19 + Next.js 16'da next/script componenti inline scripts (children
ile) için 'Encountered a script tag while rendering React component'
hatası veriyor. <script> child node React'ta artık warning üretiyor.

Çözüm:
ConsentInit'te next/script yerine düz <script dangerouslySetInnerHTML>
kullanıyoruz. Bu inline script HTML parse edildiği anda çalışır —
beforeInteractive davranışını taklit eder, hatta daha güvenilir.

Avantaj:
- gtag('consent','default') hiçbir analytics scripti yüklenmeden önce
  kaydedilir (Google Consent Mode v2 zorunluluğu)
- GTM snippet'i de aynı şekilde body'nin başında çalışır
- noscript fallback iframe korundu
2026-05-20 18:51:38 +03:00

55 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Google Consent Mode v2 — defaults set to "denied" before any tag loads.
* After the user makes a choice, CookieBanner calls gtag('consent','update', ...).
*
* Next.js 16 / React 19'da `next/script` inline scripts ile sorunlu olduğu için
* doğrudan <script dangerouslySetInnerHTML> kullanıyoruz. Script senkron olarak
* HTML parse edildiği anda çalışır — gtag('consent','default') hiçbir analytics
* scripti yüklenmeden önce kaydedilir.
*/
export function ConsentInit({ gtmId }: { gtmId?: string | null }) {
const defaultConsent = `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
window.gtag = gtag;
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
functionality_storage: 'granted',
personalization_storage: 'denied',
security_storage: 'granted',
wait_for_update: 500,
});
`;
const gtmSnippet = gtmId
? `
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','${gtmId}');
`
: null;
return (
<>
<script dangerouslySetInnerHTML={{ __html: defaultConsent }} />
{gtmSnippet && (
<>
<script dangerouslySetInnerHTML={{ __html: gtmSnippet }} />
<noscript>
<iframe
src={`https://www.googletagmanager.com/ns.html?id=${gtmId}`}
height="0"
width="0"
style={{ display: "none", visibility: "hidden" }}
/>
</noscript>
</>
)}
</>
);
}