1
Custom Emojis
Welcome to the Custom Emojis!
This page will walk you through the basic usage of custom emoji.
If you haven’t installed anything yet, please follow the steps in the Usage Guide before proceeding.
Predefined Custom Emojis
Using Predefined Custom Emojis
// components/Editor.tsx
import * as React from "react";
import { useEditor } from "@tiptap/react";
import { StarterKit } from "@tiptap/starter-kit";
import {
TwemojiExtension,
CustomEmoji,
} from "@raihancodes/tiptap-extension-twemoji-react";
export default function Editor() {
const editor = useEditor({
extensions: [StarterKit, TwemojiExtension],
content: "<p>Hello World!</p>",
immediatelyRender: false,
});
const customEmojis: CustomEmoji[] = [
{
id: "8177849e-c2c9-424a-a914-ff128ce439c5",
label: "github-icon",
url: "...",
},
{
id: "cecf7043-80da-4e3f-b167-6a85de0e464a",
label: "npm-icon",
url: "...",
},
];
React.useEffect(() => {
if (editor) {
editor.commands.updateCustomEmojis(customEmojis);
}
}, [editor]);
return <EditorContent editor={editor} />;
}
Database Custom Emojis
Fetching Example
// page.tsx
import { CustomEmoji } from "@raihancodes/tiptap-extension-twemoji-react";
export default async function Page() {
// Fetch from your database / API / data source
const { data, error } = await fetchFromDatabase("custom-emojis");
if (error) {
console.error("Error fetching emojis:", error);
}
const customEmojis = (data ?? []) as CustomEmoji[];
return <Editor customEmojis={customEmojis} />;
}
Upload & Apply Emojis
Handling Emoji Uploads and Applying Fetched Emojis
"use client";
// components/Editor.tsx
import * as React from "react";
import { useEditor } from "@tiptap/react";
import { StarterKit } from "@tiptap/starter-kit";
import {
EmojiUploadProps,
TwemojiExtension,
CustomEmoji,
} from "@raihancodes/tiptap-extension-twemoji-react";
export default function Editor({
customEmojis,
}: {
customEmojis: CustomEmoji[];
}) {
const handleEmojiUpload: EmojiUploadProps["upload"] = async ({
emojiName,
file,
handleSuccess,
handleError,
dismiss,
}) => {
// Upload to your server / S3 / Supabase
const res = await uploadToServer(file);
if (res.ok) {
handleSuccess(res.message, dismiss);
} else {
handleError(res.message);
}
};
const handleEmojiOnSuccess: EmojiUploadProps["onSuccess"] = (
successMessage,
callback
) => {
console.log(successMessage);
callback?.();
router.refresh(); // optional
};
const handleEmojiOnError: EmojiUploadProps["onError"] = (errorMessage) => {
console.error(errorMessage);
};
const editor = useEditor({
extensions: [
StarterKit,
TwemojiExtension.configure({
customEmojiOptions: {
upload: handleEmojiUpload,
onSuccess: handleEmojiOnSuccess,
onError: handleEmojiOnError,
},
}),
],
content: "<p>Hello World!</p>",
immediatelyRender: false,
});
// Applying Fetched Emojis
React.useEffect(() => {
if (editor) {
editor.commands.updateCustomEmojis(customEmojis);
}
}, [editor, customEmojis]);
return <EditorContent editor={editor} />;
}
Choose the approach that best fits your needs
Quick Demo
For more details, check the example repo on GitHub
What’s Next?
- 👉 Check out the Deep Dive section to learn how to customize the extension—header, navigation, cell size, custom emojis, etc.