diff --git a/web/invite-links/view-invite-link-modal.css b/web/invite-links/copy-invite-link-button.css
copy from web/invite-links/view-invite-link-modal.css
copy to web/invite-links/copy-invite-link-button.css
--- a/web/invite-links/view-invite-link-modal.css
+++ b/web/invite-links/copy-invite-link-button.css
@@ -1,18 +1,3 @@
-.container {
-  padding: 16px 32px 24px;
-}
-
-.description {
-  font-size: var(--s-font-14);
-  color: var(--modal-fg);
-}
-
-.sectionHeader {
-  font-size: var(--m-font-16);
-  color: var(--fg);
-  margin: 32px 0 16px;
-}
-
 .linkContainer {
   display: flex;
   flex-direction: row;
diff --git a/web/invite-links/copy-invite-link-button.react.js b/web/invite-links/copy-invite-link-button.react.js
new file mode 100644
--- /dev/null
+++ b/web/invite-links/copy-invite-link-button.react.js
@@ -0,0 +1,43 @@
+// @flow
+
+import * as React from 'react';
+
+import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
+import { inviteLinkUrl } from 'lib/facts/links.js';
+import { useResettingState } from 'lib/hooks/use-resetting-state.js';
+import type { InviteLink } from 'lib/types/link-types.js';
+
+import css from './copy-invite-link-button.css';
+import Button from '../components/button.react.js';
+
+type Props = {
+  +inviteLink: InviteLink,
+};
+
+const copiedMessageDurationMs = 2000;
+function CopyInviteLinkButton(props: Props): React.Node {
+  const { inviteLink } = props;
+  const url = inviteLinkUrl(inviteLink.name);
+  const [copied, setCopied] = useResettingState(false, copiedMessageDurationMs);
+  const copyLink = React.useCallback(async () => {
+    try {
+      await navigator.clipboard.writeText(url);
+      setCopied(true);
+    } catch (e) {
+      setCopied(false);
+    }
+  }, [setCopied, url]);
+  const buttonText = copied ? 'Copied!' : 'Copy';
+
+  return (
+    <div className={css.linkContainer}>
+      <div className={css.linkUrl}>{url}</div>
+      <Button className={css.linkCopyButton} onClick={copyLink}>
+        <SWMansionIcon icon="link" size={24} />
+        {buttonText}
+      </Button>
+    </div>
+  );
+}
+
+export default CopyInviteLinkButton;
diff --git a/web/invite-links/view-invite-link-modal.css b/web/invite-links/view-invite-link-modal.css
--- a/web/invite-links/view-invite-link-modal.css
+++ b/web/invite-links/view-invite-link-modal.css
@@ -12,26 +12,3 @@
   color: var(--fg);
   margin: 32px 0 16px;
 }
-
-.linkContainer {
-  display: flex;
-  flex-direction: row;
-  justify-content: space-between;
-  align-items: center;
-  background: var(--text-input-bg);
-  padding: 12px 16px;
-  border-radius: 20px;
-}
-
-.linkUrl {
-  font-size: var(--m-font-16);
-  color: var(--label-default-color);
-}
-
-.linkCopyButton {
-  color: var(--fg);
-  font-size: var(--xs-font-12);
-  display: flex;
-  flex-direction: row;
-  gap: 8px;
-}
diff --git a/web/invite-links/view-invite-link-modal.react.js b/web/invite-links/view-invite-link-modal.react.js
--- a/web/invite-links/view-invite-link-modal.react.js
+++ b/web/invite-links/view-invite-link-modal.react.js
@@ -3,15 +3,12 @@
 import * as React from 'react';
 
 import { useModalContext } from 'lib/components/modal-provider.react.js';
-import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { inviteLinkUrl } from 'lib/facts/links.js';
-import { useResettingState } from 'lib/hooks/use-resetting-state.js';
 import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
 import type { InviteLink } from 'lib/types/link-types.js';
 import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
 
+import CopyInviteLinkButton from './copy-invite-link-button.react.js';
 import css from './view-invite-link-modal.css';
-import Button from '../components/button.react.js';
 import Modal from '../modals/modal.react.js';
 import { useSelector } from '../redux/redux-utils.js';
 
@@ -19,7 +16,6 @@
   +inviteLink: InviteLink,
 };
 
-const copiedMessageDurationMs = 2000;
 function ViewInviteLinkModal(props: Props): React.Node {
   const { inviteLink } = props;
   const threadInfo = useSelector(
@@ -28,18 +24,6 @@
   const resolvedThreadInfo = useResolvedThreadInfo(threadInfo);
   const { popModal } = useModalContext();
 
-  const url = inviteLinkUrl(inviteLink.name);
-  const [copied, setCopied] = useResettingState(false, copiedMessageDurationMs);
-  const copyLink = React.useCallback(async () => {
-    try {
-      await navigator.clipboard.writeText(url);
-      setCopied(true);
-    } catch (e) {
-      setCopied(false);
-    }
-  }, [setCopied, url]);
-  const buttonText = copied ? 'Copied!' : 'Copy';
-
   return (
     <Modal
       name={`Invite people to ${resolvedThreadInfo.uiName}`}
@@ -51,13 +35,7 @@
           Use this public link to invite your friends into the community!
         </div>
         <div className={css.sectionHeader}>Public link</div>
-        <div className={css.linkContainer}>
-          <div className={css.linkUrl}>{url}</div>
-          <Button className={css.linkCopyButton} onClick={copyLink}>
-            <SWMansionIcon icon="link" size={24} />
-            {buttonText}
-          </Button>
-        </div>
+        <CopyInviteLinkButton inviteLink={inviteLink} />
       </div>
     </Modal>
   );