reactjsdynamicreact-hooksnext.jshellosign-api

Can't make `hellosign-embedded` work with `next/dynamic` in TS project


as the title says I can't make hellosign-embedded work with next

My app will be served though a CDN, so I don't cake if it won't work with SSR

const HelloSign: any = dynamic(
  (): any => {
    return import("hellosign-embedded")
  },
  { ssr: false }
)

export default function Home() {

  const client =
    typeof window !== "undefined"
      ? new HelloSign({
          allowCancel: false,
          clientId: "HELLO SIGN CLIENT ID", // DEV HelloSign Client ID
          skipDomainVerification: true,
        })
      : null

  return null
}

I keep getting TypeError: HelloSign is not a constructor

errorImage

I also created this issue on GitHub with further information


Solution

  • Edit:

    I see now where things got confusing. hellosign-embedded references the window object (i.e., the import needs to be visible only during the client-side compilation phase). I saw that next/dynamic was being used to import a module. Since dynamic() returns a type of ComponentType and the containing client variable was inside the Home function, I had incorrectly assumed you were trying to import a React component.

    It turns out hellosign-embedded isn't even a React component at all so you shouldn't use next/dynamic. You should be able to use ES2020 imports instead. Your pages/index.tsx file will look something like this:

    import type { NextPage } from "next";
    
    const openDocument = async () => {
      // ES2020 dynamic import
      const HelloSign = (await import("hellosign-embedded")).default;
    
      const client = new HelloSign({
        allowCancel: false,
        clientId: "HELLO SIGN CLIENT ID", // DEV HelloSign Client ID
        skipDomainVerification: true,
      });
    
      client.open("https://www.example.com");
    };
    
    const Home: NextPage = () => {
      return <button onClick={() => openDocument()}>Open</button>;
    };
    
    export default Home;
    

    disregard old answer:

    HelloSign is of type ComponentType, so you can use the JSX element stored in the variable directly:

    // disregard: see edit above
    // export default function Home() {
    // 
    //   const client =
    //     typeof window !== "undefined" ? (
    //       <HelloSign
    //         allowCancel={false}
    //         clientId="HELLO SIGN CLIENT ID" // DEV HelloSign Client ID
    //         skipDomainVerification={true}
    //       />
    //     ) : null;
    // 
    //   return client;
    // 
    // };