Svelty Editor
A Svelte 5 wrapper component for Editor.js — built with runes, TypeScript, and lazy-loaded tools.
Features
Section titled “Features”- Svelte 5 — uses
$props,$state, and$effectrunes - TypeScript — fully typed props, events, and exports
- Bring your own tools — install only the Editor.js plugins you need
- Snippet support — render custom UI around the editor with Svelte 5 snippets
- Component API —
save(),setReadOnly(),registerTool(), andgetManager()viabind:this - EditorManager — access the underlying manager class directly for advanced use cases
Installation
Section titled “Installation”npm install svelty-editor @editorjs/editorjsThen install whichever Editor.js tools you want to use:
npm install @editorjs/header @editorjs/list @editorjs/paragraphAvailable tool packages
Section titled “Available tool packages”| Package | Block type |
|---|---|
@editorjs/header | Headings (H1–H6) |
@editorjs/list | Ordered / unordered lists |
@editorjs/paragraph | Paragraphs |
@editorjs/image | Image blocks |
@editorjs/embed | Embedded content (YouTube, etc.) |
@editorjs/delimiter | Visual dividers |
@editorjs/marker | Inline text highlighting |
@editorjs/quote | Block quotes |
@editorjs/table | Tables |
@editorjs/warning | Warning callouts |
You can also use any Editor.js plugin — just pass its class in the tools prop.
Quick Start
Section titled “Quick Start”<script lang="ts"> import { SveltyEditor } from 'svelty-editor'; import Header from '@editorjs/header'; import List from '@editorjs/list'; import Paragraph from '@editorjs/paragraph';
let editor: ReturnType<typeof SveltyEditor>;
async function handleSave() { const data = await editor.save(); console.log(data); }</script>
<SveltyEditor bind:this={editor} tools={{ header: { class: Header }, list: { class: List }, paragraph: { class: Paragraph } }} placeholder="Start writing..."/>
<button onclick={handleSave}>Save</button>SveltyEditor accepts all Editor.js configuration options (except holder, which is managed internally), plus:
| Prop | Type | Description |
|---|---|---|
tools | Record<string, EditorTool> | Map of tool names to their config (including the class). |
data | OutputData | Initial editor content. |
placeholder | string | Placeholder text for an empty editor. |
autofocus | boolean | Focus the editor on mount. |
readOnly | boolean | Start in read-only mode. |
onChange | (api, event) => void | Called when editor content changes. |
onReady | () => void | Called when the editor is ready. |
class | string | CSS class applied to the outer wrapper. |
children | Snippet | Svelte 5 snippet rendered above the editor. |
Component Methods
Section titled “Component Methods”Access these via bind:this:
<SveltyEditor bind:this={editor} ... />save()
Section titled “save()”Returns the editor content as an OutputData object.
const data = await editor.save();setReadOnly(readOnly: boolean)
Section titled “setReadOnly(readOnly: boolean)”Toggle read-only mode.
editor.setReadOnly(true);registerTool(name, loader, config?)
Section titled “registerTool(name, loader, config?)”Dynamically register a tool at runtime. The editor will reinitialize to pick it up.
await editor.registerTool( 'checklist', () => import('@editorjs/checklist'), { inlineToolbar: true });getManager()
Section titled “getManager()”Returns the underlying EditorManager instance for advanced use cases.
const manager = editor.getManager();const editorjs = manager.getEditor(); // raw Editor.js instanceTool Configuration
Section titled “Tool Configuration”Each tool entry accepts an EditorTool object:
tools={{ header: { class: Header, inlineToolbar: true, config: { levels: [1, 2, 3], defaultLevel: 2 }, shortcut: 'CMD+SHIFT+H' }}}| Field | Type | Description |
|---|---|---|
class | Tool constructor | The Editor.js tool class. |
inlineToolbar | boolean | string[] | Enable inline toolbar for this block. |
config | Record<string, unknown> | Tool-specific configuration. |
shortcut | string | Keyboard shortcut. |
tunes | string[] | Block tunes to apply. |
Using Snippets
Section titled “Using Snippets”Render custom UI above the editor content using Svelte 5 snippets:
<SveltyEditor bind:this={editor} tools={...}> {#snippet children()} <div class="my-toolbar"> <button onclick={() => editor.save()}>Save</button> </div> {/snippet}</SveltyEditor>Listening to Changes
Section titled “Listening to Changes”<SveltyEditor tools={...} onChange={(api, event) => { console.log('Content changed:', event); }} onReady={() => { console.log('Editor is ready'); }}/>Loading Initial Data
Section titled “Loading Initial Data”<SveltyEditor tools={...} data={{ blocks: [ { type: 'header', data: { text: 'Hello', level: 2 } }, { type: 'paragraph', data: { text: 'Some content here.' } } ] }}/>Advanced: EditorManager
Section titled “Advanced: EditorManager”For more control, import EditorManager directly:
import { EditorManager } from 'svelty-editor';import type { EditorOptions } from 'svelty-editor';The manager exposes:
initialize()— create the editor instancesave()— get editor outputdestroy()— clean upsetReadOnly(boolean)— toggle read-onlyregisterTool(name, loader, config?)— add a tool dynamicallyupdateOptions(options)— update editor optionsgetEditor()— access the raw Editor.js instancegetInitializedTools()— get loaded tool configs
TypeScript
Section titled “TypeScript”All types are exported:
import type { EditorOptions, EditorTool, EditorChangeEvent, I18nConfig, ToolsLoadMap, SveltyEditorProps} from 'svelty-editor';