Include a third party script in a functional component of react with server side rendering

Viewed 333

I'm having trouble inserting a third-party script inside a functional component with server-side rendering.

This is the script I should include in a normal HTML document.

<script class="feedaty_sdk" src="https://widget.feedaty.com/public/js/feedaty.js?merchant=******&style_ver=2021" async ></script><div class="feedaty_widget" data-ver="2021" data-id="61fee7f06c9b2" data-type="merchant" data-variant="150x100-1" data-lang="all" data-gui="all"></div>

Inside react I created a functional component and within useEffect, I created the script.

import { useEffect, useState } from 'react';

const FeedatyButton = () => {
 const [scriptLoaded, setScriptLoaded] = useState(false);

 useEffect(() => {
    const feedatyDiv = document.getElementById('feedatyScript');
    if (typeof window !== undefined && !scriptLoaded && !feedatyDiv) {
        const script = document.createElement('script');
        script.setAttribute('async', '');
        script.setAttribute('id', 'feedatyScript');
        script.src =
                'https://widget.feedaty.com/public/js/feedaty.js?merchant=******&style_ver=2021';
        script.addEventListener('load', () => setScriptLoaded(true));
        document.appendChild(script);
    }
  }, []);


  return (
        <div className='flex justify-end items-center' id='feedatyContainer'>
            <div
                className='feedaty_widget'
                data-ver='2021'
                data-id='61fee7f06c9b2'
                data-type='merchant'
                data-variant='150x100-1'
                data-lang='all'
                data-gui='all'></div>
        </div>
    );
};

export default FeedatyButton;

The script loads without problem, but nothing appears inside the feedaty_widget div.

If I create the div with createElement and append it to the document or the body, then it works, but it shows at the end of my react app and obviously, it's not what I want. I want to place it inside my functional component in a specific position.

What could be the problem?

1 Answers

I was wrong in approach, because I was not updating the component with the code generated by the "feedaty" script. This is the updated code using ref to update the content

import { useEffect, useState, useRef } from 'react';

const FeedatyButton = () => {
    const feedatyContainerRef = useRef();
    const [scriptLoaded, setScriptLoaded] = useState(false);

    useEffect(() => {
        scriptLoader();
        return () => {
            scriptUnloader();
        };
    }, []);

    useEffect(() => {
        if (!scriptLoaded) return;
    }, [scriptLoaded]);

    const scriptLoader = () => {
        window.addEventListener('load', scriptMover);
        const feedatyDiv = document.getElementById('feedatyScript');
        if (typeof window !== undefined && !feedatyDiv) {
            const script = document.createElement('script');
            script.src =
                'https://widget.feedaty.com/public/js/feedaty.js?merchant=1******&style_ver=2021';
            script.id = 'feedatyScript';
            script.async = true;
            document.body.appendChild(script);
        }
    };

    const scriptUnloader = () => {
        window.removeEventListener('load', scriptMover);
        const feedatyDiv = document.getElementById('feedatyScript');
        document.body.removeChild(document.querySelector('#feedatyScript')); 
    };

    // this function get called when script is loaded and i get the content of the widget, so i can update my component using ref
    const scriptMover = () => {
        const feedatyWidgetUpdated = document.getElementById('feedatyWidget');
        feedatyContainerRef.current.appendChild(feedatyWidgetUpdated);
        setScriptLoaded();
    };

    return (
        <div
            className='flex justify-end items-start'
            id='feedatyContainer'
            ref={feedatyContainerRef}>
            <div
                id='feedatyWidget'
                className='feedaty_widget'
                data-id='61fee7f06c9b7'
                data-type='merchant'
                data-variant='150x100-1'
                data-lang='it-IT'
                data-gui='it-IT'></div>
        </div>
    );
};

export default FeedatyButton;
Related