Skip to content

Instantly share code, notes, and snippets.

@ArrayIterator
Last active February 24, 2025 03:26
Show Gist options
  • Save ArrayIterator/fd0e9b7a112fddbd49bd4e07735c785b to your computer and use it in GitHub Desktop.
Save ArrayIterator/fd0e9b7a112fddbd49bd4e07735c785b to your computer and use it in GitHub Desktop.

Revisions

  1. ArrayIterator revised this gist Feb 24, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion AdsenseJS.tsx
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@ import React from 'react';

    const IS_SSR = typeof window !== 'object' || !window || typeof window.document !== 'object';
    const GOOGLE_JS_URI = '//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
    const GOOGLE_JS = `https://${GOOGLE_JS_URI}`;
    const GOOGLE_JS = `https:${GOOGLE_JS_URI}`;
    const ID = 'adsense-js-script';
    const loaded = IS_SSR || (
    (document.querySelector(`script#${ID}`) as HTMLScriptElement)
  2. ArrayIterator revised this gist Feb 23, 2025. 1 changed file with 14 additions and 10 deletions.
    24 changes: 14 additions & 10 deletions Adsense.tsx
    Original file line number Diff line number Diff line change
    @@ -30,16 +30,20 @@ export function Adsense(props: {
    if (!mounted) {
    return;
    }
    if (adSlotRef.current
    && undefined === (adSlotRef.current as HTMLModElement&{
    pushed?: boolean
    }).pushed) {
    (window.adsbygoogle = window.adsbygoogle || []);
    window.adsbygoogle.push({});
    Object.defineProperty(adSlotRef.current, 'pushed', {
    value: true,
    writable: false,
    })
    try {
    if (adSlotRef.current
    && undefined === (adSlotRef.current as HTMLModElement & {
    pushed?: boolean
    }).pushed) {
    (window.adsbygoogle = window.adsbygoogle || []);
    window.adsbygoogle.push({});
    Object.defineProperty(adSlotRef.current, 'pushed', {
    value: true,
    writable: false,
    })
    }
    } catch {
    // do nothing
    }
    }, [adSlotRef.current, mounted]);

  3. ArrayIterator created this gist Feb 23, 2025.
    69 changes: 69 additions & 0 deletions Adsense.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    import React, {createRef, useEffect, useState} from 'react';
    import {CSSProperties, ReactNode} from 'react';
    import AdsenseJS from './AdsenseJS';

    declare var window: Window&{
    adsbygoogle: any[],
    };

    const IS_SSR = typeof window !== 'object' || !window || typeof window.document !== 'object';
    export function Adsense(props: {
    slot: string,
    client: string,
    className?: string,
    style?: CSSProperties,
    layout?: string,
    layoutKey?: string,
    format?: "auto" | "fluid",
    responsive?: "true" | "false",
    }) : ReactNode {
    const adSlotRef = createRef<HTMLModElement>();
    const [mounted, setMounted] = useState(IS_SSR);
    const {className, style, client, slot, layout, layoutKey, format, responsive} = {...props};

    useEffect(() => {
    setMounted(true); // for strict mode
    return () => setMounted(false);
    }, []);

    useEffect(() => {
    if (!mounted) {
    return;
    }
    if (adSlotRef.current
    && undefined === (adSlotRef.current as HTMLModElement&{
    pushed?: boolean
    }).pushed) {
    (window.adsbygoogle = window.adsbygoogle || []);
    window.adsbygoogle.push({});
    Object.defineProperty(adSlotRef.current, 'pushed', {
    value: true,
    writable: false,
    })
    }
    }, [adSlotRef.current, mounted]);

    if (!mounted) {
    return null;
    }

    return (
    <>
    <ins
    data-ad-slot={slot}
    data-ad-client={client}
    style={style || {}}
    className={className?.includes('adsbygoogle') ? className : `adsbygoogle ${className||''}`}
    data-full-width-responsive={responsive === 'true' ? 'true' : 'false'}
    data-ad-format={format || 'auto'}
    data-ad-layout-key={layoutKey || ''}
    data-ad-layout={layout || ''}
    ref={adSlotRef}
    />
    {/*include adsense-js once*/}
    <AdsenseJS/>
    </>
    )
    }

    // usage: <Adsense slot="1234567890" client="ca-pub-1234567890" className="adsbygoogle" style={{display: 'block'}} layout="in-article" format="fluid" responsive="true"/>
    59 changes: 59 additions & 0 deletions AdsenseJS.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    import {forwardRef, useEffect, useImperativeHandle, useRef, useState} from 'react';
    import React from 'react';

    const IS_SSR = typeof window !== 'object' || !window || typeof window.document !== 'object';
    const GOOGLE_JS_URI = '//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
    const GOOGLE_JS = `https://${GOOGLE_JS_URI}`;
    const ID = 'adsense-js-script';
    const loaded = IS_SSR || (
    (document.querySelector(`script#${ID}`) as HTMLScriptElement)
    ?.getAttribute('src')
    ?.split('#')[0].split('?')[0]
    .endsWith(GOOGLE_JS)
    || false
    );

    const AdsenseJS = forwardRef((props, ref) => {
    const [mounted, setMounted] = useState(IS_SSR);
    const [scriptLoaded, setScriptLoaded] = useState(loaded);
    const scriptRef = useRef<null|HTMLScriptElement>(null);

    useEffect(() => {
    setMounted(true);
    return () => setMounted(false);
    }, []);

    useEffect(() => {
    if (mounted && !scriptLoaded) {
    if (!scriptRef.current) {
    const script = document.createElement('script');
    script.id = 'adsense-js-script';
    script.async = true;
    script.src = GOOGLE_JS;
    script.crossOrigin = 'anonymous';
    script.onload = () => {
    setScriptLoaded(true);
    };
    scriptRef.current = script;
    document.head.appendChild(script);
    } else if (scriptRef.current.parentNode !== document.head) {
    document.head.appendChild(scriptRef.current);
    setScriptLoaded(true);
    } else {
    setScriptLoaded(true);
    }
    }
    }, [mounted, scriptLoaded]);

    useImperativeHandle(ref, () => ({
    isLoaded: scriptLoaded,
    reload: () => {},
    }));

    if (IS_SSR) {
    return <script id={ID} src={GOOGLE_JS} async crossOrigin="anonymous"/>;
    }
    return null;
    });

    export default AdsenseJS;