Tutorial: overview
This tutorial builds one editor for meeting notes. You start with the smallest working editor, add features one at a time, write your own block, connect it to a server, teach it to an AI model and finally see the same editor on React. Every chapter ends with a working result and one link to the next chapter.
The finished editor of chapters 1 to 5 runs below. Type /callout to add a callout, hover a callout block to change its tone, and open „Umwandeln in …“ on any paragraph.
What you build
| Chapter | You add | Result |
|---|---|---|
| 2. A simple editor | SimpleEditor, EditorToolbar, EditorOutline | Rich text, toolbar, outline, read-only switch |
| 3. Compose features | EditorSurface over defineEditor, mentions, media, tables, block UI | @ and # suggestions, image drop, tables, drag handle |
| 4. Own block, path A | The „Hinweis“ node through the extensions and commands props | A callout block with a /hinweis entry |
| 5. Own feature, path B | The callout as an EditorFeature | Toolbar button, hover menu, „Umwandeln in …“ |
| 6. Backend and collaboration | The Nuxt module, EditorPorts, a collaboration session | Two browsers on one document |
| 7. AI | aiFeature(), aiContext | The model knows about callouts |
| 8. The React surface | EditorContextProvider, EditorSurface, SimpleEditor | The same editor on React |
The UI strings of the examples are German („Hinweis“, „Warnung“, „Erledigt“, „Umwandeln in …“), the code and this tutorial are English. Pass createEditor({ locale: 'en' }) to switch the built-in strings of the library to English; the strings of your own block stay yours.
Prerequisites
- Node 22 or newer and Bun (the commands below use
bun;npmworks the same). - A Vite app with Vue 3. Nuxt UI's Vite plugin,
@nuxt/ui/vite, provides the theme, icons and component imports; the editor's Vue layer uses Nuxt UI components. You do not need Nuxt for chapters 1 to 5. @skaile/forge-editorand its peers installed as described in Installation.
If you start from nothing, Quick start: plain Vue lists the three small files (package.json, index.html, tsconfig.json) a new app needs. The Vite config of the runnable example, examples/vue-simple, is the one this tutorial builds on:
// Plain Vite + Vue (no Nuxt, router or backend). Nuxt UI's Vite plugin brings the theme, icons and component imports.
export default defineConfig({
server: { port: 3040, strictPort: true },
resolve: sourceResolve,
plugins: [
vue(),
ui({ router: false, icon: { clientBundle: { scan: true, icons: [...libraryIcons] } } }),
],
})
Two parts of this file belong to the repository only. sourceResolve makes Vite read the library from packages/editor/src instead of a built package, and libraryIcons bundles the library's icons although the library lies outside the Vite root. In your own app the plugin list [vue(), ui({ router: false })] is enough; the icon bundling is optional and only avoids runtime requests to the Iconify API.
Run the examples
Every chapter shows code from a real file of the repository, so you can run the same code:
bun install
bun run --cwd examples/vue-simple dev # chapters 2 and 4, port 3040
bun run dev # chapters 5 to 7, port 3056 (the repository's Nuxt app)
What you have now
A plan, and a place to run each step: the simple example app for the first chapters and the repository's Nuxt app for the advanced ones.