Documentation Index Fetch the complete documentation index at: https://mintlify.com/prosekit/prosekit/llms.txt
Use this file to discover all available pages before exploring further.
ProseKit provides first-class support for Svelte 5 through the @prosekit/svelte package, offering Svelte-specific components, runes, and utilities for building powerful editors.
Installation
npm install prosekit @prosekit/svelte
Peer dependencies:
Quick Start
Create a basic editor with Svelte:
< script lang = "ts" >
import { createEditor } from '@prosekit/core'
import { ProseKit , useEditor } from '@prosekit/svelte'
import { defineBasicExtension } from '@prosekit/extensions'
import EditorContent from './EditorContent.svelte'
const editor = createEditor ({
extension: defineBasicExtension ()
})
</ script >
< ProseKit { editor } >
< EditorContent />
</ ProseKit >
<!-- EditorContent.svelte -->
< script lang = "ts" >
import { useEditor } from '@prosekit/svelte'
import { onMount } from 'svelte'
const editor = useEditor ()
let editorElement : HTMLElement
onMount (() => {
if ( editorElement ) {
$ editor . mount ( editorElement )
}
})
</ script >
< div bind : this = { editorElement } ></ div >
Core Components
ProseKit
The root component that provides editor context to all child components.
< script lang = "ts" >
import { ProseKit } from '@prosekit/svelte'
import type { Editor } from '@prosekit/core'
let editor : Editor
</ script >
< ProseKit { editor } >
<!-- Your editor UI components -->
</ ProseKit >
Props:
editor: The editor instance created with createEditor()
Essential Functions
useEditor
Retrieves the editor instance from the nearest ProseKit component.
< script lang = "ts" >
import { useEditor } from '@prosekit/svelte'
const editor = useEditor ()
function toggleBold () {
$ editor . commands . toggleBold ()
}
</ script >
< button onclick = { toggleBold } > Bold </ button >
Returns: Readable<Editor> (Svelte store)
Options:
update?: boolean - Whether to update the store when editor state changes (default: false)
// Update store on every state update
const editor = useEditor ({ update: true })
useEditorDerivedValue
Compute and subscribe to derived values from the editor state.
< script lang = "ts" >
import { useEditorDerivedValue } from '@prosekit/svelte'
const wordCount = useEditorDerivedValue (( editor ) => {
return editor . state . doc . textContent . split ( / \s + / ). length
})
</ script >
< div > Words: { $ wordCount } </ div >
useExtension
Dynamically add extensions to the editor.
< script lang = "ts" >
import { useExtension } from '@prosekit/svelte'
import { defineCodeBlock } from '@prosekit/extensions'
let enableCodeBlock = $ state ( false )
const extension = $ derived ( enableCodeBlock ? defineCodeBlock () : null )
useExtension ( extension )
</ script >
< label >
< input type = "checkbox" bind : checked = { enableCodeBlock } />
Enable Code Blocks
</ label >
Options:
editor?: Editor - Optional editor instance (defaults to context editor)
priority?: Priority - Extension priority
useKeymap
Define keyboard shortcuts.
< script lang = "ts" >
import { useKeymap } from '@prosekit/svelte'
useKeymap ({
'Mod-s' : () => {
console . log ( 'Save triggered' )
return true
}
})
</ script >
useDocChange
Execute a callback when the document changes.
< script lang = "ts" >
import { useDocChange } from '@prosekit/svelte'
useDocChange (( editor ) => {
const json = editor . getDocJSON ()
localStorage . setItem ( 'doc' , JSON . stringify ( json ))
})
</ script >
useStateUpdate
Execute a callback on every state update (including selection changes).
< script lang = "ts" >
import { useStateUpdate } from '@prosekit/svelte'
let selection = $ state ({ from: 0 , to: 0 })
useStateUpdate (( editor ) => {
selection = editor . state . selection
})
</ script >
Custom Node Views
Create interactive node views with Svelte components:
// image-extension.ts
import { defineSvelteNodeView } from '@prosekit/svelte'
import ImageComponent from './ImageComponent.svelte'
export const imageExtension = defineSvelteNodeView ({
name: 'image' ,
component: ImageComponent ,
contentDOM: false ,
})
<!-- ImageComponent.svelte -->
< script lang = "ts" >
import type { SvelteNodeViewProps } from '@prosekit/svelte'
let { node , setAttrs } : SvelteNodeViewProps = $ props ()
function handleClick () {
setAttrs ({ selected: true })
}
</ script >
< img
src = { node . attrs . src }
alt = { node . attrs . alt }
onclick = { handleClick }
/>
SvelteNodeViewProps:
node - The ProseMirror node
view - The editor view
getPos - Function to get node position
setAttrs - Function to update node attributes
decorations - Node decorations
selected - Whether the node is selected
Custom Mark Views
Create custom mark rendering with Svelte:
// comment-extension.ts
import { defineSvelteMarkView } from '@prosekit/svelte'
import CommentMark from './CommentMark.svelte'
export const commentExtension = defineSvelteMarkView ({
name: 'comment' ,
component: CommentMark ,
})
<!-- CommentMark.svelte -->
< script lang = "ts" >
import type { SvelteMarkViewProps } from '@prosekit/svelte'
let { mark , children } : SvelteMarkViewProps = $ props ()
const commentId = mark . attrs . id
</ script >
< span
class = "comment"
data-comment-id = { commentId }
>
{@ render children ()}
</ span >
UI Components
ProseKit provides pre-built Svelte components for common editor UI patterns:
Autocomplete
< script lang = "ts" >
import {
AutocompletePopover ,
AutocompleteItem ,
AutocompleteList ,
AutocompleteEmpty
} from '@prosekit/svelte/autocomplete'
</ script >
< AutocompletePopover >
< AutocompleteList >
< AutocompleteEmpty > No results </ AutocompleteEmpty >
< AutocompleteItem value = "svelte" > Svelte </ AutocompleteItem >
< AutocompleteItem value = "react" > React </ AutocompleteItem >
</ AutocompleteList >
</ AutocompletePopover >
Inline Popover
< script lang = "ts" >
import { InlinePopover } from '@prosekit/svelte/inline-popover'
</ script >
< InlinePopover >
< button > Bold </ button >
< button > Italic </ button >
</ InlinePopover >
< script lang = "ts" >
import { TooltipRoot , TooltipTrigger , TooltipContent } from '@prosekit/svelte/tooltip'
</ script >
< TooltipRoot >
< TooltipTrigger >
< button > Hover me </ button >
</ TooltipTrigger >
< TooltipContent >
Tooltip text
</ TooltipContent >
</ TooltipRoot >
Popover
< script lang = "ts" >
import { PopoverRoot , PopoverTrigger , PopoverContent } from '@prosekit/svelte/popover'
</ script >
< PopoverRoot >
< PopoverTrigger >
< button > Open </ button >
</ PopoverTrigger >
< PopoverContent >
Popover content
</ PopoverContent >
</ PopoverRoot >
Block Handle
< script lang = "ts" >
import { BlockHandleDraggable , BlockHandleAdd , BlockHandlePopover } from '@prosekit/svelte/block-handle'
</ script >
< BlockHandleDraggable />
< BlockHandleAdd />
< BlockHandlePopover >
<!-- Block options -->
</ BlockHandlePopover >
Table Handle
< script lang = "ts" >
import {
TableHandleRoot ,
TableHandleColumnRoot ,
TableHandleColumnTrigger ,
TableHandleRowRoot ,
TableHandleRowTrigger
} from '@prosekit/svelte/table-handle'
</ script >
< TableHandleRoot >
< TableHandleColumnRoot >
< TableHandleColumnTrigger />
</ TableHandleColumnRoot >
< TableHandleRowRoot >
< TableHandleRowTrigger />
</ TableHandleRowRoot >
</ TableHandleRoot >
Resizable
< script lang = "ts" >
import { ResizableRoot , ResizableHandle } from '@prosekit/svelte/resizable'
</ script >
< ResizableRoot >
< img src = "image.jpg" />
< ResizableHandle />
</ ResizableRoot >
TypeScript Support
ProseKit has full TypeScript support with type inference:
import { createEditor } from '@prosekit/core'
import { useEditor } from '@prosekit/svelte'
import { defineBasicExtension } from '@prosekit/extensions'
const extension = defineBasicExtension ()
const editor = createEditor ({ extension })
// Editor type is automatically inferred
const editorStore = useEditor ()
// $editorStore.commands has autocomplete for all available commands
$editorStore . commands . toggleBold ()
Svelte 5 Runes
ProseKit works seamlessly with Svelte 5’s new runes:
< script lang = "ts" >
import { createEditor } from '@prosekit/core'
import { ProseKit , useEditor } from '@prosekit/svelte'
import { defineBasicExtension } from '@prosekit/extensions'
let content = $ state ( '' )
const editor = createEditor ({
extension: defineBasicExtension ()
})
const editorRef = useEditor ()
$ effect (() => {
content = $ editorRef . state . doc . textContent
})
</ script >
< ProseKit { editor } >
< div > Content length: { content . length } </ div >
</ ProseKit >
Server-Side Rendering (SSR)
ProseKit supports server-side rendering with SvelteKit:
< script lang = "ts" >
import { createEditor } from '@prosekit/core'
import { ProseKit } from '@prosekit/svelte'
import { defineBasicExtension } from '@prosekit/extensions'
import { onMount } from 'svelte'
import { browser } from '$app/environment'
let editor = $ state ( null )
onMount (() => {
if ( browser ) {
editor = createEditor ({
extension: defineBasicExtension ()
})
}
})
</ script >
{# if editor }
< ProseKit { editor } >
<!-- Editor components -->
</ ProseKit >
{/ if }
Examples
Check out full working examples:
Next Steps
Extensions Learn about available extensions
Commands Explore editor commands
Styling Customize editor appearance
API Reference Full API documentation