reactjsnext.jsscript-tag

How to maintain script tag position on webpage?


I am using a script tag to add a widget to my Next.js app. I have create a section component for this widget but when I run the app it renders below my footer but it is supposed to render above as a section component. Can someone help me out with this, please?

Below you will see the screenshot of the issue, my index.js, the script component and the component where I hope it would be rendered. Another user asked a question related to the same issue. Is there anyone that knows how to fix it?

enter image description here

import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.scss'
import Header from './src/components/Header'
import Services from './src/components/Services'
import Portfolio from './src/components/Portfolio'
import ContactCard from './src/components/ContactCard'
import Booking from './src/components/Booking'

export default function Home() {
  return (
    <div className="container-fluid">
      <Head>
        <title>Dr Cut TheBarber Show</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />       
      </Head>
      <main className="main">
       <Header />
       <Services />
       <Portfolio />
       <ContactCard />
       <Booking />
      </main>

      <footer className="footer text-center">
        <a
          className="text-decoration-none text-dark"
          href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          Powered by{' '}
          <span className={styles.logo}>
            <Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
          </span>
        </a>
      </footer>
      </div>
    
  )
}

Booksy.js

import script from 'next/script';
//import Script from 'next/script'
import { useEffect } from 'react';
const Booksy = () =>{
    useEffect(() => {
        const script = document.createElement('script');
        script.src="https://booksy.com/widget/code.js?id=17618&country=es&lang=es";
        script.async = true;
        document.body.appendChild(script);
        return () => {
            document.body.removeChild(script);
        }
    }, [])
  return script
}

export default Booksy;

Booking.js

import Booksy from "./Booksy";

function Booking () {
    return (
        <div className="page-section">
            
                <Booksy />

        </div>
    )
}
export default Booking;

Solution

  • There's some problem with lack of a documentation of this Booksy widget but I had the same problem and here's the solution.

    This script always creating button exactly where you'll place it. So if you want to have in a specific place just create element and place script inside. Then you'll be able to change the position by positioning this element.

    So in Booking.js add id for a div like:

    <div id="booksy" className="page-section">
    

    And modify the place where you'll mount the script like:

    document.getElementById('booksy').appendChild(script)
    

    Now you should have the Booksy button inside this div and you can change the position of it using styles.

    Also if you want custom button for Booksy here's the trick:

    1. Do like before
    2. Add your custom button anywhere
    3. Using styles make booksy button invisible. In SCSS this would be like:
    #booksy {
       .booksy-widget-container {
            display: none !important;
       }
    }
    
    1. Using Javascript make onClick your custom button to trigger click() on invisible Booksy button:
    const openBooksy = () => {
        const button = document.querySelector(
          '#booksy > .booksy-widget-container > .booksy-widget-button'
        )
        button.click()
    }
    

    This will do the job.