2

I am trying to use WebViewer imported from "@pdftron/webviewer", code below marked as number 1 is code that I use in React.js app and it works fine, while code number 2 is code that I use in Next.js app that throws this error:

Unhandled Runtime Error TypeError: WebViewer is not a function

Code number 1 (used in React.js app):

import { useEffect, useRef } from "react";
import WebViewer from "@pdftron/webviewer";
import "./App.css";

export default function App() {
  const viewerDiv = useRef<HTMLDivElement>(null);
  useEffect(() => {
    WebViewer({ path: "./lib", initialDoc: "./sample.doc" }, viewerDiv.current as HTMLDivElement);
  }, []);
  return (
    <div>
      <div className="webviewer" ref={viewerDiv}></div>
    </div>
  );
}

Code number 2 (used in Next.js app):

import dynamic from "next/dynamic";
const WebViewer = dynamic(() => import("@pdftron/webviewer"), { ssr: false });
import { useEffect, useRef } from "react";

export default function Editor() {
  const viewerDiv = useRef(null);
  useEffect(() => {
    WebViewer(
      {
        path: "webviewer",
        initialDoc: "http://www.africau.edu/images/default/sample.pdf",
      },
      viewerDiv.current
    );
  }, []);
  return (
    <div>
      <div className={"webviewer"} ref={viewerDiv}></div>
    </div>
  );
}

Can somebody explain me why am I getting this error within Next.js app and how to fix it?

UPDATE: I went from js to ts in Next.js app also and got this warnings:

Argument of type '() => Promise<typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")>' is not assignable to parameter of type 'DynamicOptions | Loader'. Type '() => Promise<typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")>' is not assignable to type '() => LoaderComponent'. Type 'Promise<typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")>' is not assignable to type 'LoaderComponent'. Type 'typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")' is not assignable to type 'ComponentType | { default: ComponentType; }'. Type 'typeof import("/home/petar/Workspace/next-ts-editor/node_modules/@pdftron/webviewer/types")' is not assignable to type '{ default: ComponentType; }'. Types of property 'default' are incompatible. Type '(options: WebViewerOptions, viewerElement: HTMLElement) => Promise' is not assignable to type 'ComponentType'. Type '(options: WebViewerOptions, viewerElement: HTMLElement) => Promise' is not assignable to type 'FunctionComponent'. Type 'Promise' is missing the following properties from type 'ReactElement<any, any>': type, props, key

This expression is not callable. Not all constituents of type 'ComponentType' are callable. Type 'ComponentClass<WebViewerOptions, any>' has no call signatures.

1

1 Answer 1

2

I have managed to find a solution for this problem. This is a code snippet that works for me, please let me know if there is a better way.

import { useEffect, useRef } from "react";

export default function Editor() {
  const viewerDiv = useRef<HTMLDivElement>(null);
  const loadViewer = async () => {
    const WebViewer = (await import("@pdftron/webviewer")).default;
    WebViewer(
      {
        path: "lib",
        initialDoc: "./sample.pdf",
      },
      viewerDiv.current as HTMLDivElement
    );
  };
  useEffect(() => {
    loadViewer();
  }, []);
  return (
    <div>
      <div className={"webviewer"} ref={viewerDiv}></div>
    </div>
  );
}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.