Skip to content

Commit 1e6fcac

Browse files
committed
🎨 Reordered share buttons and improved LinkedIn share URL
ref #26866 LinkedIn is now a primary action and uses the shareArticle URL to improve preview unfurl reliability.
1 parent c65bc21 commit 1e6fcac

2 files changed

Lines changed: 30 additions & 22 deletions

File tree

apps/portal/src/components/pages/share-modal.js

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ export const ShareModalStyles = `
293293
order: 2;
294294
}
295295
296-
.gh-portal-share-action.facebook {
296+
.gh-portal-share-action.linkedin {
297297
order: 3;
298298
}
299299
@@ -455,6 +455,14 @@ const createEmailShareLink = ({shareTitle, shareUrl}) => {
455455
return `mailto:${params.length ? `?${params.join('&')}` : ''}`;
456456
};
457457

458+
const createLinkedinShareLink = ({shareTitle, shareUrl}) => {
459+
return createShareLink('https://www.linkedin.com/shareArticle', {
460+
mini: 'true',
461+
url: shareUrl,
462+
title: shareTitle
463+
});
464+
};
465+
458466
const ShareModal = () => {
459467
const [copied, setCopied] = useState(false);
460468
const [isMoreMenuOpen, setIsMoreMenuOpen] = useState(false);
@@ -477,7 +485,7 @@ const ShareModal = () => {
477485
facebook: createShareLink('https://www.facebook.com/sharer/sharer.php', {u: shareUrl}),
478486
email: createEmailShareLink({shareTitle, shareUrl}),
479487
threads: createShareLink('https://www.threads.net/intent/post', {text: threadsText}),
480-
linkedin: createShareLink('https://www.linkedin.com/sharing/share-offsite/', {url: shareUrl}),
488+
linkedin: createLinkedinShareLink({shareTitle, shareUrl}),
481489
bluesky: createShareLink('https://bsky.app/intent/compose', {text: threadsText})
482490
};
483491
}, [shareTitle, shareUrl]);
@@ -616,15 +624,15 @@ const ShareModal = () => {
616624
</a>
617625

618626
<a
619-
className='gh-portal-btn gh-portal-share-action facebook'
620-
href={socialLinks.facebook}
627+
className='gh-portal-btn gh-portal-share-action linkedin'
628+
href={socialLinks.linkedin}
621629
target='_blank'
622630
rel='noopener noreferrer'
623-
aria-label={t('Facebook')}
624-
title={t('Facebook')}
631+
aria-label={t('LinkedIn')}
632+
title={t('LinkedIn')}
625633
>
626634
<span className='gh-portal-share-icon' aria-hidden='true'>
627-
<FacebookIcon />
635+
<LinkedinIcon />
628636
</span>
629637
</a>
630638

@@ -659,16 +667,16 @@ const ShareModal = () => {
659667
<div className='gh-portal-share-more-menu' role='menu' aria-label={t('More options')}>
660668
<a
661669
className='gh-portal-share-more-item'
662-
href={socialLinks.linkedin}
670+
href={socialLinks.facebook}
663671
target='_blank'
664672
rel='noopener noreferrer'
665673
role='menuitem'
666674
onClick={onClickMoreItem}
667675
>
668676
<span className='gh-portal-share-more-item-icon' aria-hidden='true'>
669-
<LinkedinIcon />
677+
<FacebookIcon />
670678
</span>
671-
<span>{t('LinkedIn')}</span>
679+
<span>{t('Facebook')}</span>
672680
</a>
673681
<a
674682
className='gh-portal-share-more-item'

apps/portal/test/unit/components/pages/share-modal.test.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,13 @@ describe('ShareModal', () => {
9595
const actions = Array.from(container.querySelector('.gh-portal-share-actions').children);
9696
expect(actions[0]).toHaveClass('gh-portal-share-action', 'copy');
9797
expect(actions[1]).toHaveClass('gh-portal-share-action', 'twitter');
98-
expect(actions[2]).toHaveClass('gh-portal-share-action', 'facebook');
98+
expect(actions[2]).toHaveClass('gh-portal-share-action', 'linkedin');
9999
expect(actions[3]).toHaveClass('gh-portal-share-action', 'email');
100100
expect(actions[4]).toHaveClass('gh-portal-share-more');
101101

102102
const copyButton = getByRole('button', {name: 'Copy link'});
103103
const twitterLink = getByRole('link', {name: 'X (Twitter)'});
104-
const facebookLink = getByRole('link', {name: 'Facebook'});
104+
const linkedInLink = getByRole('link', {name: 'LinkedIn'});
105105
const emailLink = getByRole('link', {name: 'Email'});
106106
const moreOptionsButton = getByRole('button', {name: 'More options'});
107107

@@ -110,15 +110,17 @@ describe('ShareModal', () => {
110110
expect(queryByRole('menu')).not.toBeInTheDocument();
111111

112112
const twitterUrl = new URL(twitterLink.getAttribute('href'));
113-
const facebookUrl = new URL(facebookLink.getAttribute('href'));
113+
const linkedInUrl = new URL(linkedInLink.getAttribute('href'));
114114
const emailUrl = new URL(emailLink.getAttribute('href'));
115115

116116
expect(twitterUrl.origin + twitterUrl.pathname).toBe('https://twitter.com/intent/tweet');
117117
expect(twitterUrl.searchParams.get('url')).toBe('https://example.com/post?ref=test');
118118
expect(twitterUrl.searchParams.get('text')).toBe('Example post title');
119119

120-
expect(facebookUrl.origin + facebookUrl.pathname).toBe('https://www.facebook.com/sharer/sharer.php');
121-
expect(facebookUrl.searchParams.get('u')).toBe('https://example.com/post?ref=test');
120+
expect(linkedInUrl.origin + linkedInUrl.pathname).toBe('https://www.linkedin.com/shareArticle');
121+
expect(linkedInUrl.searchParams.get('mini')).toBe('true');
122+
expect(linkedInUrl.searchParams.get('url')).toBe('https://example.com/post?ref=test');
123+
expect(linkedInUrl.searchParams.get('title')).toBe('Example post title');
122124

123125
expect(emailUrl.protocol).toBe('mailto:');
124126
expect(emailUrl.searchParams.get('subject')).toBe('Example post title');
@@ -134,16 +136,16 @@ describe('ShareModal', () => {
134136
expect(moreOptionsButton).toHaveAttribute('aria-expanded', 'true');
135137
expect(getByRole('menu')).toBeInTheDocument();
136138

137-
const linkedInLink = getByRole('menuitem', {name: 'LinkedIn'});
139+
const facebookLink = getByRole('menuitem', {name: 'Facebook'});
138140
const threadsLink = getByRole('menuitem', {name: 'Threads'});
139141
const blueskyLink = getByRole('menuitem', {name: 'Bluesky'});
140142

141-
const linkedInUrl = new URL(linkedInLink.getAttribute('href'));
143+
const facebookUrl = new URL(facebookLink.getAttribute('href'));
142144
const threadsUrl = new URL(threadsLink.getAttribute('href'));
143145
const blueskyUrl = new URL(blueskyLink.getAttribute('href'));
144146

145-
expect(linkedInUrl.origin + linkedInUrl.pathname).toBe('https://www.linkedin.com/sharing/share-offsite/');
146-
expect(linkedInUrl.searchParams.get('url')).toBe('https://example.com/post?ref=test');
147+
expect(facebookUrl.origin + facebookUrl.pathname).toBe('https://www.facebook.com/sharer/sharer.php');
148+
expect(facebookUrl.searchParams.get('u')).toBe('https://example.com/post?ref=test');
147149

148150
expect(threadsUrl.origin + threadsUrl.pathname).toBe('https://www.threads.net/intent/post');
149151
expect(threadsUrl.searchParams.get('text')).toBe('Example post title https://example.com/post?ref=test');
@@ -186,9 +188,7 @@ describe('ShareModal', () => {
186188

187189
const {getByRole, getByText, queryByTestId} = setup();
188190

189-
fireEvent.click(getByRole('button', {name: 'More options'}));
190-
191-
const linkedInLink = getByRole('menuitem', {name: 'LinkedIn'});
191+
const linkedInLink = getByRole('link', {name: 'LinkedIn'});
192192
const linkedInUrl = new URL(linkedInLink.getAttribute('href'));
193193

194194
expect(linkedInUrl.searchParams.get('url')).toBe(window.location.href);

0 commit comments

Comments
 (0)