Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workaround for Next.JS error "referenceError: document is not defined" for an external library component?

I am having some troubles integrating a component from the outside library 'react-calendly', the PopUpButton widget specifically, that requires the parent DOM node to be inserted into. My current understanding is that my issue is being caused by the fact that Next.js uses SSR and therefore I do not have access to the browser. How can I work around this? For reference, my website is a very simple fullstack app for his business and I am new to React/full-stack development. Here is the code for the app portion that renders my page components:

import '../styles/globals.css'
import styles from '../styles/App.module.css'
import Navbar from '../components/navbar'
import Footer from '../components/footer'

function MyApp({Component, pageProps}) {

  return (
    <div className={styles.app}>
      <div>
        <Navbar />
      </div>
      <div className={styles.body} id="body">
        <Component props={pageProps} />
      </div>
      <div>
        <Footer className={styles.footer}/>
      </div>
    </div>
  )
}

export default MyApp

And here is the code for my specific page component:

import styles from '../styles/Home.module.css'
import Head from 'next/head'
import { PopupButton } from 'react-calendly'

export default function Home() {
  
  return (
    <div className="home">
      <Head>
        <title>Homepage</title>
      </Head>
      <div className="cal_div">

        <PopupButton
          url="https://calendly.com/my_url"
          rootElement={document.getElementsById("body")}
          text="Click here to schedule!"
        />
      </div>
    </div> 
  )
}

like image 631
lukedawg Avatar asked Jun 25 '26 18:06

lukedawg


1 Answers

I actually managed to fix this issue for the exact same case next.js and react.js

The architecture is as follow:

1. Calendly calling react component -> 2. dynamic calendly __next component -> 3. calendly child

1. The React Parent Component:

'use client';
import React from "react";
import CalendlyDynamic from "./Components/CalendlyDynamic";

export default function Home(){

return (
        <div>
             <CalendlyDynamic />
             <div id="__next"></div>
        </div>
)}

1. -> 2. The Calendly dynamic Component:

import dynamic from "next/dynamic";

const Calendly = dynamic(() => import("../Components/Calendly"), {
  ssr: false
});


export default function Home() {
  return (
    <div>
      <Calendly />
    </div>
  );
}

2. -> 3. The Calendly Child

'use client'
import { PopupButton } from "react-calendly";
import { useEffect, useState } from "react";

export default function Calendly() {
  const [rootElement, setRootElement] = useState(null);

  useEffect(() => {
    // Wait for the component to be mounted before setting the rootElement
    if (typeof window !== "undefined") {
      setRootElement(document.getElementById("__next"));
    }
  }, []);

  return (
    <div className="cal_div">
      <PopupButton
        className="rounded-md bg-primary py-4 px-8 text-base font-semibold text-white duration-300 ease-in-out hover:bg-primary/80"
        url="https://calendly.com/your-link"
        rootElement={rootElement}
        text="Schedule Appointment"
      />
    </div>
  );
}
like image 182
Julia Avatar answered Jun 28 '26 14:06

Julia



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!