{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "installation-next-docs",
  "title": "Next.js",
  "description": "Install and configure Plate UI for Next.js",
  "files": [
    {
      "path": "../../content/docs/installation/next.mdx",
      "content": "---\ntitle: Next.js\ndescription: Install and configure Plate UI for Next.js\n---\n\n<Callout type=\"warning\" title=\"Prerequisites\">\n  Before you begin, ensure you have installed and configured [shadcn/ui](https://ui.shadcn.com/docs/installation/next) and [Plate UI](/docs/installation/plate-ui).\n</Callout>\n\nThis guide walks you through incrementally building a Plate editor in your Next.js application.\n\n<Steps>\n\n### Create Your First Editor\n\nStart by adding the core [Editor](/docs/components/editor) component to your project:\n\n```bash\nnpx shadcn@latest add @plate/editor\n```\n\nNext, create a basic editor page. This example sets up a simple editor within an `EditorContainer`.\n\n```tsx showLineNumbers title=\"app/editor/page.tsx\"\n'use client';\n\nimport { Plate, usePlateEditor } from 'platejs/react';\n\nimport { Editor, EditorContainer } from '@/components/ui/editor';\n\nexport default function MyEditorPage() {\n  const editor = usePlateEditor(); // Initializes the editor instance\n\n  return (\n    <Plate editor={editor}>      {/* Provides editor context */}\n      <EditorContainer>         {/* Styles the editor area */}\n        <Editor placeholder=\"Type your amazing content here...\" />\n      </EditorContainer>\n    </Plate>\n  );\n}\n```\n\n<Callout type=\"info\">\n  `usePlateEditor` creates a memoized editor instance, ensuring stability across re-renders. For a non-memoized version, use `createPlateEditor`.\n</Callout>\n\n<ComponentPreview name=\"installation-next-01-editor-demo\" height=\"200px\" />\n\n### Adding Basic Marks\n\nEnhance your editor with text formatting. Add the **Basic Nodes Kit**, [FixedToolbar](/docs/components/fixed-toolbar) and [MarkToolbarButton](/docs/components/mark-toolbar-button) components:\n\n```bash\nnpx shadcn@latest add @plate/basic-nodes-kit @plate/fixed-toolbar @plate/mark-toolbar-button\n```\n\n<Callout type=\"info\">\n  The `basic-nodes-kit` includes all the basic plugins (bold, italic, underline, headings, blockquotes, etc.) and their components that we'll use in the following steps.\n</Callout>\n\nUpdate your editor page to include these components and the basic mark plugins.\nThis example adds bold, italic, and underline functionality.\n\n```tsx showLineNumbers title=\"app/editor/page.tsx\" {4,6-10,17-18,20-33,37-38,43-47}\n'use client';\n\nimport * as React from 'react';\nimport type { Value } from 'platejs';\n\nimport {\n  BoldPlugin,\n  ItalicPlugin,\n  UnderlinePlugin,\n} from '@platejs/basic-nodes/react';\nimport {\n  Plate,\n  usePlateEditor,\n} from 'platejs/react';\n\nimport { Editor, EditorContainer } from '@/components/ui/editor';\nimport { FixedToolbar } from '@/components/ui/fixed-toolbar';\nimport { MarkToolbarButton } from '@/components/ui/mark-toolbar-button';\n\nconst initialValue: Value = [\n  {\n    type: 'p',\n    children: [\n      { text: 'Hello! Try out the ' },\n      { text: 'bold', bold: true },\n      { text: ', ' },\n      { text: 'italic', italic: true },\n      { text: ', and ' },\n      { text: 'underline', underline: true },\n      { text: ' formatting.' },\n    ],\n  },\n];\n\nexport default function MyEditorPage() {\n  const editor = usePlateEditor({\n    plugins: [BoldPlugin, ItalicPlugin, UnderlinePlugin], // Add the mark plugins\n    value: initialValue,         // Set initial content\n  });\n\n  return (\n    <Plate editor={editor}>\n      <FixedToolbar className=\"justify-start rounded-t-lg\">\n        <MarkToolbarButton nodeType=\"bold\" tooltip=\"Bold (⌘+B)\">B</MarkToolbarButton>\n        <MarkToolbarButton nodeType=\"italic\" tooltip=\"Italic (⌘+I)\">I</MarkToolbarButton>\n        <MarkToolbarButton nodeType=\"underline\" tooltip=\"Underline (⌘+U)\">U</MarkToolbarButton>\n      </FixedToolbar>\n      <EditorContainer>\n        <Editor placeholder=\"Type your amazing content here...\" />\n      </EditorContainer>\n    </Plate>\n  );\n}\n```\n\n<ComponentPreview name=\"installation-next-02-marks-demo\" height=\"200px\" />\n\n### Adding Basic Elements\n\nIntroduce block-level elements like headings and blockquotes with custom components.\n\n```tsx showLineNumbers title=\"app/editor/page.tsx\" {7,9-11,20,23,25,28-35,52-55,63-67}\n'use client';\n\nimport * as React from 'react';\nimport type { Value } from 'platejs';\n\nimport {\n  BlockquotePlugin,\n  BoldPlugin,\n  H1Plugin,\n  H2Plugin,\n  H3Plugin,\n  ItalicPlugin,\n  UnderlinePlugin,\n} from '@platejs/basic-nodes/react';\nimport {\n  Plate,\n  usePlateEditor,\n} from 'platejs/react';\n\nimport { BlockquoteElement } from '@/components/ui/blockquote-node';\nimport { Editor, EditorContainer } from '@/components/ui/editor';\nimport { FixedToolbar } from '@/components/ui/fixed-toolbar';\nimport { H1Element, H2Element, H3Element } from '@/components/ui/heading-node';\nimport { MarkToolbarButton } from '@/components/ui/mark-toolbar-button';\nimport { ToolbarButton } from '@/components/ui/toolbar'; // Generic toolbar button\n\nconst initialValue: Value = [\n  {\n    children: [{ text: 'Title' }],\n    type: 'h3',\n  },\n  {\n    children: [\n      {\n        children: [{ text: 'This is a quote.' }],\n        type: 'p',\n      },\n    ],\n    type: 'blockquote',\n  },\n  {\n    children: [\n      { text: 'With some ' },\n      { bold: true, text: 'bold' },\n      { text: ' text for emphasis!' },\n    ],\n    type: 'p',\n  },\n];\n\nexport default function MyEditorPage() {\n  const editor = usePlateEditor({\n    plugins: [\n      BoldPlugin,\n      ItalicPlugin,\n      UnderlinePlugin,\n      H1Plugin.withComponent(H1Element),\n      H2Plugin.withComponent(H2Element),\n      H3Plugin.withComponent(H3Element),\n      BlockquotePlugin.withComponent(BlockquoteElement),\n    ],\n    value: initialValue,\n  });\n\n  return (\n    <Plate editor={editor}>\n      <FixedToolbar className=\"flex justify-start gap-1 rounded-t-lg\">\n        {/* Element Toolbar Buttons */}\n        <ToolbarButton onClick={() => editor.tf.h1.toggle()}>H1</ToolbarButton>\n        <ToolbarButton onClick={() => editor.tf.h2.toggle()}>H2</ToolbarButton>\n        <ToolbarButton onClick={() => editor.tf.h3.toggle()}>H3</ToolbarButton>\n        <ToolbarButton onClick={() => editor.tf.blockquote.toggle()}>Quote</ToolbarButton>\n        {/* Mark Toolbar Buttons */}\n        <MarkToolbarButton nodeType=\"bold\" tooltip=\"Bold (⌘+B)\">B</MarkToolbarButton>\n        <MarkToolbarButton nodeType=\"italic\" tooltip=\"Italic (⌘+I)\">I</MarkToolbarButton>\n        <MarkToolbarButton nodeType=\"underline\" tooltip=\"Underline (⌘+U)\">U</MarkToolbarButton>\n      </FixedToolbar>\n      <EditorContainer>\n        <Editor placeholder=\"Type your amazing content here...\" />\n      </EditorContainer>\n    </Plate>\n  );\n}\n```\n\n<ComponentPreview name=\"installation-next-03-elements-demo\" height=\"200px\" />\n\n<Callout type=\"info\" title=\"Component Registration\">\n  Notice how we use `Plugin.withComponent(Component)` to register components with their respective plugins. This is the recommended approach for associating React components with Plate plugins.\n\n  For a quicker start with common plugins and components pre-configured, use the `editor-basic` block:\n  ```bash\n  npx shadcn@latest add @plate/editor-basic\n  ```\n  This handles much of the boilerplate for you.\n</Callout>\n\n### Handling Editor Value\n\nTo make the editor content persistent, let's integrate `localStorage` to save and load the editor's value client-side.\n\n```tsx showLineNumbers title=\"app/editor/page.tsx\" {57-60,66-68,78-84}\n'use client';\n\nimport * as React from 'react';\nimport type { Value } from 'platejs';\n\nimport {\n  BlockquotePlugin,\n  BoldPlugin,\n  H1Plugin,\n  H2Plugin,\n  H3Plugin,\n  ItalicPlugin,\n  UnderlinePlugin,\n} from '@platejs/basic-nodes/react';\nimport {\n  Plate,\n  usePlateEditor,\n} from 'platejs/react';\n\nimport { BlockquoteElement } from '@/components/ui/blockquote-node';\nimport { Editor, EditorContainer } from '@/components/ui/editor';\nimport { FixedToolbar } from '@/components/ui/fixed-toolbar';\nimport { H1Element, H2Element, H3Element } from '@/components/ui/heading-node';\nimport { MarkToolbarButton } from '@/components/ui/mark-toolbar-button';\nimport { ToolbarButton } from '@/components/ui/toolbar';\n\nconst initialValue: Value = [\n  {\n    children: [{ text: 'Title' }],\n    type: 'h3',\n  },\n  {\n    children: [\n      {\n        children: [{ text: 'This is a quote.' }],\n        type: 'p',\n      },\n    ],\n    type: 'blockquote',\n  },\n  {\n    children: [\n      { text: 'With some ' },\n      { bold: true, text: 'bold' },\n      { text: ' text for emphasis!' },\n    ],\n    type: 'p',\n  },\n];\n\nexport default function MyEditorPage() {\n  const editor = usePlateEditor({\n    plugins: [\n      BoldPlugin,\n      ItalicPlugin,\n      UnderlinePlugin,\n      H1Plugin.withComponent(H1Element),\n      H2Plugin.withComponent(H2Element),\n      H3Plugin.withComponent(H3Element),\n      BlockquotePlugin.withComponent(BlockquoteElement),\n    ],\n    value: () => {\n      const savedValue = localStorage.getItem('installation-next-demo');\n      return savedValue ? JSON.parse(savedValue) : initialValue;\n    },\n  });\n\n  return (\n    <Plate\n      editor={editor}\n      onChange={({ value }) => {\n        localStorage.setItem('installation-next-demo', JSON.stringify(value));\n      }}\n    >\n      <FixedToolbar className=\"flex justify-start gap-1 rounded-t-lg\">\n        <ToolbarButton onClick={() => editor.tf.h1.toggle()}>H1</ToolbarButton>\n        <ToolbarButton onClick={() => editor.tf.h2.toggle()}>H2</ToolbarButton>\n        <ToolbarButton onClick={() => editor.tf.h3.toggle()}>H3</ToolbarButton>\n        <ToolbarButton onClick={() => editor.tf.blockquote.toggle()}>Quote</ToolbarButton>\n        <MarkToolbarButton nodeType=\"bold\" tooltip=\"Bold (⌘+B)\">B</MarkToolbarButton>\n        <MarkToolbarButton nodeType=\"italic\" tooltip=\"Italic (⌘+I)\">I</MarkToolbarButton>\n        <MarkToolbarButton nodeType=\"underline\" tooltip=\"Underline (⌘+U)\">U</MarkToolbarButton>\n        <div className=\"flex-1\" />\n        <ToolbarButton\n          className=\"px-2\"\n          onClick={() => editor.tf.setValue(initialValue)}\n        >\n          Reset\n        </ToolbarButton>\n      </FixedToolbar>\n      <EditorContainer>\n        <Editor placeholder=\"Type your amazing content here...\" />\n      </EditorContainer>\n    </Plate>\n  );\n}\n```\n\n<ComponentPreview name=\"installation-next-demo\" />\n\n### Next Steps\n\nCongratulations! You've built a foundational Plate editor in Next.js.\n\nTo further enhance your editor:\n\n*   **Explore Components:** Discover [Toolbars, Menus, Node components](/docs/components), and more.\n*   **Add Plugins:** Integrate features like [Tables](/docs/table), [Mentions](/docs/mention), [AI](/docs/ai), or [Markdown](/docs/markdown).\n*   **Use Editor Blocks:** Quickly set up pre-configured editors:\n    *   Basic editor: `npx shadcn@latest add @plate/editor-basic`\n    *   AI-powered editor: `npx shadcn@latest add @plate/editor-ai`\n*   **Learn More:**\n    *   [Editor Configuration](/docs/editor)\n    *   [Plugin Configuration](/docs/plugin)\n    *   [Plugin Components](/docs/plugin-components)\n\n</Steps>\n",
      "type": "registry:file",
      "target": "content/docs/plate/installation/next.mdx"
    }
  ],
  "type": "registry:file"
}