Skip to content

Commit 23569c4

Browse files
committed
fix: enhance ad initialization logic in AdSlots component
- Added useRef to manage ad element reference and track initialization state. - Implemented logic to reset ad initialization when the ad is hidden or shown. - Introduced a retry mechanism with a maximum count to ensure ads are initialized correctly based on element dimensions. - Utilized ResizeObserver to monitor ad element size and trigger initialization when dimensions are available. - Improved error handling during ad initialization to prevent issues with uninitialized ads.
1 parent 063188b commit 23569c4

File tree

1 file changed

+103
-7
lines changed
  • apps/frontend/src/modules/shared/components/client/ads

1 file changed

+103
-7
lines changed

apps/frontend/src/modules/shared/components/client/ads/AdSlots.tsx

Lines changed: 103 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { faClose } from '@fortawesome/free-solid-svg-icons';
44
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
55
import Script from 'next/script';
6-
import { useEffect, useState } from 'react';
6+
import { useEffect, useRef, useState } from 'react';
77

88
import { cn } from '@web/lib/utils';
99

@@ -53,16 +53,111 @@ const AdTemplate = ({
5353
const pubId = useAdSenseClient();
5454

5555
const [isHidden, setIsHidden] = useState(false);
56+
const adRef = useRef<HTMLModElement>(null);
57+
const [isAdInitialized, setIsAdInitialized] = useState(false);
5658

59+
// Reset initialization state when ad is hidden/shown
5760
useEffect(() => {
58-
if (window) {
59-
try {
60-
(window.adsbygoogle = window.adsbygoogle || []).push({});
61-
} catch (e) {
62-
console.error(e);
61+
if (isHidden) {
62+
setIsAdInitialized(false);
63+
}
64+
}, [isHidden]);
65+
66+
useEffect(() => {
67+
if (!pubId || isHidden || isAdInitialized || !adRef.current) {
68+
return;
69+
}
70+
71+
let isInitializing = false;
72+
let retryCount = 0;
73+
const maxRetries = 50; // 5 seconds max (50 * 100ms)
74+
75+
const initializeAd = () => {
76+
const adElement = adRef.current;
77+
if (!adElement || isInitializing || isAdInitialized) {
78+
return;
79+
}
80+
81+
// Check if ad is already initialized by AdSense
82+
const adStatus = adElement.getAttribute('data-adsbygoogle-status');
83+
if (
84+
adStatus === 'done' ||
85+
adStatus === 'filled' ||
86+
adStatus === 'unfilled'
87+
) {
88+
setIsAdInitialized(true);
89+
return;
6390
}
91+
92+
// Check if the element has dimensions
93+
const rect = adElement.getBoundingClientRect();
94+
if (rect.width === 0 || rect.height === 0) {
95+
retryCount++;
96+
if (retryCount < maxRetries) {
97+
// Retry after a short delay if element has no dimensions
98+
setTimeout(initializeAd, 100);
99+
}
100+
return;
101+
}
102+
103+
// Check if adsbygoogle script is loaded
104+
if (typeof window !== 'undefined' && window.adsbygoogle) {
105+
isInitializing = true;
106+
try {
107+
// Double-check the element hasn't been initialized by another call
108+
const currentStatus = adElement.getAttribute(
109+
'data-adsbygoogle-status',
110+
);
111+
if (!currentStatus || currentStatus === '') {
112+
(window.adsbygoogle = window.adsbygoogle || []).push({});
113+
setIsAdInitialized(true);
114+
} else {
115+
setIsAdInitialized(true);
116+
}
117+
} catch (e) {
118+
console.error('AdSense initialization error:', e);
119+
isInitializing = false;
120+
}
121+
} else {
122+
retryCount++;
123+
if (retryCount < maxRetries) {
124+
// Wait for script to load
125+
setTimeout(() => {
126+
if (typeof window !== 'undefined' && window.adsbygoogle) {
127+
initializeAd();
128+
}
129+
}, 100);
130+
}
131+
}
132+
};
133+
134+
// Use ResizeObserver to wait for element to have dimensions
135+
const resizeObserver = new ResizeObserver((entries) => {
136+
for (const entry of entries) {
137+
if (entry.contentRect.width > 0 && entry.contentRect.height > 0) {
138+
initializeAd();
139+
resizeObserver.disconnect();
140+
break;
141+
}
142+
}
143+
});
144+
145+
if (adRef.current) {
146+
resizeObserver.observe(adRef.current);
64147
}
65-
}, []);
148+
149+
// Fallback: try after a delay even if ResizeObserver doesn't fire
150+
const timeoutId = setTimeout(() => {
151+
initializeAd();
152+
resizeObserver.disconnect();
153+
}, 500);
154+
155+
return () => {
156+
resizeObserver.disconnect();
157+
clearTimeout(timeoutId);
158+
isInitializing = false;
159+
};
160+
}, [pubId, isHidden, isAdInitialized]);
66161

67162
const InfoText = !pubId
68163
? () => (
@@ -85,6 +180,7 @@ const AdTemplate = ({
85180
{!isHidden && (
86181
<>
87182
<ins
183+
ref={adRef}
88184
className={cn('adsbygoogle', isHidden ? 'hidden' : '')}
89185
style={{
90186
display: 'block',

0 commit comments

Comments
 (0)