1

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

LuisEnMarroquin
  • 1,609
  • 1
  • 14
  • 26

1 Answers1

4

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;
// 
// };
Mark G
  • 1,868
  • 1
  • 6
  • 15
  • If I do this I won't be able to do `client.open(URL)` inside a button `onClick`. TS says: `Property 'open' does not exist on type 'Element'.ts(2339)` – LuisEnMarroquin Mar 24 '22 at 22:29
  • Also how can I add types to the `client` object? – LuisEnMarroquin Mar 24 '22 at 22:41
  • @LuisMarroquin That non-existent property error is separate from the non-constructor error in the original question, so we'll need more details (or maybe a separate question; I don't know anything about `hellosign-embedded`'s implementation). If you want to explicitly annotate `client`, you could do something like `client: ReactElement | null`, but that now depends on whether this answer still works for you or not (because of said non-existent property error). – Mark G Mar 24 '22 at 22:55
  • @LuisMarroquin Please see updated answer. – Mark G Mar 25 '22 at 01:06
  • According to [HelloSign docs](https://app.hellosign.com/api/embeddedSigningWalkthrough) `hellosign-embedded` should be used as a constructor `const client = new HelloSign()` so then I can open an iFrame `client.open(signUrl, { clientId: 'Your API client ID'; });`. It doesn't make sense to make it into a component because it's useless if I can't open the document – LuisEnMarroquin Mar 25 '22 at 16:57
  • @LuisMarroquin Did you try the example from my updated answer? It worked on my end. – Mark G Mar 25 '22 at 17:10
  • I tried that example. It compiles, but it makes no sense to be able to compile if I can't use the library for it's main purpose of openning a Document to sign with `client.open(signUrl)` – LuisEnMarroquin Mar 25 '22 at 17:16
  • @LuisMarroquin I think you're still looking at the "old" answer. I'm using `client.open("https://www.example.com")` there in the update (the top code block) -- you have to change the placeholder URL I have in there with the real one. – Mark G Mar 25 '22 at 17:18
  • Sorry, I was confused and think that the last answer was the correct one. But that totally did the trick, I was able to run in dev mode and also build the app. Thanks!!! – LuisEnMarroquin Mar 25 '22 at 18:06