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) => {
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. React, Vue, and Svelte let you customize it with compound components; Angular renders a built-in loading row you style with CSS.
<Mentions.Loading>
<Spinner /> Searching...
</Mentions.Loading> <MentionsLoading>
<Spinner /> Searching...
</MentionsLoading> <MentionsLoading>
<Spinner /> Searching...
</MentionsLoading> /* The loading row is rendered automatically — style it: */
.sa-mentions-empty { color: var(--muted); font-style: italic; } Error Handling
Fetch errors are caught and reported via the error callback.
<Mentions
triggers={triggers}
onError={(error) => toast.error(error.message)}
/> <Mentions
:triggers="triggers"
@error="(error) => toast.error(error.message)"
/> <Mentions
{triggers}
onError={(error) => toast.error(error.message)}
/> import { provideMentions } from "@skyastrall/mentions-angular";
// In your app config (or component) providers:
providers: [
provideMentions({ onError: (error) => toast.error(error.message) }),
] If a fetch fails, the dropdown closes and the user can retry by typing more.