diff --git a/native/markdown/markdown-link.react.js b/native/markdown/markdown-link.react.js
--- a/native/markdown/markdown-link.react.js
+++ b/native/markdown/markdown-link.react.js
@@ -1,69 +1,12 @@
 // @flow
 
-import invariant from 'invariant';
 import * as React from 'react';
-import { Text, Linking } from 'react-native';
-
-import { inviteLinkUrl } from 'lib/facts/links.js';
+import { Text } from 'react-native';
 
 import {
-  MarkdownContext,
-  type MarkdownContextType,
-} from './markdown-context.js';
-import { MarkdownSpoilerContext } from './markdown-spoiler-context.js';
-import { MessagePressResponderContext } from '../chat/message-press-responder-context.js';
-import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context.js';
-import { InviteLinksContext } from '../invite-links/invite-links-context-provider.react.js';
-import Alert from '../utils/alert.js';
-import { normalizeURL } from '../utils/url-utils.js';
-
-function useHandleLinkClick(
-  inputURL: string,
-  markdownContext: MarkdownContextType,
-  messageKey: ?string,
-) {
-  const { setLinkModalActive } = markdownContext;
-  const onDismiss = React.useCallback(() => {
-    messageKey && setLinkModalActive({ [messageKey]: false });
-  }, [setLinkModalActive, messageKey]);
-
-  const url = normalizeURL(inputURL);
-  const onConfirm = React.useCallback(() => {
-    onDismiss();
-    Linking.openURL(url);
-  }, [url, onDismiss]);
-
-  let displayURL = url.substring(0, 64);
-  if (url.length > displayURL.length) {
-    displayURL += '…';
-  }
-
-  const inviteLinksContext = React.useContext(InviteLinksContext);
-  return React.useCallback(() => {
-    if (url.startsWith(inviteLinkUrl(''))) {
-      inviteLinksContext?.setCurrentLinkUrl(url);
-      return;
-    }
-    messageKey && setLinkModalActive({ [messageKey]: true });
-    Alert.alert(
-      'External link',
-      `You sure you want to open this link?\n\n${displayURL}`,
-      [
-        { text: 'Cancel', style: 'cancel', onPress: onDismiss },
-        { text: 'Open', onPress: onConfirm },
-      ],
-      { cancelable: true, onDismiss },
-    );
-  }, [
-    url,
-    messageKey,
-    setLinkModalActive,
-    displayURL,
-    onDismiss,
-    onConfirm,
-    inviteLinksContext,
-  ]);
-}
+  useMarkdownOnPressUtils,
+  useHandleLinkClick,
+} from './markdown-utils.js';
 
 type TextProps = React.ElementConfig<typeof Text>;
 type Props = {
@@ -73,33 +16,17 @@
 };
 function MarkdownLink(props: Props): React.Node {
   const { target, ...rest } = props;
-
-  const markdownContext = React.useContext(MarkdownContext);
-  invariant(markdownContext, 'MarkdownContext should be set');
-
-  const markdownSpoilerContext = React.useContext(MarkdownSpoilerContext);
-  // Since MarkdownSpoilerContext may not be set, we need
-  // to default isRevealed to true for when
-  // we use the ternary operator in the onPress
-  const isRevealed = markdownSpoilerContext?.isRevealed ?? true;
-
-  const textMessageMarkdownContext = React.useContext(
-    TextMessageMarkdownContext,
-  );
-  const messageKey = textMessageMarkdownContext?.messageKey;
-
-  const messagePressResponderContext = React.useContext(
-    MessagePressResponderContext,
+  const { markdownContext, messageKey, shouldBePressable, onLongPressHandler } =
+    useMarkdownOnPressUtils();
+  const onPressHandler = useHandleLinkClick(
+    target,
+    markdownContext,
+    messageKey,
   );
-
-  const onPressMessage = messagePressResponderContext?.onPressMessage;
-
-  const onPressLink = useHandleLinkClick(target, markdownContext, messageKey);
-
   return (
     <Text
-      onPress={isRevealed ? onPressLink : null}
-      onLongPress={isRevealed ? onPressMessage : null}
+      onPress={shouldBePressable ? onPressHandler : null}
+      onLongPress={shouldBePressable ? onLongPressHandler : null}
       {...rest}
     />
   );
diff --git a/native/markdown/markdown-link.react.js b/native/markdown/markdown-utils.js
copy from native/markdown/markdown-link.react.js
copy to native/markdown/markdown-utils.js
--- a/native/markdown/markdown-link.react.js
+++ b/native/markdown/markdown-utils.js
@@ -2,7 +2,7 @@
 
 import invariant from 'invariant';
 import * as React from 'react';
-import { Text, Linking } from 'react-native';
+import { Linking } from 'react-native';
 
 import { inviteLinkUrl } from 'lib/facts/links.js';
 
@@ -17,11 +17,47 @@
 import Alert from '../utils/alert.js';
 import { normalizeURL } from '../utils/url-utils.js';
 
+function useMarkdownOnPressUtils(blockOnPress: boolean = false): {
+  markdownContext: MarkdownContextType,
+  shouldBePressable: boolean,
+  messageKey: ?string,
+  onLongPressHandler: ?() => void,
+} {
+  const markdownContext = React.useContext(MarkdownContext);
+  invariant(markdownContext, 'MarkdownContext should be set');
+
+  const markdownSpoilerContext = React.useContext(MarkdownSpoilerContext);
+  // Since MarkdownSpoilerContext may not be set, we need
+  // to default isRevealed to true for when
+  // we use the ternary operator in the onPress
+  const isRevealed = markdownSpoilerContext?.isRevealed ?? true;
+
+  const shouldBePressable = blockOnPress ? false : isRevealed;
+
+  const textMessageMarkdownContext = React.useContext(
+    TextMessageMarkdownContext,
+  );
+  const messageKey = textMessageMarkdownContext?.messageKey;
+
+  const messagePressResponderContext = React.useContext(
+    MessagePressResponderContext,
+  );
+
+  const onLongPressHandler = messagePressResponderContext?.onPressMessage;
+
+  return {
+    markdownContext,
+    shouldBePressable,
+    messageKey,
+    onLongPressHandler,
+  };
+}
+
 function useHandleLinkClick(
   inputURL: string,
   markdownContext: MarkdownContextType,
   messageKey: ?string,
-) {
+): () => void {
   const { setLinkModalActive } = markdownContext;
   const onDismiss = React.useCallback(() => {
     messageKey && setLinkModalActive({ [messageKey]: false });
@@ -65,44 +101,4 @@
   ]);
 }
 
-type TextProps = React.ElementConfig<typeof Text>;
-type Props = {
-  +target: string,
-  +children: React.Node,
-  ...TextProps,
-};
-function MarkdownLink(props: Props): React.Node {
-  const { target, ...rest } = props;
-
-  const markdownContext = React.useContext(MarkdownContext);
-  invariant(markdownContext, 'MarkdownContext should be set');
-
-  const markdownSpoilerContext = React.useContext(MarkdownSpoilerContext);
-  // Since MarkdownSpoilerContext may not be set, we need
-  // to default isRevealed to true for when
-  // we use the ternary operator in the onPress
-  const isRevealed = markdownSpoilerContext?.isRevealed ?? true;
-
-  const textMessageMarkdownContext = React.useContext(
-    TextMessageMarkdownContext,
-  );
-  const messageKey = textMessageMarkdownContext?.messageKey;
-
-  const messagePressResponderContext = React.useContext(
-    MessagePressResponderContext,
-  );
-
-  const onPressMessage = messagePressResponderContext?.onPressMessage;
-
-  const onPressLink = useHandleLinkClick(target, markdownContext, messageKey);
-
-  return (
-    <Text
-      onPress={isRevealed ? onPressLink : null}
-      onLongPress={isRevealed ? onPressMessage : null}
-      {...rest}
-    />
-  );
-}
-
-export default MarkdownLink;
+export { useMarkdownOnPressUtils, useHandleLinkClick };