33import { faClose } from '@fortawesome/free-solid-svg-icons' ;
44import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
55import Script from 'next/script' ;
6- import { useEffect , useState } from 'react' ;
6+ import { useEffect , useRef , useState } from 'react' ;
77
88import { 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