Fumadocs Editor

MdxEditor

Props, ref, parts and keyboard shortcuts

import { MdxEditor } from "@fumadocs-editor/ui";

Props

Prop

Type

sync

See Sync.

Prop

Type

Ref

Prop

Type

Page variant

variant="page" makes the editor fill the page, with a sticky header and a centered column. header adds your own controls to it. Studio is built this way.

page.tsx
import { useState, type CSSProperties } from "react";
import { MdxEditor } from "@fumadocs-editor/ui";

export function Page({ path }: { path: string }) {
  const [panel, setPanel] = useState(false);
  return (
    <div style={{ "--fde-page-inset": panel ? "18rem" : "0px" } as CSSProperties}>
      <MdxEditor
        variant="page"
        header={{
          start: (
            <button type="button" onClick={() => setPanel(!panel)}>
              Files
            </button>
          ),
        }}
        sync={{ path }}
      />
      {panel && (
        <aside style={{ position: "fixed", top: "3.25rem", left: "0.75rem", width: "17rem" }} />
      )}
    </div>
  );
}
CSS variableDefaultSets
--fde-page-width52remthe column width
--fde-page-inset0pxspace kept clear at the start, for a side panel

Parts

MdxEditor shows one surface at a time with tabs to switch. For another layout, compose the parts:

split.tsx
import { MdxEditor } from "@fumadocs-editor/ui";

export function SplitEditor({ path }: { path: string }) {
  return (
    <MdxEditor.Root sync={{ path }}>
      <MdxEditor.Status />
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr" }}>
        <MdxEditor.Visual />
        <MdxEditor.Source />
      </div>
    </MdxEditor.Root>
  );
}
PartRenders
MdxEditor.Rootnothing; owns the document, takes the props above
MdxEditor.Visualthe WYSIWYG surface
MdxEditor.Sourcethe MDX source
MdxEditor.Statusthe sync status and conflict buttons
MdxEditor.Tabsthe Visual / MDX switch

For fully custom surfaces, read the document with useSourceText, useSyncStatus and useEditorMode inside MdxEditor.Root.

Keyboard

KeysDoes
⌘B ⌘I ⌘E ⌘⇧Sbold, italic, code, strikethrough
→ at a line's endstop the current formatting
⌘.open the block menu
⌥↑ ⌥↓move the block
Escselect the component around the caret, then its parent
⌘Aselect the region, then wider, then everything
Tab ⇧Tabnext or previous region of a component
⌘Enteradd the next item (a Step, Tab, File or code tab)
  • Mouse: double-click a component's border or icon to select it, then drag its handle to move it.
  • Touch: the toolbar stays visible while typing, and each block has a drag handle beside it.

EditorThemeProvider

For pages without their own theme: tracks light, dark or system, remembers the choice and applies it to the editor. Read or change it with useEditorTheme().

standalone.tsx
import { EditorThemeProvider, MdxEditor } from "@fumadocs-editor/ui";

export function StandaloneEditor({ source }: { source: string }) {
  return (
    <EditorThemeProvider>
      <MdxEditor defaultValue={source} />
    </EditorThemeProvider>
  );
}

Prop

Type

Last updated on

On this page