diff --git a/locales/index.d.ts b/locales/index.d.ts
index 890658b10b..ce6212faf1 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -582,6 +582,10 @@ export interface Locale extends ILocale {
      * このリアクションで検索
      */
     "searchThisReaction": string;
+    /**
+     * 部分一致
+     */
+    "partialMatch": string;
     /**
      * 返信
      */
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 9861033fdd..07ca634303 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -140,6 +140,7 @@ copyProfileUrl: "プロフィールURLをコピー"
 searchUser: "ユーザーを検索"
 searchThisUsersNotes: "ユーザーのノートを検索"
 searchThisReaction: "このリアクションで検索"
+partialMatch: "部分一致"
 reply: "返信"
 loadMore: "もっと見る"
 showMore: "もっと見る"
diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
index 6da3c7b449..99252a74dc 100644
--- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
@@ -11,7 +11,6 @@ SPDX-License-Identifier: AGPL-3.0-only
 	class="_button"
 	:class="[$style.root, { [$style.reacted]: note.myReaction == reaction, [$style.canToggle]: (canToggle || alternative), [$style.small]: defaultStore.state.reactionsDisplaySize === 'small', [$style.large]: defaultStore.state.reactionsDisplaySize === 'large' }]"
 	@click.stop="(ev) => { canToggle || alternative ? toggleReaction(ev) : stealReaction(ev) }"
-	@contextmenu.stop="onContextmenu"
 	@contextmenu.prevent.stop="menu"
 >
 	<MkReactionIcon :class="defaultStore.state.limitWidthOfReaction ? $style.limitWidth : ''" :reaction="reaction" :emojiUrl="note.reactionEmojis[reaction.substring(1, reaction.length - 1)]" @click.stop="(ev) => { canToggle || alternative ? toggleReaction(ev) : stealReaction(ev) }"/>
@@ -74,19 +73,6 @@ const router = useRouter();
 
 const alternative: ComputedRef<string | null> = computed(() => defaultStore.state.reactableRemoteReactionEnabled ? (customEmojis.value.find(it => it.name === reactionName.value)?.name ?? null) : null);
 
-function onContextmenu(ev: MouseEvent) {
-	if (!advanccedNotesSearchAvailable) return;
-	let menu: MenuItem[];
-	menu = [{
-		text: i18n.ts.searchThisReaction,
-		icon: 'ti ti-search',
-		action: () => {
-			router.push(`/search?type=anote&reactions=${encodeURIComponent(props.reaction)}`);
-		},
-	}];
-	os.contextMenu(menu, ev);
-}
-
 async function toggleReaction(ev: MouseEvent) {
 	if (!canToggle.value) {
 		chooseAlternative(ev);
@@ -171,31 +157,48 @@ function stealReaction(ev: MouseEvent) {
 }
 
 async function menu(ev) {
-	if (!canGetInfo.value) return;
-
-	os.popupMenu([{
+	const isCustomEmoji = props.reaction.endsWith(':');
+	let menu = [isCustomEmoji ? {
 		type: 'label',
 		text: `:${reactionName.value}:`,
-	}, {
+	} : undefined, isCustomEmoji ? {
 		text: i18n.ts.info,
 		icon: 'ti ti-info-circle',
 		action: async () => {
 			const { dispose } = os.popup(MkCustomEmojiDetailedDialog, {
 				emoji: await misskeyApiGet('emoji', {
-					name: props.reaction.replace(/:/g, '').replace(/@\./, ''),
+					name: props.reaction.replace(/:/g, '').replace(/@.+/, ''),
+					...(!props.reaction.endsWith('@.:') && { host: props.reaction.split('@')[1].replace(':', '') }),
 				}),
 			}, {
 				closed: () => dispose(),
 			});
 		},
-	}, customEmojis.value.find(it => it.name === reactionName.value)?.name ? {
+	} : undefined, customEmojis.value.find(it => it.name === reactionName.value)?.name ? {
 		text: i18n.ts.copy,
 		icon: 'ti ti-copy',
 		action: () => {
 			copyToClipboard(`:${reactionName.value}:`);
 			os.toast(i18n.ts.copied, 'copied');
 		},
-	} : undefined], ev.currentTarget ?? ev.target);
+	} : undefined,
+	];
+	if (advanccedNotesSearchAvailable) {
+		menu.push({
+			text: i18n.ts.searchThisReaction,
+			icon: 'ti ti-search',
+			action: () => {
+				router.push(`/search?type=anote&reactions=${encodeURIComponent(isCustomEmoji ? props.reaction.endsWith('@.:') ? props.reaction.replace('@.', '') : props.reaction : props.reaction)}`);
+			},
+		}, isCustomEmoji ? {
+			text: `${i18n.ts.searchThisReaction}(${i18n.ts.partialMatch})`,
+			icon: 'ti ti-search',
+			action: () => {
+				router.push(`/search?type=anote&reactions=${encodeURIComponent(`${ props.reaction.endsWith('@.:') ? props.reaction.replace('@.:', '') : props.reaction.split('@')[0]}*`)}`);
+			},
+		} : undefined );
+	}
+	os.popupMenu(menu, ev.currentTarget ?? ev.target);
 }
 
 function anime() {