Async Data

Fetch suggestions from an API. Debouncing, aborting, and loading states are built in.

Basic Async Fetcher

Pass a function instead of an array to data.

const triggers = [{
  char: "@",
  data: async (query) => {
    const res = await fetch(`/api/users?q=${encodeURIComponent(query)}`);
    return res.json();
  },
  debounce: 300,
}];

Using Context

The fetcher receives a MentionContext with editor state for smarter suggestions.

const triggers = [{
  char: "@",
  data: async (query, context) => {
    // Don't suggest users already mentioned
    const exclude = context.activeMentions.map(m => m.id);
    const res = await fetch(`/api/users?q=${query}&exclude=${exclude.join(",")}`);
    return res.json();
  },
}];

Debounce

Set debounce to control how long to wait after typing stops before fetching. Default is 200ms.

{ char: "@", data: fetchUsers, debounce: 500 }

Minimum Characters

Require a minimum query length before fetching.

{ char: "@", data: fetchUsers, minChars: 2 }

Loading State

The component shows a loading indicator automatically. Customize it with compound components:

<Mentions.Loading>
  <Spinner /> Searching...
</Mentions.Loading>

Error Handling

Fetch errors are caught and reported via onError.

<Mentions
  triggers={triggers}
  onError={(error) => toast.error(error.message)}
/>

If a fetch fails, the dropdown closes and the user can retry by typing more.