@@ -28,6 +28,7 @@ export interface MarkdownRenderProps {
2828 codeTheme ?: string ;
2929 onConvertFinish ?: ( html : string ) => any ;
3030 editing ?: boolean ;
31+ shouldShowAds ?: boolean ;
3132}
3233
3334function sanitizeEventScript ( htmlString : string ) {
@@ -208,6 +209,7 @@ const MarkdownRender: React.FC<MarkdownRenderProps> = ({
208209 codeTheme = 'atom-one' ,
209210 onConvertFinish,
210211 editing,
212+ shouldShowAds = false ,
211213} ) => {
212214 const [ html , setHtml ] = useState (
213215 ssrEnabled
@@ -232,6 +234,8 @@ const MarkdownRender: React.FC<MarkdownRenderProps> = ({
232234 const [ element , setElement ] = useState < RenderedElement > ( null ) ;
233235 const [ hasTagError , setHasTagError ] = useState ( false ) ;
234236 const [ delay , setDelay ] = useState ( 25 ) ;
237+ const [ hasEnoughBlock , setHasEnoughBlock ] = useState ( false ) ;
238+ const [ htmlWithAds , setHtmlWithAds ] = useState ( '' ) ;
235239
236240 const throttledUpdate = React . useMemo ( ( ) => {
237241 return throttle ( delay , ( markdown : string ) => {
@@ -288,6 +292,76 @@ const MarkdownRender: React.FC<MarkdownRenderProps> = ({
288292 throttledUpdate ( markdown ) ;
289293 } , [ markdown , throttledUpdate ] ) ;
290294
295+ useEffect ( ( ) => {
296+ if ( ! shouldShowAds || ! html ) {
297+ setHtmlWithAds ( '' ) ;
298+ return ;
299+ }
300+
301+ const parser = new DOMParser ( ) ;
302+ const doc = parser . parseFromString ( html , 'text/html' ) ;
303+ const blockElements = doc . querySelectorAll ( 'p, h1, h2, h3, h4, h5, h6, blockquote, pre, ul, ol, hr, table' ) ;
304+
305+ console . log ( 'Total blocks:' , blockElements . length ) ;
306+
307+ const hasEnough = blockElements . length >= 20 ;
308+ setHasEnoughBlock ( hasEnough ) ;
309+ console . log ( 'hasEnoughBlock:' , hasEnough ) ;
310+
311+ if ( hasEnough ) {
312+ // Find the position to insert ad
313+ let targetBlock = null ;
314+ let insertPosition = 19 ; // 20th block (0-based index)
315+
316+ // Look for first h1, h2, h3 after 20th block
317+ for ( let i = 20 ; i < blockElements . length && i < 50 ; i ++ ) {
318+ const block = blockElements [ i ] ;
319+ if ( block . tagName === 'H1' || block . tagName === 'H2' || block . tagName === 'H3' ) {
320+ targetBlock = block ;
321+ insertPosition = i ;
322+ break ;
323+ }
324+ }
325+
326+ // If heading found and before index 50, insert before it
327+ // Otherwise insert after 20th block
328+ const blockToInsertAfter = targetBlock
329+ ? blockElements [ insertPosition - 1 ]
330+ : blockElements [ 19 ] ;
331+
332+ if ( blockToInsertAfter ) {
333+ const adDiv = doc . createElement ( 'ins' ) ;
334+ adDiv . className = 'adsbygoogle' ;
335+ adDiv . style . display = 'block' ;
336+ adDiv . style . textAlign = 'center' ;
337+ adDiv . setAttribute ( 'data-ad-layout' , 'in-article' ) ;
338+ adDiv . setAttribute ( 'data-ad-format' , 'fluid' ) ;
339+ adDiv . setAttribute ( 'data-ad-client' , 'ca-pub-5574866530496701' ) ;
340+ adDiv . setAttribute ( 'data-ad-slot' , '9632367492' ) ;
341+
342+ // Insert after the target block (or before heading if found)
343+ if ( targetBlock ) {
344+ targetBlock . parentNode ?. insertBefore ( adDiv , targetBlock ) ;
345+ } else {
346+ blockToInsertAfter . parentNode ?. insertBefore ( adDiv , blockToInsertAfter . nextSibling ) ;
347+ }
348+
349+ // Set the modified HTML
350+ const updatedHtml = doc . body . innerHTML ;
351+ setHtmlWithAds ( updatedHtml ) ;
352+
353+ // Push ad after 1 second
354+ setTimeout ( ( ) => {
355+ ( window . adsbygoogle = window . adsbygoogle || [ ] ) . push ( { } ) ;
356+ } , 1000 ) ;
357+ } else {
358+ setHtmlWithAds ( '' ) ;
359+ }
360+ } else {
361+ setHtmlWithAds ( '' ) ;
362+ }
363+ } , [ html , shouldShowAds ] ) ;
364+
291365 return (
292366 < Typography >
293367 < Helmet >
@@ -312,7 +386,7 @@ const MarkdownRender: React.FC<MarkdownRenderProps> = ({
312386 ) : (
313387 < MarkdownRenderBlock
314388 className = { codeTheme }
315- dangerouslySetInnerHTML = { { __html : html } }
389+ dangerouslySetInnerHTML = { { __html : htmlWithAds || html } }
316390 />
317391 ) }
318392 </ Typography >
0 commit comments