Skip to main content
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.
rule
AutocompleteRule
required
An autocomplete rule defining the pattern and behavior.

AutocompleteRule

Class for defining autocomplete behavior.
options.regex
RegExp
required
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.
options.canMatch
CanMatchPredicate
Optional predicate to determine if matching should occur in current context.

How it works

When a match is found:
  1. An inline decoration is applied to matched text
  2. The decoration has class prosekit-autocomplete-match
  3. A data-autocomplete-match-text attribute contains the matched string
  4. 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;
}