Custom emojis
Add your own image-based emotes alongside the Unicode set
Emoteer ships the full Unicode emoji set by default. You can extend it with your own image-based emotes ("custom emotes") by passing a locals array to the EmoteProvider.
Adding custom emotes
Each entry is a LocalEmote:
interface LocalEmote {
id: string; // stable identifier — used as the React key
name: string; // display name, also the shortcode (without colons)
src: string; // URL or local path to the image
category?: string; // optional free-form label, indexed for search
}Pass them to the provider:
import { EmoteProvider } from '@emoteer/react';
const locals = [
{ id: 'party-parrot', name: 'party_parrot', src: '/emotes/party-parrot.gif' },
{ id: 'emoteer', name: 'emoteer', src: '/emotes/brand.png', category: 'brand' },
];
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<EmoteProvider locals={locals}>
{children}
</EmoteProvider>
);
}Where they show up
| Component | Support |
|---|---|
EmoteList.Grid | ✅ Rendered under a "Custom" section at the top. |
EmoteList.Tabs | ✅ "Custom" tab appears when locals.length > 0. |
EmoteList.Search | ✅ Matches against name and category. |
EmoteList.Preview | ✅ Image preview; copy button writes :name: to clipboard; can be favourited. |
EmoteAutocomplete | ✅ Suggested when typing :<name> — selecting inserts :name: (not a glyph). |
EmoteInput / EmoteTextArea | ❌ <input> / <textarea> can't embed images. :name: is preserved verbatim. |
ReactionCounter / ReactionButton | ❌ These accept raw emoji strings, not emotes. Pass the emoji/glyph directly and render an <img> yourself if needed. |
Reading the selection
All picker/autocomplete onSelect callbacks now fire with an Emote union — native or local. Use the isLocalEmote helper to branch:
import { EmoteList, isLocalEmote, type Emote } from '@emoteer/react';
function Picker() {
const handleSelect = (emote: Emote) => {
if (isLocalEmote(emote)) {
insertImage(emote.src); // render your own <img>
} else {
insertText(emote.unicode); // native glyph
}
};
return (
<EmoteList.Root onSelect={handleSelect}>
<EmoteList.Search />
<EmoteList.Tabs />
<EmoteList.Grid />
<EmoteList.Preview />
</EmoteList.Root>
);
}Shortcode collisions
If a local name collides with a native shortcode (e.g. you define name: "smile"), the local wins — locals are inserted into the shortcode index after natives, so the last writer wins.
Disabling natives
If you want a brand-only picker with no Unicode emojis, set natives={false}:
<EmoteProvider natives={false} locals={locals}>
{children}
</EmoteProvider>Localising shortcodes
Pass a BCP 47 locale to load a different native shortcode dictionary:
<EmoteProvider locale="es" locals={locals}>
{children}
</EmoteProvider>Bundled locales include en, en-gb, es, es-mx, fr, de, it, ja, ko, pt, zh, zh-hant, and many more. Unsupported tags fall back to en at runtime.