2
 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?

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
  • What is `document not found` error? Could you post it here? – Danila Feb 18 '21 at 07:19
  • Server Error ReferenceError: document is not defined This error happened while generating the page. Any console logs will be displayed in the terminal window. Call Stack insertStyleElement file:/home/tesla/Documents/projects/portfolio/client/node_modules/monaco-jsx-highlighter/dist/webpack:/monaco-jsx-highlighter/node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js (93:15) – Yilmaz Feb 18 '21 at 07:28
  • @Danila since there is a pending edit, I cannot edit the question. – Yilmaz Feb 18 '21 at 07:28
  • Seems like the problem is that highlighter is client side only component 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, it should work. – Danila Feb 18 '21 at 07:41
  • @Danila Highlighter is a class . How can I import it in HighlighterWrapper? – Yilmaz Feb 18 '21 at 07:49
  • Like you always do, `import Highlighter from "monaco-jsx-highlighter";` – Danila Feb 18 '21 at 07:56
  • @Danila If I did not misunderstood you I created a ts file. `import Highlighter from "monaco-jsx-highlighter"; export default Highlighter; ` then I dynamically import it to he file but i still got a Loadable Component – Yilmaz Feb 18 '21 at 08:40
  • Yes, you misunderstood, I'll make an answer – Danila Feb 18 '21 at 08:56

3 Answers3

3

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>
  );
}
Danila
  • 15,606
  • 2
  • 35
  • 67
2

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 />
}
Peter
  • 1,280
  • 8
  • 15
  • What that means? – Peter Feb 18 '21 at 08:19
  • @Peter that means, the module that you import should be a component. But in this case Highlighter is a class, so dynamic import does not work – Yilmaz Feb 18 '21 at 08:32
  • Then create a standalone `Component`, write the business logic how should the Highlighter work, and import that `Component` `dynamicly` to the current page. – Peter Feb 18 '21 at 08:43
  • Sec, Im updating my answer – Peter Feb 18 '21 at 08:44
  • @Yilmaz I have updated my answer, and also check out, how `dynamic(()=> import(), {})` works – Peter Feb 18 '21 at 08:50
  • @Peter Thank you for your answer. I upvoted both answers :) However I still have an issue and currently cannot update the question due to a pending edit. it is 5am here and I will hopefully be able to update the question when I wake up – Yilmaz Feb 18 '21 at 09:37
0

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;
});
Yilmaz
  • 35,338
  • 10
  • 157
  • 202