Using Lexical with NextJS #5888
Answered
by
2wheeh
zack-ashen
asked this question in
Q&A
-
I'm trying to use Lexical with NextJS and am continuously getting the error:
I've checked every import and I'm not sure what I might be implementing incorrectly. This is my component: "use client";
import { CodeHighlightNode, CodeNode } from "@lexical/code";
import { AutoLinkNode, LinkNode } from "@lexical/link";
import { ListItemNode, ListNode } from "@lexical/list";
import { TRANSFORMERS } from "@lexical/markdown";
import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
import { LexicalComposer } from "@lexical/react/LexicalComposer";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
import { ListPlugin } from "@lexical/react/LexicalListPlugin";
import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
import { EditorState } from "lexical";
import { useEffect, useState } from "react";
import AutoLinkPlugin from "./plugins/AutoLinkPlugin";
import CodeHighlightPlugin from "./plugins/CodeHighlightPlugin";
import ListMaxIndentLevelPlugin from "./plugins/ListMaxIndentLevelPlugin";
import ToolbarPlugin from "./plugins/ToolbarPlugin";
import "./styles.css";
function Placeholder() {
return <div className="editor-placeholder">Enter some rich text...</div>;
}
const Theme = {
ltr: "ltr",
rtl: "rtl",
placeholder: "editor-placeholder",
paragraph: "editor-paragraph",
quote: "editor-quote",
heading: {
h1: "editor-heading-h1",
h2: "editor-heading-h2",
h3: "editor-heading-h3",
h4: "editor-heading-h4",
h5: "editor-heading-h5",
},
list: {
nested: {
listitem: "editor-nested-listitem",
},
ol: "editor-list-ol",
ul: "editor-list-ul",
listitem: "editor-listitem",
},
image: "editor-image",
link: "editor-link",
text: {
bold: "editor-text-bold",
italic: "editor-text-italic",
overflowed: "editor-text-overflowed",
hashtag: "editor-text-hashtag",
underline: "editor-text-underline",
strikethrough: "editor-text-strikethrough",
underlineStrikethrough: "editor-text-underlineStrikethrough",
code: "editor-text-code",
},
code: "editor-code",
codeHighlight: {
atrule: "editor-tokenAttr",
attr: "editor-tokenAttr",
boolean: "editor-tokenProperty",
builtin: "editor-tokenSelector",
cdata: "editor-tokenComment",
char: "editor-tokenSelector",
class: "editor-tokenFunction",
"class-name": "editor-tokenFunction",
comment: "editor-tokenComment",
constant: "editor-tokenProperty",
deleted: "editor-tokenProperty",
doctype: "editor-tokenComment",
entity: "editor-tokenOperator",
function: "editor-tokenFunction",
important: "editor-tokenVariable",
inserted: "editor-tokenSelector",
keyword: "editor-tokenAttr",
namespace: "editor-tokenVariable",
number: "editor-tokenProperty",
operator: "editor-tokenOperator",
prolog: "editor-tokenComment",
property: "editor-tokenProperty",
punctuation: "editor-tokenPunctuation",
regex: "editor-tokenVariable",
selector: "editor-tokenSelector",
string: "editor-tokenSelector",
symbol: "editor-tokenProperty",
tag: "editor-tokenProperty",
url: "editor-tokenOperator",
variable: "editor-tokenVariable",
},
};
const editorConfig = {
namespace: "editor",
// The editor theme
theme: Theme,
// Handling of errors during update
onError(error: Error) {
throw error;
},
// Any custom nodes go here
nodes: [
HeadingNode,
ListNode,
ListItemNode,
QuoteNode,
CodeNode,
CodeHighlightNode,
TableNode,
TableCellNode,
TableRowNode,
AutoLinkNode,
LinkNode,
],
};
function OnChangePlugin({
onChange,
}: {
onChange: (state: EditorState) => void;
}) {
// Access the editor through the LexicalComposerContext
const [editor] = useLexicalComposerContext();
// Wrap our listener in useEffect to handle the teardown and avoid stale references.
useEffect(() => {
// most listeners return a teardown function that can be called to clean them up.
return editor.registerUpdateListener(({ editorState }) => {
// call onChange here to pass the latest state up to the parent.
onChange(editorState);
});
}, [editor, onChange]);
return null;
}
export default function RichTextEditor({
onEditorChange,
}: {
onEditorChange: (value: string) => void;
}) {
const [isMounted, setIsMounted] = useState(false);
const [editorState, setEditorState] = useState<EditorState>();
function onChange(editorState: EditorState) {
setEditorState(editorState);
onEditorChange(JSON.stringify(editorState.toJSON()));
}
useEffect(() => {
setIsMounted(true);
}, []);
if (!isMounted) return null;
return (
<LexicalComposer initialConfig={editorConfig}>
<div className="editor-container">
<ToolbarPlugin />
<div className="editor-inner">
{/* <RichTextPlugin
contentEditable={<ContentEditable className="editor-input" />}
placeholder={<Placeholder />}
ErrorBoundary={LexicalErrorBoundary}
/> */}
<HistoryPlugin />
<AutoFocusPlugin />
<CodeHighlightPlugin />
<ListPlugin />
<LinkPlugin />
<AutoLinkPlugin />
<OnChangePlugin onChange={onChange} />
<ListMaxIndentLevelPlugin maxDepth={7} />
<MarkdownShortcutPlugin transformers={TRANSFORMERS} />
</div>
</div>
</LexicalComposer>
);
} Thanks for any help in advance. |
Beta Was this translation helpful? Give feedback.
Answered by
2wheeh
Apr 13, 2024
Replies: 1 comment 2 replies
-
It is fixed (hopefully) but not released yet. |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
based on your implementation, you could try with dynamic import instead of
isMounted
.