How can I import browser module in next.js without dynamic import

Viewed 2153
 import Highlighter from "monaco-jsx-highlighter";

this import in next.js gives "document not found" error. So i tried to dynamically import

import dynamic from "next/dynamic";
const Highlighter = dynamic(import("monaco-jsx-highlighter"), { ssr: false });

However dynamic import returns Loadable Component. I checked the next-github and looks like dynamic import works only for components. But import Highlighter from "monaco-jsx-highlighter". Highlighter is actually a class and needs to be initialized as :

const highlighter = new Highlighter()

How can I use this module in next.js without dynamic import?

3 Answers

Seems like the problem is that highlighter has client side only code and cannot run on server with SSR. You could import it regularly into some other component, like HighlighterWrapper and then import HighlighterWrapper dynamically into your main component where you need it, then it should work.

import Highlighter from "monaco-jsx-highlighter";

export const HighligherWrapper = (props) => {
  // Make instance here or outside
  const highlighter = useMemo(() => new Highlighter(),[]);  

  // Do whatever you want here with highlighter instance

  return <div>Something</div>;
}

export default HighligherWrapper;
import dynamic from "next/dynamic";

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

const Page() {
  // Now you can use it in your code and it won't break SSR
  return (
    <div>
      <HighligherWrapper />
    </div>
  );
}

Try smt. like this:

/ClientSideComponent.js:

import Highlighter from "monaco-jsx-highlighter";

export default function ClientSideComponent(props){
    // Write here the Highlighter logic.
    return <>Highlighter</>;
}

/page.js:

import dynamic from "next/dynamic";
const ClientSideComponent = dynamic(()=> import("./ClientSideComponent.js"), { ssr: false });

function Page(props) {
    return <ClientSideComponent />
}

I solved the issue with the vanilla dynamic import instead of next.js dynamic import.

let jsxHighlighter = null;
import("monaco-jsx-highlighter").then((allMonacoSyntaxHighlighter) => {
  jsxHighlighter = allMonacoSyntaxHighlighter.default;
});
Related