diff --git a/web/chat/chat-message-list.react.js b/web/chat/chat-message-list.react.js
--- a/web/chat/chat-message-list.react.js
+++ b/web/chat/chat-message-list.react.js
@@ -19,7 +19,10 @@
   useMessageListData,
 } from 'lib/selectors/chat-selectors.js';
 import { messageKey } from 'lib/shared/message-utils.js';
-import { threadIsPending } from 'lib/shared/thread-utils.js';
+import {
+  threadIsPending,
+  useThreadChatMentionCandidates,
+} from 'lib/shared/thread-utils.js';
 import type { FetchMessageInfosPayload } from 'lib/types/message-types.js';
 import { threadTypes } from 'lib/types/thread-types-enum.js';
 import { type ThreadInfo } from 'lib/types/thread-types.js';
@@ -437,7 +440,11 @@
 
     const { clearTooltip } = useTooltipContext();
 
-    const getTextMessageMarkdownRules = useTextMessageRulesFunc(threadInfo);
+    const chatMentionCandidates = useThreadChatMentionCandidates(threadInfo);
+    const getTextMessageMarkdownRules = useTextMessageRulesFunc(
+      threadInfo,
+      chatMentionCandidates,
+    );
     const messageListContext = React.useMemo(() => {
       if (!getTextMessageMarkdownRules) {
         return undefined;
diff --git a/web/chat/message-preview.react.js b/web/chat/message-preview.react.js
--- a/web/chat/message-preview.react.js
+++ b/web/chat/message-preview.react.js
@@ -5,6 +5,7 @@
 import * as React from 'react';
 
 import { useMessagePreview } from 'lib/shared/message-utils.js';
+import { useThreadChatMentionCandidates } from 'lib/shared/thread-utils.js';
 import { type MessageInfo } from 'lib/types/message-types.js';
 import { type ThreadInfo } from 'lib/types/thread-types.js';
 
@@ -17,10 +18,11 @@
 };
 function MessagePreview(props: Props): React.Node {
   const { messageInfo, threadInfo } = props;
+  const chatMentionCandidates = useThreadChatMentionCandidates(threadInfo);
   const messagePreviewResult = useMessagePreview(
     messageInfo,
     threadInfo,
-    getDefaultTextMessageRules().simpleMarkdownRules,
+    getDefaultTextMessageRules(chatMentionCandidates).simpleMarkdownRules,
   );
 
   if (!messageInfo) {
diff --git a/web/components/message-result.react.js b/web/components/message-result.react.js
--- a/web/components/message-result.react.js
+++ b/web/components/message-result.react.js
@@ -5,6 +5,7 @@
 
 import { useStringForUser } from 'lib/hooks/ens-cache.js';
 import type { ChatMessageInfoItem } from 'lib/selectors/chat-selectors.js';
+import { useThreadChatMentionCandidates } from 'lib/shared/thread-utils.js';
 import type { ThreadInfo } from 'lib/types/thread-types.js';
 import { longAbsoluteDate } from 'lib/utils/date-utils.js';
 
@@ -22,7 +23,11 @@
 function MessageResult(props: MessageResultProps): React.Node {
   const { item, threadInfo, scrollable } = props;
 
-  const getTextMessageMarkdownRules = useTextMessageRulesFunc(threadInfo);
+  const chatMentionCandidates = useThreadChatMentionCandidates(threadInfo);
+  const getTextMessageMarkdownRules = useTextMessageRulesFunc(
+    threadInfo,
+    chatMentionCandidates,
+  );
   const messageListContext = React.useMemo(() => {
     if (!getTextMessageMarkdownRules) {
       return undefined;
diff --git a/web/markdown/rules.react.js b/web/markdown/rules.react.js
--- a/web/markdown/rules.react.js
+++ b/web/markdown/rules.react.js
@@ -5,7 +5,11 @@
 import * as SimpleMarkdown from 'simple-markdown';
 
 import * as SharedMarkdown from 'lib/shared/markdown.js';
-import type { RelativeMemberInfo, ThreadInfo } from 'lib/types/thread-types.js';
+import type {
+  RelativeMemberInfo,
+  ThreadInfo,
+  ChatMentionCandidates,
+} from 'lib/types/thread-types.js';
 
 import MarkdownSpoiler from './markdown-spoiler.react.js';
 
@@ -159,19 +163,21 @@
 
 function useTextMessageRulesFunc(
   threadInfo: ThreadInfo,
+  chatMentionCandidates: ChatMentionCandidates,
 ): boolean => MarkdownRules {
   const { members } = threadInfo;
   return React.useMemo(
     () =>
       _memoize<[boolean], MarkdownRules>((useDarkStyle: boolean) =>
-        textMessageRules(members, useDarkStyle),
+        textMessageRules(members, chatMentionCandidates, useDarkStyle),
       ),
-    [members],
+    [chatMentionCandidates, members],
   );
 }
 
 function textMessageRules(
   members: $ReadOnlyArray<RelativeMemberInfo>,
+  chatMentionCandidates: ChatMentionCandidates,
   useDarkStyle: boolean,
 ): MarkdownRules {
   const baseRules = markdownRules(useDarkStyle);
@@ -198,9 +204,14 @@
 
 let defaultTextMessageRules = null;
 
-function getDefaultTextMessageRules(): MarkdownRules {
+function getDefaultTextMessageRules(
+  overrideDefaultChatMentionCandidates: ChatMentionCandidates = {},
+): MarkdownRules {
+  if (Object.keys(overrideDefaultChatMentionCandidates).length > 0) {
+    return textMessageRules([], overrideDefaultChatMentionCandidates, false);
+  }
   if (!defaultTextMessageRules) {
-    defaultTextMessageRules = textMessageRules([], false);
+    defaultTextMessageRules = textMessageRules([], {}, false);
   }
   return defaultTextMessageRules;
 }
diff --git a/web/modals/threads/sidebars/sidebar.react.js b/web/modals/threads/sidebars/sidebar.react.js
--- a/web/modals/threads/sidebars/sidebar.react.js
+++ b/web/modals/threads/sidebars/sidebar.react.js
@@ -6,6 +6,7 @@
 import { useModalContext } from 'lib/components/modal-provider.react.js';
 import type { ChatThreadItem } from 'lib/selectors/chat-selectors.js';
 import { useMessagePreview } from 'lib/shared/message-utils.js';
+import { useThreadChatMentionCandidates } from 'lib/shared/thread-utils.js';
 import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
 import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
 
@@ -52,10 +53,11 @@
     [lastUpdatedTime],
   );
 
+  const chatMentionCandidates = useThreadChatMentionCandidates(threadInfo);
   const messagePreviewResult = useMessagePreview(
     mostRecentMessageInfo,
     threadInfo,
-    getDefaultTextMessageRules().simpleMarkdownRules,
+    getDefaultTextMessageRules(chatMentionCandidates).simpleMarkdownRules,
   );
 
   const lastMessage = React.useMemo(() => {
diff --git a/web/modals/threads/subchannels/subchannel.react.js b/web/modals/threads/subchannels/subchannel.react.js
--- a/web/modals/threads/subchannels/subchannel.react.js
+++ b/web/modals/threads/subchannels/subchannel.react.js
@@ -6,6 +6,7 @@
 import { useModalContext } from 'lib/components/modal-provider.react.js';
 import { type ChatThreadItem } from 'lib/selectors/chat-selectors.js';
 import { useMessagePreview } from 'lib/shared/message-utils.js';
+import { useThreadChatMentionCandidates } from 'lib/shared/thread-utils.js';
 import { shortAbsoluteDate } from 'lib/utils/date-utils.js';
 import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
 
@@ -50,11 +51,11 @@
     () => shortAbsoluteDate(lastUpdatedTimeIncludingSidebars),
     [lastUpdatedTimeIncludingSidebars],
   );
-
+  const chatMentionCandidates = useThreadChatMentionCandidates(threadInfo);
   const messagePreviewResult = useMessagePreview(
     mostRecentMessageInfo,
     threadInfo,
-    getDefaultTextMessageRules().simpleMarkdownRules,
+    getDefaultTextMessageRules(chatMentionCandidates).simpleMarkdownRules,
   );
 
   const lastMessage = React.useMemo(() => {
diff --git a/web/selectors/thread-selectors.js b/web/selectors/thread-selectors.js
--- a/web/selectors/thread-selectors.js
+++ b/web/selectors/thread-selectors.js
@@ -10,6 +10,7 @@
 import {
   createPendingSidebar,
   threadInHomeChatList,
+  useThreadChatMentionCandidates,
 } from 'lib/shared/thread-utils.js';
 import type {
   ComposableMessageInfo,
@@ -72,6 +73,7 @@
   const cacheContext = React.useContext(ENSCacheContext);
   const { getENSNames } = cacheContext;
 
+  const chatMentionCandidates = useThreadChatMentionCandidates(threadInfo);
   return React.useCallback(
     async (event: SyntheticEvent<HTMLElement>) => {
       event.preventDefault();
@@ -82,7 +84,8 @@
         sourceMessageInfo: messageInfo,
         parentThreadInfo: threadInfo,
         loggedInUserInfo,
-        markdownRules: getDefaultTextMessageRules().simpleMarkdownRules,
+        markdownRules: getDefaultTextMessageRules(chatMentionCandidates)
+          .simpleMarkdownRules,
         getENSNames,
       });
       dispatch({
@@ -93,7 +96,14 @@
         },
       });
     },
-    [loggedInUserInfo, messageInfo, threadInfo, dispatch, getENSNames],
+    [
+      loggedInUserInfo,
+      chatMentionCandidates,
+      threadInfo,
+      messageInfo,
+      getENSNames,
+      dispatch,
+    ],
   );
 }