feat(analytics): update Google Analytics integration and improve fetch interception

- Refactored Google Analytics proxy routes in the Next.js configuration to enhance fallback handling.
- Improved fetch interception logic in the RootLayout component for more robust handling of Google Analytics requests, including support for `sendBeacon`.
- Updated the analytics script source to align with new API routes for better tracking accuracy.
This commit is contained in:
Evandro Fonseca Junior committed 2026-01-20 21:10:39 -03:00
1 parent ad6a76efdd
commit c9b057b674
4 files changed
+154 -19

No files matched your search

+39 -7
View File
@@ -201,11 +201,19 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
dangerouslySetInnerHTML={{
__html: `
(function() {
// Interceptar fetch
// Interceptar fetch - método mais robusto
const originalFetch = window.fetch;
window.fetch = function(url, options) {
if (typeof url === 'string' && url.includes('google-analytics.com')) {
url = url.replace('https://www.google-analytics.com', '/ga');
if (typeof url === 'string') {
// Interceptar google-analytics.com/g/collect
if (url.includes('google-analytics.com/g/collect')) {
const urlObj = new URL(url);
url = '/api/metrics' + urlObj.search;
}
// Interceptar outros endpoints do google-analytics.com
else if (url.includes('google-analytics.com')) {
url = url.replace(/https?:\\/\\/[^\\/]*google-analytics\\.com/g, '/api/metrics');
}
}
return originalFetch.call(this, url, options);
};
@@ -213,18 +221,39 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
// Interceptar XMLHttpRequest
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
if (typeof url === 'string' && url.includes('google-analytics.com')) {
url = url.replace('https://www.google-analytics.com', '/ga');
if (typeof url === 'string') {
if (url.includes('google-analytics.com/g/collect')) {
const urlObj = new URL(url);
url = '/api/metrics' + urlObj.search;
}
else if (url.includes('google-analytics.com')) {
url = url.replace(/https?:\\/\\/[^\\/]*google-analytics\\.com/g, '/api/metrics');
}
}
return originalOpen.call(this, method, url, ...rest);
};
// Interceptar sendBeacon (método usado pelo GA4)
const originalSendBeacon = navigator.sendBeacon;
navigator.sendBeacon = function(url, data) {
if (typeof url === 'string') {
if (url.includes('google-analytics.com/g/collect')) {
const urlObj = new URL(url);
return originalSendBeacon.call(this, '/api/metrics' + urlObj.search, data);
}
else if (url.includes('google-analytics.com')) {
url = url.replace(/https?:\\/\\/[^\\/]*google-analytics\\.com/g, '/api/metrics');
}
}
return originalSendBeacon.call(this, url, data);
};
})();
`,
}}
/>
{/* Google Analytics - Script principal via proxy */}
<Script
src="/gtm/js/G-QTT9QT0T3S"
src="/api/gtm/G-QTT9QT0T3S"
strategy="afterInteractive"
async
/>
@@ -237,7 +266,10 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-QTT9QT0T3S');
gtag('config', 'G-QTT9QT0T3S', {
// Forçar uso de fetch em vez de imagem beacon
transport_type: 'fetch'
});
`,
}}
/>