0

I'm creating website in Gatsby.js, and I want to open widget from Booksy, by onClick method. They gave me a script:

<script src="https://booksy.net/widget/code.js?id=9178&amp;country=pl&amp;lang=pl"></script>

How can I do that? Function document.write() doesn't work, its blocked by browser. I also tried conditional rendered iframe it works, but badly.

const StyledIframe = styled.iframe`
    width: 100vw;
    height: 100vh;
    position: absolute;
    z-index: 99999;
`;

const BooksyWidget = ({ isOpen }) => {
    const src = "https://booksy.com/widget/index.html?id=9178&lang=pl&country=pl&mode=dialog&theme=default"
    const Content = () => {
        return isOpen ? <StyledIframe src={ src }/> : null 
    }
    return (
        <>
            {Content()}
        </>      
    )
};

I want to get result when clicking 'Make an Appointment' button like on this website: http://gentlemanbarber.pl/ I guess my Iframe method can't provide this. So how can i do it?

Derek Nguyen
  • 11,294
  • 1
  • 40
  • 64
  • Hi Kamil, can you clarify what you mean by 'badly'? – Derek Nguyen Jul 19 '19 at 02:11
  • That doesn't seem to be a gatsby specific question. Maybe you find a solution here: https://stackoverflow.com/questions/34424845/adding-script-tag-to-react-jsx – friedger Jul 19 '19 at 08:39
  • Hi Derek, badly because this script should generate a button. So iframe is not good solution. Friedger thanks it helped, but not in 100%. Script now renders button but it disapears when I enter subpage and go back. – Kamil Dulęba Jul 19 '19 at 13:53

2 Answers2

0

Problem above is solved by this approach:

const LoadScript = () => {
    useEffect(() => {
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = 'https://booksy.net/widget/code.js?id=9178&country=pl&lang=pl';
        script.async = true; 
        document.getElementById('script').appendChild(script);
    }, []);

    return  <div id='script'></div>
}

Script renders a button in div. But when I go to 'http://localhost:8000/page-2/' and back to 'http://localhost:8000/', button disappears and console throws error: "Uncaught TypeError: Cannot read property 'src' of undefined". The same thing happens when I use class-based component and componentDidMount() method instead of hook. There is link to repository with code: https://github.com/kamilduleba/script How can I use this script to render button that doesn't disappear?

  • When id in script.src link is different each time, button renders every time I go back http://localhost:8000/. But this id has to be the same, beacuse it need to render widget from specific company. – Kamil Dulęba Jul 19 '19 at 19:19
0
const BooksyWidget = React.memo(() => {
  const booksyWidgetRef = React.useRef();
  React.useEffect(() => {
    if (!booksyWidgetRef.current) return
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://booksy.com/widget/code.js?id=123&country=pl&lang=pl';
    script.async = true;
    booksyWidgetRef.current.appendChild(script);

    // to prevent the following error after unmount and mount again:
    // Uncaught Error: [Booksy][widget][error] cannot locate current script
    return () => {
      if (!window.booksy) return;
      delete window.booksy;
    };
  }, []);

  return  <div ref={booksyWidgetRef}></div>
})

Optional:
To prevent content layout shift div should have min-height: 94px