The autocomplete extension executes custom logic when the text before the cursor matches a regular expression pattern. It’s commonly used for mentions, slash commands, and other context-aware suggestions.
Installation
The autocomplete extension is included in the prosekit package.
import { defineAutocomplete, AutocompleteRule } from 'prosekit/extensions/autocomplete'
Usage
import { createEditor } from 'prosekit/core'
import { defineAutocomplete, AutocompleteRule } from 'prosekit/extensions/autocomplete'
const mentionRule = new AutocompleteRule({
regex: /@([\w]+)$/,
onMatch: ({ match, setOpen }) => {
const query = match[1]
setOpen(true)
},
onExit: ({ setOpen }) => {
setOpen(false)
},
})
const editor = createEditor({
extension: defineAutocomplete(mentionRule)
})
API reference
defineAutocomplete(rule)
Creates an autocomplete extension that executes logic when text matches the given pattern.
An autocomplete rule defining the pattern and behavior.
AutocompleteRule
Class for defining autocomplete behavior.
Regular expression to match text before the cursor.
options.onMatch
(options: MatchHandlerOptions) => void
required
Handler called when text matches the regex. Receives:
match - The regex match array
text - The full matched text
from - Starting position of match
to - Ending position of match
view - The editor view
setOpen - Function to show/hide autocomplete UI
options.onExit
(options: MatchHandlerOptions) => void
Handler called when text no longer matches. Use this to clean up UI.
Optional predicate to determine if matching should occur in current context.
How it works
When a match is found:
- An inline decoration is applied to matched text
- The decoration has class
prosekit-autocomplete-match
- A
data-autocomplete-match-text attribute contains the matched string
- Your
onMatch handler is called to show UI
Examples
Mention autocomplete
import { AutocompleteRule } from 'prosekit/extensions/autocomplete'
const mentionRule = new AutocompleteRule({
regex: /@([\w]+)$/,
onMatch: ({ match, setOpen, from, to }) => {
const query = match[1]
// Show autocomplete popover with filtered users
setOpen(true)
},
onExit: ({ setOpen }) => {
// Hide autocomplete popover
setOpen(false)
},
})
Slash commands
import { AutocompleteRule } from 'prosekit/extensions/autocomplete'
const slashRule = new AutocompleteRule({
regex: /^\/([\w]*)$/,
onMatch: ({ match, setOpen }) => {
const query = match[1]
// Show command palette with filtered commands
setOpen(true)
},
onExit: ({ setOpen }) => {
setOpen(false)
},
})
Emoji autocomplete
import { AutocompleteRule } from 'prosekit/extensions/autocomplete'
const emojiRule = new AutocompleteRule({
regex: /:([\w]+)$/,
onMatch: ({ match, setOpen }) => {
const query = match[1]
// Show emoji picker with filtered emojis
setOpen(true)
},
onExit: ({ setOpen }) => {
setOpen(false)
},
})
Conditional matching
import { AutocompleteRule } from 'prosekit/extensions/autocomplete'
import { isInCodeBlock } from 'prosekit/core'
const mentionRule = new AutocompleteRule({
regex: /@([\w]+)$/,
canMatch: ({ state }) => {
// Don't match in code blocks
return !isInCodeBlock(state)
},
onMatch: ({ match, setOpen }) => {
setOpen(true)
},
onExit: ({ setOpen }) => {
setOpen(false)
},
})
With UI components
Use with ProseKit’s autocomplete components:
import { useEditor } from 'prosekit/react'
import { AutocompletePopover, AutocompleteList, AutocompleteItem } from 'prosekit/react/autocomplete'
import { defineAutocomplete, AutocompleteRule } from 'prosekit/extensions/autocomplete'
const mentionRule = new AutocompleteRule({
regex: /@([\w]+)$/,
onMatch: ({ setOpen }) => setOpen(true),
onExit: ({ setOpen }) => setOpen(false),
})
export default function Editor() {
const editor = useEditor({
extension: defineAutocomplete(mentionRule)
})
return (
<ProseKit editor={editor}>
<div ref={editor.mount} />
<AutocompletePopover regex={/@([\w]+)$/}>
<AutocompleteList>
<AutocompleteItem value="alice">@alice</AutocompleteItem>
<AutocompleteItem value="bob">@bob</AutocompleteItem>
</AutocompleteList>
</AutocompletePopover>
</ProseKit>
)
}
Styling the match
.prosekit-autocomplete-match {
background-color: rgba(37, 99, 235, 0.1);
border-radius: 2px;
}