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
This commit is contained in:
Ege Can Komur
2026-05-20 18:51:38 +03:00
parent 9d74cceb69
commit 69f0c857ec
+17 -15
View File
@@ -1,16 +1,14 @@
import Script from "next/script";
/**
* Google Consent Mode v2 — defaults set to "denied" before any tag loads.
* After the user makes a choice, CookieBanner calls gtag('consent','update', ...).
*
* GTM/GA inject sadece site_settings.gtm_id doluysa yapılır.
* 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 }) {
return (
<>
<Script id="consent-default" strategy="beforeInteractive">
{`
const defaultConsent = `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
window.gtag = gtag;
@@ -24,19 +22,23 @@ export function ConsentInit({ gtmId }: { gtmId?: string | null }) {
security_storage: 'granted',
wait_for_update: 500,
});
`}
</Script>
`;
{gtmId && (
<>
<Script id="gtm-script" strategy="afterInteractive">
{`
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}');
`}
</Script>
`
: null;
return (
<>
<script dangerouslySetInnerHTML={{ __html: defaultConsent }} />
{gtmSnippet && (
<>
<script dangerouslySetInnerHTML={{ __html: gtmSnippet }} />
<noscript>
<iframe
src={`https://www.googletagmanager.com/ns.html?id=${gtmId}`}