react-quill icon indicating copy to clipboard operation
react-quill copied to clipboard

React Quill in NextJS

Open TheDarkStrix opened this issue 4 years ago • 4 comments

Uncaught TypeError: Cannot read property 'options' of undefined
    at areAllDependenciesMet (mathquill4quill.js:58)
    at enableMathQuillFormulaAuthoring (mathquill4quill.js:340)

My source Code : https://pastebin.com/bDP84zcs

Screenshot of the error : https://ibb.co/42w5sNn

Not sure what is wrong here , any insights to get this working is very much appreciated .

I am also using mathquill4quill.

I am using NEXTJS

ReactQuill version

  • v2.0.0-beta.2

TheDarkStrix avatar Apr 16 '21 09:04 TheDarkStrix

@TheDarkStrix Have you tried putting the whole editor in a separate module, e.g. MyEditor.tsx and then lazy loading the it? Simplified:

Page module ~/pages/index.ts:

import dynamic from "next/dynamic";
const MyEditor = dynamic(() => import("../components/MyEditor");

// ...

export default function IndexPage(){
    return <MyEditor/>
}

View module: ~/components/MyEditor.tsx

import ReactQuill from "react-quill";
import Quill from "quill";

export default function MyEditor(){
    const [value, setValue] = useState("");
    const quillRef = useRef();
 
    useEffect(() => {
      const katex = window.katex;
      console.log(quillRef.current);
      let enableMathQuillFormulaAuthoring = mathquill4quill({ Quill });
      enableMathQuillFormulaAuthoring(quillRef.current.editor);
    }, [quillRef]);

    // ...

    return <ReactQuill />;
}

flaming-codes avatar Aug 08 '21 21:08 flaming-codes

Also, you're using the script-tag in a page, please move it to the _document.tsx, Documentation

flaming-codes avatar Aug 08 '21 21:08 flaming-codes

Thank you for your response, I ended up implementing like this, but still have issues with registering quill libraries

import React, { useState, useRef, useEffect } from "react";

// KaTeX dependency
import katex from "katex";
import "katex/dist/katex.css";

// Quill dependency
const Quill =
  typeof window === "object" ? require("react-quill").Quill : () => false;
const ReactQuill =
  typeof window === "object" ? require("react-quill") : () => false;
import "react-quill/dist/quill.snow.css";

// MathQuill dependency
import "jquery";
typeof window === "object"
  ? require("mathquill/build/mathquill.js")
  : () => false;
import "mathquill/build/mathquill.css";

const mathquill4quill =
  typeof window === "object" ? require("mathquill4quill") : () => false;
import "mathquill4quill/mathquill4quill.css";

//Global definition
if (typeof window !== "undefined") {
  window.Quill = Quill;
  window.katex = katex;
}

export default function QuillPage() {
  const [load, setLoad] = useState(true);
  const [value, setValue] = useState("");
  const quillRef = useRef();

  useEffect(() => {
    // window.Quill = Quill;
    window.katex = katex;

    const enableMathQuillFormulaAuthoring = mathquill4quill({ Quill, katex });
    console.log(window);
    enableMathQuillFormulaAuthoring(
      quillRef.current.editor,
      {
        operators: [
          ["\\pm", "\\pm"],
          ["\\sqrt{x}", "\\sqrt"],
          ["\\sqrt[n]{x}", "\\nthroot"],
          ["\\frac{x}{y}", "\\frac"],
          ["\\sum^{s}_{x}{d}", "\\sum"],
          ["\\prod^{s}_{x}{d}", "\\prod"],
          ["\\coprod^{s}_{x}{d}", "\\coprod"],
          ["\\int^{s}_{x}{d}", "\\int"],
          ["\\binom{n}{k}", "\\binom"],
          ["\\log{x}", "\\log"],
        ],

        displayHistory: true, // defaults to false
        historyCacheKey: "__my_app_math_history_cachekey_", // optional
        historySize: 20, // optional (defaults to 10)
      },
      quillRef.current.options
    );
    setLoad(false);
  }, [quillRef]);

  useEffect(() => {
    console.log(value);
  }, [value]);

  const imageHandler = () => {
    console.log("image");
  };

  return (
    <>
      <ReactQuill
        ref={quillRef}
        modules={{
          formula: true,
          toolbar: [["formula", "image"]],
        }}
        theme="snow"
        value={value}
        onChange={setValue}
      />
    </>
  );
}

TheDarkStrix avatar Aug 16 '21 07:08 TheDarkStrix

The simplest way is with dynamic import importing only when is not in server

const ISSERVER = window === "undefined";

if (!ISSERVER) {
    const EditorComponent = dynamic(() => import("../EditorComponent"));
  }

render (
<>
{!ISSERVER && (
              <EditorComponent></EditorComponent>
            )}
</>
)

jrsanchezalcala avatar Mar 22 '22 21:03 jrsanchezalcala