A Svelte 5 wrapper component for Editor.js -- built with runes, TypeScript, and lazy-loaded tools.
- 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
npm install svelty-editor @editorjs/editorjsThen install whichever Editor.js tools you want to use:
npm install @editorjs/header @editorjs/list @editorjs/paragraph| 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.
<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. |
Access these via bind:this:
<SveltyEditor bind:this={editor} ... />Returns the editor content as an OutputData object.
const data = await editor.save();Toggle read-only mode.
editor.setReadOnly(true);Dynamically register a tool at runtime. The editor will reinitialize to pick it up.
await editor.registerTool(
'checklist',
() => import('@editorjs/checklist'),
{ inlineToolbar: true }
);Returns the underlying EditorManager instance for advanced use cases.
const manager = editor.getManager();
const editorjs = manager.getEditor(); // raw Editor.js instanceEach 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. |
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><SveltyEditor
tools={...}
onChange={(api, event) => {
console.log('Content changed:', event);
}}
onReady={() => {
console.log('Editor is ready');
}}
/><SveltyEditor
tools={...}
data={{
blocks: [
{ type: 'header', data: { text: 'Hello', level: 2 } },
{ type: 'paragraph', data: { text: 'Some content here.' } }
]
}}
/>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
All types are exported:
import type {
EditorOptions,
EditorTool,
EditorChangeEvent,
I18nConfig,
ToolsLoadMap,
SveltyEditorProps
} from 'svelty-editor';git clone https://github.com/code-gio/svelty-editor.git
cd svelty-editor
npm install
npm run devVisit http://localhost:5173 to see the demo page.
MIT