{"record":{"id":"d32a764f9581a316","repo":"facebook/lexical","slug":"linkplugin-linknode-not-registered-on-editor","errorCode":null,"errorMessage":"LinkPlugin: LinkNode not registered on editor","messagePattern":"LinkPlugin: LinkNode not registered on editor","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/lexical-react/src/LexicalLinkPlugin.ts","lineNumber":36,"sourceCode":"\n/**\n * Enables {@link LinkNode} support, registering the commands and transforms\n * that toggle and normalize links. Pass `validateUrl` to restrict which URLs\n * may be applied (which also enables automatic link creation when pasting a\n * matching URL) and `attributes` to set defaults such as `target` or `rel`.\n * The editor must have the {@link LinkNode} registered.\n *\n * This is a legacy plugin. When building an editor with the extension API,\n * configure {@link LinkExtension} instead.\n *\n * @returns `null`, this plugin renders no DOM of its own.\n */\nexport function LinkPlugin({validateUrl, attributes}: Props): null {\n  const [editor] = useLexicalComposerContext();\n\n  useEffect(() => {\n    if (!editor.hasNodes([LinkNode])) {\n      throw new Error('LinkPlugin: LinkNode not registered on editor');\n    }\n  });\n  useEffect(() => {\n    return registerLink(editor, namedSignals({attributes, validateUrl}));\n  }, [editor, validateUrl, attributes]);\n\n  return null;\n}\n","sourceCodeStart":18,"sourceCodeEnd":45,"githubUrl":"https://github.com/facebook/lexical/blob/76a22dcba981b46119fcec45f935270707e26a57/packages/lexical-react/src/LexicalLinkPlugin.ts#L18-L45","documentation":"LinkPlugin registers link behavior that operates on LinkNode, so it verifies the editor has LinkNode registered and throws otherwise. Lexical only recognizes node classes explicitly configured on the editor. The check runs in a useEffect at mount, surfacing the misconfiguration immediately when the plugin renders.","triggerScenarios":"Rendering <LinkPlugin /> in a LexicalComposer whose editor config lacks LinkNode (AutoLinkNode alone is not sufficient).","commonSituations":"Adding the link plugin from docs to an editor with a hand-built nodes list; registering AutoLinkNode but not LinkNode; migrating to @lexical/link package split and dropping the node import.","solutions":["Add LinkNode (and AutoLinkNode if using autolinks) from @lexical/link to the editor's nodes array","Use the link extension with buildEditorFromExtensions to register nodes automatically","Check editor.hasNodes([LinkNode]) before rendering the plugin"],"exampleFix":"// before\nconst initialConfig = {nodes: [ParagraphNode, TextNode, AutoLinkNode]};\n<LinkPlugin /> // throws: LinkNode missing\n\n// after\nimport {LinkNode, AutoLinkNode} from '@lexical/link';\nconst initialConfig = {nodes: [ParagraphNode, TextNode, LinkNode, AutoLinkNode]};\n<LinkPlugin /> // ok","handlingStrategy":"validation","validationCode":"import {LinkNode, AutoLinkNode} from '@lexical/link';\nif (!editor.hasNodes([LinkNode])) {\n  throw new Error('Add LinkNode to your editor nodes config before using LinkPlugin');\n}","typeGuard":"function supportsLinks(editor: LexicalEditor): boolean {\n  return editor.hasNodes([LinkNode]);\n}","tryCatchPattern":"try {\n  if (!editor.hasNodes([LinkNode])) throw new Error('LinkNode missing');\n  // safe to use LinkPlugin\n} catch (e) {\n  console.error('LinkPlugin misconfigured:', e);\n}","preventionTips":["Register both LinkNode and AutoLinkNode together — AutoLinkNode alone is not enough","Keep nodes imports adjacent to plugin imports so they are added together","Use the link extension bundle instead of manual plugin wiring"],"tags":["lexical","react","node-registration","link","plugin"],"backgroundTag":"missing-node-registration","analyzedSha":"76a22dcba981b46119fcec45f935270707e26a57","analyzedAt":"2026-08-31T21:45:54.792Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}