Skip to main content

Quick start

Get a working Yoopta Editor up and running in under 5 minutes. This guide will walk you through creating a basic editor with essential plugins and text formatting.

Step 1: Install dependencies

If you haven’t already, install the required packages:
npm install slate slate-react slate-dom @yoopta/editor @yoopta/paragraph @yoopta/headings @yoopta/marks

Step 2: Create your first editor

Create a new file Editor.tsx (or .jsx if not using TypeScript):
Editor.tsx
import { useMemo } from 'react';
import YooptaEditor, { createYooptaEditor, type YooptaContentValue } from '@yoopta/editor';
import Paragraph from '@yoopta/paragraph';
import Headings from '@yoopta/headings';
import { Bold, Italic, Underline, Strike, CodeMark, Highlight } from '@yoopta/marks';

const PLUGINS = [
  Paragraph,
  Headings.HeadingOne,
  Headings.HeadingTwo,
  Headings.HeadingThree,
];

const MARKS = [Bold, Italic, Underline, Strike, CodeMark, Highlight];

export default function Editor() {
  const editor = useMemo(
    () => createYooptaEditor({ plugins: PLUGINS, marks: MARKS }),
    []
  );

  return (
    <YooptaEditor
      editor={editor}
      placeholder="Type / to open menu"
      style={{ width: 750, paddingBottom: 100 }}
      onChange={(value) => console.log('Content changed:', value)}
    />
  );
}
1

Import dependencies

Import the core editor, plugins you want to use, and text formatting marks.
2

Define plugins and marks

Create arrays of plugins and marks. Note that Headings exports multiple plugins: HeadingOne, HeadingTwo, HeadingThree.
3

Create editor instance

Use createYooptaEditor() with your plugins and marks. Wrap it in useMemo() to ensure the editor instance is stable across re-renders.
4

Render YooptaEditor

Render the <YooptaEditor> component with the editor instance. Add a placeholder and handle content changes with onChange.

Step 3: Test your editor

That’s it! You now have a working editor. Try these interactions:
  1. Type text - Start typing to create paragraphs
  2. Use keyboard shortcuts:
    • Cmd/Ctrl + B for bold
    • Cmd/Ctrl + I for italic
    • Cmd/Ctrl + U for underline
  3. Type / - Opens the slash command menu (more on this below)
  4. Press Enter - Creates a new paragraph

Add more plugins

Let’s enhance the editor with more block types:
Editor.tsx
import { useMemo } from 'react';
import YooptaEditor, { createYooptaEditor } from '@yoopta/editor';
import Paragraph from '@yoopta/paragraph';
import Headings from '@yoopta/headings';
import { NumberedList, BulletedList, TodoList } from '@yoopta/lists';
import Blockquote from '@yoopta/blockquote';
import Code from '@yoopta/code';
import Divider from '@yoopta/divider';
import { Bold, Italic, Underline, Strike, CodeMark, Highlight } from '@yoopta/marks';

const PLUGINS = [
  Paragraph,
  Headings.HeadingOne,
  Headings.HeadingTwo,
  Headings.HeadingThree,
  NumberedList,
  BulletedList,
  TodoList,
  Blockquote,
  Code.Code,
  Divider,
];

const MARKS = [Bold, Italic, Underline, Strike, CodeMark, Highlight];

export default function Editor() {
  const editor = useMemo(
    () => createYooptaEditor({ plugins: PLUGINS, marks: MARKS }),
    []
  );

  return (
    <YooptaEditor
      editor={editor}
      placeholder="Type / to open menu"
      style={{ width: 750, paddingBottom: 100 }}
      autoFocus
    />
  );
}
The Code plugin exports two plugins: Code.Code for code blocks and Code.CodeGroup for grouped code blocks with tabs.

Add UI components

For a complete editing experience, add the floating toolbar and slash menu:
1

Install @yoopta/ui

npm install @yoopta/ui
2

Import UI components

import { FloatingToolbar, SlashCommandMenu } from '@yoopta/ui';
3

Add components as children

UI components must be children of <YooptaEditor> so they can access the editor context.
Here’s the complete example with UI components:
Editor.tsx
import { useMemo } from 'react';
import YooptaEditor, { createYooptaEditor } from '@yoopta/editor';
import Paragraph from '@yoopta/paragraph';
import Headings from '@yoopta/headings';
import { NumberedList, BulletedList, TodoList } from '@yoopta/lists';
import Blockquote from '@yoopta/blockquote';
import Code from '@yoopta/code';
import { Bold, Italic, Underline, Strike, CodeMark, Highlight } from '@yoopta/marks';
import { FloatingToolbar, SlashCommandMenu } from '@yoopta/ui';

const PLUGINS = [
  Paragraph,
  Headings.HeadingOne,
  Headings.HeadingTwo,
  Headings.HeadingThree,
  NumberedList,
  BulletedList,
  TodoList,
  Blockquote,
  Code.Code,
];

const MARKS = [Bold, Italic, Underline, Strike, CodeMark, Highlight];

export default function Editor() {
  const editor = useMemo(
    () => createYooptaEditor({ plugins: PLUGINS, marks: MARKS }),
    []
  );

  return (
    <YooptaEditor
      editor={editor}
      placeholder="Type / to open menu"
      style={{ width: 750, paddingBottom: 100 }}
      autoFocus
    >
      <FloatingToolbar />
      <SlashCommandMenu />
    </YooptaEditor>
  );
}

Apply a theme

By default, Yoopta is headless. For pre-styled blocks, apply a theme:
1

Install theme package

npm install @yoopta/themes-shadcn
2

Apply theme to all plugins

import { applyTheme } from '@yoopta/themes-shadcn';

const editor = useMemo(
  () => createYooptaEditor({ 
    plugins: applyTheme(PLUGINS), 
    marks: MARKS 
  }),
  []
);
Complete example with theme:
Editor.tsx
import { useMemo } from 'react';
import YooptaEditor, { createYooptaEditor } from '@yoopta/editor';
import Paragraph from '@yoopta/paragraph';
import Headings from '@yoopta/headings';
import Blockquote from '@yoopta/blockquote';
import Callout from '@yoopta/callout';
import { Bold, Italic, Underline, Strike, CodeMark, Highlight } from '@yoopta/marks';
import { applyTheme } from '@yoopta/themes-shadcn';
import { FloatingToolbar, SlashCommandMenu } from '@yoopta/ui';

const PLUGINS = [
  Paragraph,
  Headings.HeadingOne,
  Headings.HeadingTwo,
  Headings.HeadingThree,
  Blockquote,
  Callout,
];

const MARKS = [Bold, Italic, Underline, Strike, CodeMark, Highlight];

export default function Editor() {
  const editor = useMemo(
    () => createYooptaEditor({ 
      plugins: applyTheme(PLUGINS), 
      marks: MARKS 
    }),
    []
  );

  return (
    <YooptaEditor
      editor={editor}
      placeholder="Type / to open menu"
      style={{ width: 750, paddingBottom: 100 }}
      autoFocus
    >
      <FloatingToolbar />
      <SlashCommandMenu />
    </YooptaEditor>
  );
}
The applyTheme() function applies styled UI to all supported plugins. You can also apply themes to individual plugins using plugin.extend({ elements: ThemeUI }).

Working with content

Get editor content

Access the editor content in the onChange callback or programmatically:
const onChange = (value: YooptaContentValue) => {
  // Save to state, localStorage, or send to server
  console.log('Content:', value);
  localStorage.setItem('editorContent', JSON.stringify(value));
};

// Or get content programmatically
const content = editor.getEditorValue();

Set initial content

Provide initial content when creating the editor:
const initialValue = {
  // Your content structure
};

const editor = useMemo(
  () => createYooptaEditor({ 
    plugins: PLUGINS, 
    marks: MARKS,
    value: initialValue,
  }),
  []
);

// Or set content later
useEffect(() => {
  const savedContent = localStorage.getItem('editorContent');
  if (savedContent) {
    editor.setEditorValue(JSON.parse(savedContent));
  }
}, [editor]);

Export content

Export editor content to different formats:
// Get as HTML
const html = editor.getHTML();

// Get as Markdown
const markdown = editor.getMarkdown();

// Get as plain text
const text = editor.getPlainText();
For export functionality, install @yoopta/exports: npm install @yoopta/exports

Common use cases

app/editor/page.tsx
'use client';

import { useMemo } from 'react';
import YooptaEditor, { createYooptaEditor } from '@yoopta/editor';
import Paragraph from '@yoopta/paragraph';
import Headings from '@yoopta/headings';
import { Bold, Italic } from '@yoopta/marks';

const PLUGINS = [Paragraph, Headings.HeadingOne, Headings.HeadingTwo];
const MARKS = [Bold, Italic];

export default function EditorPage() {
  const editor = useMemo(
    () => createYooptaEditor({ plugins: PLUGINS, marks: MARKS }),
    []
  );

  return (
    <div className="max-w-4xl mx-auto py-8">
      <YooptaEditor
        editor={editor}
        placeholder="Start typing..."
        style={{ width: '100%' }}
        autoFocus
      />
    </div>
  );
}
Don’t forget to add 'use client' at the top of your file when using Yoopta Editor in Next.js App Router.

Next steps

You now have a working Yoopta Editor! Here’s what to explore next:

Configuration

Learn how to configure plugins and customize behavior

Plugins

Explore all available plugins and their options

UI components

Add toolbars, menus, and other UI components

API reference

Dive into the editor API and programmatic control

Full example

Here’s a complete, production-ready example with all features:
Editor.tsx
'use client';

import { useMemo, useEffect } from 'react';
import YooptaEditor, { createYooptaEditor, type YooptaContentValue } from '@yoopta/editor';
import Paragraph from '@yoopta/paragraph';
import Headings from '@yoopta/headings';
import { NumberedList, BulletedList, TodoList } from '@yoopta/lists';
import Blockquote from '@yoopta/blockquote';
import Callout from '@yoopta/callout';
import Code from '@yoopta/code';
import Link from '@yoopta/link';
import Divider from '@yoopta/divider';
import { Bold, Italic, Underline, Strike, CodeMark, Highlight } from '@yoopta/marks';
import { applyTheme } from '@yoopta/themes-shadcn';
import { FloatingToolbar, SlashCommandMenu, FloatingBlockActions, SelectionBox } from '@yoopta/ui';

const PLUGINS = [
  Paragraph,
  Headings.HeadingOne,
  Headings.HeadingTwo,
  Headings.HeadingThree,
  NumberedList,
  BulletedList,
  TodoList,
  Blockquote,
  Callout,
  Code.Code,
  Link,
  Divider,
];

const MARKS = [Bold, Italic, Underline, Strike, CodeMark, Highlight];

export default function Editor() {
  const editor = useMemo(
    () => createYooptaEditor({ 
      plugins: applyTheme(PLUGINS), 
      marks: MARKS 
    }),
    []
  );

  useEffect(() => {
    // Load saved content from localStorage
    const savedContent = localStorage.getItem('editorContent');
    if (savedContent) {
      editor.setEditorValue(JSON.parse(savedContent));
    }
  }, [editor]);

  const handleChange = (value: YooptaContentValue) => {
    // Save content to localStorage
    localStorage.setItem('editorContent', JSON.stringify(value));
  };

  return (
    <div className="max-w-4xl mx-auto py-8 px-4">
      <YooptaEditor
        editor={editor}
        placeholder="Type / to open menu, or start typing..."
        style={{ width: '100%', paddingBottom: 100 }}
        onChange={handleChange}
        autoFocus
      >
        <FloatingToolbar />
        <SlashCommandMenu />
        <FloatingBlockActions />
        <SelectionBox />
      </YooptaEditor>
    </div>
  );
}
Check out the full-setup example on the Yoopta website to see all features in action, including drag-and-drop, mentions, and more.

Build docs developers (and LLMs) love