TypeError: moduleClass is not a constructor in React-Quill with Quill Mention Module
I'm encountering an error while integrating the quill-mention module with react-quill in a Next.js application. The error message I see is:
Unhandled Runtime Error TypeError: moduleClass is not a constructor
Call Stack
SnowTheme.addModule
(node_modules/react-quill/node_modules/quill/dist/quill.js (6130:0))
SnowTheme.addModule
(node_modules/react-quill/node_modules/quill/dist/quill.js (6774:0))
eval
(node_modules/react-quill/node_modules/quill/dist/quill.js (6122:0))
Array.forEach
Here is how I’m trying to use the quill-mention module: "use client"; import React, { Dispatch, SetStateAction, useEffect, useState } from "react"; import dynamic from "next/dynamic"; import Quill from "quill"; import Mention from "quill-mention"; import "react-quill/dist/quill.snow.css"; import { Button } from "@/components/ui/button"; import { Loader2 } from "lucide-react"; import TooltipCommon from "@/components/common/TooltipCommon"; import { useCopywriterStore } from "@/Store/CopywriterStore"; import { useUserStore } from "@/Store/UserStore"; import { useEditorStore } from "@/Store/EditorStore";
// Dynamically import ReactQuill to prevent SSR issues const ReactQuill = dynamic(() => import("react-quill"), { ssr: false });
interface QuillEditorProps {
customerId: string | string[];
updateId: string | string[];
indicatorText: string | string[];
handleEdit: string | string[];
orderId: string | string[];
productFlowId: string | string[];
leadId: string | string[];
technicalId: string | string[];
copywriterId: string | string[];
amendmentId: string | string[];
websiteContentId: string | string[];
setIsOpenReplyModel: Dispatch<SetStateAction
const QuillEditor: React.FC<QuillEditorProps> = ({
customerId,
setIsOpenReplyModel,
setOpenQuill,
updateId,
productFlowId,
orderId,
technicalId,
leadId,
indicatorText,
amendmentId,
copywriterId,
websiteContentId,
handleEdit,
handlesave,
editContent,
}: any) => {
const [value, setValue] = useState
const handleClear = () => { setValue(""); };
const handleChanges = (value: string, editorData: any) => { setValue(() => editorData.getText().trim() === "" && value === "" ? "" : value ); };
const handleAddData = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); if ((value !== "" && value !== "
if (indicatorText === "post") {
requests.push(
orderId && baseInstance.post(`/updates/order/${orderId}`, formData),
productFlowId &&
baseInstance.post(
`/updates/productflow/${productFlowId}`,
formData
),
customerId &&
baseInstance.post(`/updates/customer/${customerId}`, formData),
leadId && baseInstance.post(`/updates/lead/${leadId}`, formData),
technicalId &&
baseInstance.post(
`/updates/technicaltracker/${technicalId}`,
formData
),
copywriterId &&
baseInstance.post(
`/updates/copywritertracker/${copywriterId}`,
formData
),
websiteContentId &&
baseInstance.post(
`/updates/newwebsitecontent/${websiteContentId}`,
formData
),
amendmentId &&
baseInstance.post(`/updates/amendment/${amendmentId}`, formData)
);
}
if (indicatorText === "reply") {
requests.push(
baseInstance.post(`/updates/update/reply/${updateId}`, formData)
);
}
const responses = await Promise.all(requests.filter(Boolean));
responses.forEach((response) => {
if (response.status === 201) {
successToastingFunction(response?.data?.message);
fetchEditorData(customerId);
fetchOrderEditorData(orderId);
fetchLeadsEditorData(leadId);
fetchTechnicalUpdateData(technicalId);
fetchCopywriterUpdateData(copywriterId);
fetchAmendmentUpdateData(amendmentId);
fetchProductFlowUpdateData(productFlowId);
fetchWebsiteContentUpdateData(websiteContentId);
setIsOpenReplyModel(false);
setOpenQuill(false);
handleClear();
setImages([]);
setValue("");
}
fetchEditorData(customerId);
});
} catch (error) {
errorToastingFunction(error);
} finally {
setIsLoading(false);
}
} else {
errorToastingFunction("Please enter text or upload an image to submit.");
}
};
const handleFileUpload = (files: FileList | null) => { if (files) { const fileList = Array.from(files); setImages((prevImages) => [...prevImages, ...fileList]);
fileList.forEach((file) => {
if (file.type.startsWith("image/")) {
const reader = new FileReader();
reader.onloadend = () => {
const img = `<img src="${reader.result}" alt="${file.name}" />`;
setValue((prevValue) => prevValue + img + `</br>`);
};
reader.readAsDataURL(file);
} else {
const url = URL.createObjectURL(file);
setFileURLs((prev) => ({ ...prev, [file.name]: url }));
const link = `<a href="${url}" target="_blank" rel="noopener noreferrer">${file.name}</a>`;
setValue((prevValue) => prevValue + link + `</br>`);
}
});
}
};
const imageHandler = () => { const inputImage = document.createElement("input"); inputImage.setAttribute("type", "file"); inputImage.setAttribute( "accept", "image/, video/, .pdf, .xlsx, .doc, .docx" ); inputImage.setAttribute("multiple", "true"); inputImage.click();
inputImage.onchange = (e) => {
handleFileUpload(inputImage.files);
};
};
useEffect(() => { return () => { Object.values(fileURLs).forEach((url) => URL.revokeObjectURL(url)); }; }, [fileURLs]);
// Commented out because it causes an error // useEffect(() => { // if (Quill) { // Quill.register("modules/imageResize", ImageResize); // Quill.register("modules/mention", Mention); // } // }, [Quill]);
const toolbarOptions = [ ["bold", "italic", "underline", "strike"], [{ size: ["small", false, "large", "huge"] }], [{ list: "ordered" }, { list: "bullet" }, { list: "check" }], [{ script: "sub" }, { script: "super" }], [{ indent: "-1" }, { indent: "+1" }], [{ direction: "rtl" }], [{ color: [] }, { background: [] }], [{ font: [] }], [{ align: [] }], ];
const options = { debug: "info", modules: { toolbar: toolbarOptions, imageResize: { parchment: Quill.import("parchment"), modules: ["Resize", "DisplaySize"], }, mention: { allowedChars: /^[A-Za-z\s]*$/, mentionDenotationChars: ["@"], source: async ( searchTerm: string, renderItem: (data: any[]) => void ) => { try { await fetchUsersData(); // Ensure data is fetched first const filteredUsers = userData .filter((user: any) => user.name.toLowerCase().includes(searchTerm.toLowerCase()) ) .map((user: any) => ({ value: user.name })); renderItem(filteredUsers); } catch (error) { console.error("Error fetching mention users:", error); renderItem([]); } }, }, }, placeholder: "Compose an epic...", theme: "snow", };
return ( <> <form onSubmit={handleAddData} className="flex gap-2 flex-col "> <div className=""> <ReactQuill placeholder={options.placeholder} theme={options.theme} modules={options.modules} value={value} onChange={(value, _, __, editor) => { handleChanges(value, editor); }} /> <div className="flex justify-start gap-2 items-center"> <Button type="submit" className="cursor-pointer h-[24px] rounded-lg border border-primary bg-primary px-4 text-white transition hover:bg-opacity-90" > {isLoading ? ( <Loader2 className="mr-2 h-6 w-6 animate-spin text-[#fff]" /> ) : indicatorText === "reply" ? ( "Reply" ) : ( "Update" )} </Button>
<div onClick={imageHandler} className="w-fit cursor-pointer ">
<TooltipCommon text="Add Files">
<div className="hover:bg-gray-100 px-2 py-1 rounded">
<AddFilesDarkUIconSVG />
</div>
</TooltipCommon>
</div>
</div>
</form>
</>
); };
export default QuillEditor;
Question:
I've integrated the quill-mention module into my react-quill component but am running into an issue. The error TypeError: moduleClass is not a constructor appears, and the call stack indicates a problem with SnowTheme.addModule in the Quill.js file.
I've tried to register the module as follows:
useEffect(() => { if (Quill) { Quill.register("modules/imageResize", ImageResize); Quill.register("modules/mention", Mention); } }, [Quill]);
However, this causes the mentioned error. I've also commented out the registration as it seems to be the cause of the issue.
What I've Tried:
Ensuring that the quill-mention module is correctly imported and used. Checking the version compatibility of react-quill, quill, and quill-mention. Referencing the Quill documentation for proper module registration. What I Need Help With:
Why am I encountering this TypeError? How can I properly integrate the quill-mention module with react-quill? Are there any additional steps or configurations required to avoid this error? Any guidance or suggestions would be greatly appreciated!
This is the Error:-
"quill": "^2.0.2", "quill-image-resize-module-react": "^3.0.0", "quill-image-resize-module-ts": "^3.0.3", "quill-mention": "^6.0.1", "react-quill": "^2.0.0",
these are the versions.
package,json
I'm also facing same issue. Let me know if any solution found?
hello did you find the solution?? I am still searching but didn't find.. should we change in node Modules package.?
Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'unshift')
Call Stack
new Mention
(app-pages-browser)\node_modules\quill-mention\dist\mention.mjs (57:36)
SnowTheme.addModule
(app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6130:0)
SnowTheme.addModule
(app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6774:0)
eval
(app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6122:0)
Array.forEach
"quill": "^2.0.2", "quill-image-resize-module-react": "^3.0.0", "quill-image-resize-module-ts": "^3.0.3", "quill-mention": "^6.0.1",
Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'unshift')
Call Stack new Mention (app-pages-browser)\node_modules\quill-mention\dist\mention.mjs (57:36) SnowTheme.addModule (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6130:0) SnowTheme.addModule (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6774:0) eval (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6122:0) Array.forEach SnowTheme.init (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6120:0) new Quill (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (1163:0)
could you please mention me when you got the solution same error facing
+1 Also having this issue with these versions of react-quill and quill-mention.
quill Cannot import modules/mention. Are you sure it was registered?
Uncaught TypeError: moduleClass is not a constructor
+1 Also having this issue with these versions of react-quill and quill-mention.
quill Cannot import modules/mention. Are you sure it was registered?Uncaught TypeError: moduleClass is not a constructor
+1 Having the same issue, do let me know if you find the solution.
i'm facing this issue
Cannot read properties of undefined (reading 'unshift')
any updates?
going to "quill-mention": "^4.1.0", fixed this for me
From https://github.com/VaguelySerious/react-quill (a fork of this repo):
This is fork of react-quill that updates its QuillJS dependency from 1.3.7 to >=2.0.2 and tries to keep on top of dependency updates and issues, as the original maintainers are no longer active.