In this tutorial, we discuss:
Most popular social media platforms provide simple buttons you can add to any web page.
Facebook “like”, Twitter tweets/retweets/likes, LinkedIn share, and more. The buttons allow users to share and discuss your content … in theory.
The reality is somewhat less beneficial.
Social sharing buttons are rarely used. It will depend on your site, but most will be lucky to achieve a 1% click-rate. The GOV.UK website published their sharing statistics from 2014 shortly after the site went live:
Moovweb reported a similar click rate of 0.2%. Visitors were twelve times more likely to click an advertisement!
Every social media site has a different button that must be added to pages on your website.
The submission processes can also be confusing for users. Forms are inconsistent, terminology can vary, and the user interfaces can be awkward – especially on mobile devices.
Your Facebook, Twitter, and LinkedIn buttons are no good to someone who wants to share on Pinterest! Adding every social media option is impractical and even a third-party service such as AddThis may not cater to popular systems across an international audience. Some services, such as Instagram, do not provide sharing facilities.
Most sharing buttons can be added to your site with a few lines of code. Unfortunately, that innocuous-looking HTML has a hidden cost. Facebook’s share button alone downloads 786Kb of code (216Kb gzipped). Twitter adds a further 151Kb (52Kb) and LinkedIn 182Kb (55Kb).
You can assess the total size of sharing buttons on your site by opening the Network tab in your browser DevTools. Check Disable cache, enter a specific domain such as “facebook” in the filter, then refresh the page:
The status bar at the bottom shows the number of requests, the total (compressed) data downloaded, the uncompressed file sizes, and load timings. The total of all third-party requests can be examined by entering “-domain:*.yourdomain.com” in the filter box.
Adding a few social media buttons will add significant bulk to your page weight. Processing a megabyte or two of JavaScript also has a detrimental effect on performance – especially on mobile devices.
Facebook’s JavaScript code is not sitting idle. Regardless of whether they click the button, all your visitors are being monitored across your site and other sites so their activities can be monetized. While this may not concern you, the social media sites collect user data for their benefit – not yours.
Does adding a “like” button make you liable for the use – or misuse – of personal data by a social network?
The European Court of Justice recently ruled that website owners can be held liable for data collection when using share buttons. A site is voluntarily sharing visitor information with a social network so it is considered a joint data controller.
Can you be certain those share buttons are legally-compliant in every territory where you operate? Are you sure the social media platform is acting responsibly?
Adding a third-party <script>
tag runs JavaScript with the same site-wide rights and permissions as your own code. That script can do anything – your security is only as good as the weakest provider.
British Airways was fined $232 million USD in 2018 when 500,000 customers had their names, email addresses, and full credit card information stolen during website transactions. The attack is likely to have originated from a third-party script which was modified possibly without the knowledge or permission of its supplier.
Social media companies will endeavor to prevent issues but no one is immune to security compromises.
Social media platforms can only survive if they are used. Clicking a “share” button transports your visitor to that system where they will be encouraged to stay and be distracted from interacting with your brand or service.
Despite the risks and low usage, sharing buttons can increase exposure and offer some SEO benefits. Your next customer could learn about your service from conversations on Facebook, Twitter, LinkedIn, etc.
The problems with page weight, performance, privacy, and security can be significantly reduced by using URL-based share APIs. These do not require third-party JavaScript and will not track users unless they choose to engage with the buttons.
Any web page can be shared with Facebook by loading the URL:
https://www.facebook.com/sharer/sharer.php?u=${url}
or Twitter:
https://twitter.com/intent/tweet?url=${url}&text=${title}
or LinkedIn:
https://www.linkedin.com/shareArticle?mini=true&url=${url}&title=${title}
where ${url} is the page URL and ${title} is the title (typically the content of the HTML <title>
tag).
Where available, visitors can also use a browser’s share facility to post URLs to other applications such as email, messaging, Pocket, WhatsApp, etc. However, that option is rarely obvious to users – until now…
Following a few false starts, the Web Share API finally landed in Chrome 76 on Android, Safari 12.3 on iOS, and Safari 12.1 on Mac OS. When used, the browser hands information to the sharing facility on the host operating system. The OS knows which apps support sharing and passes data accordingly.
The advantages:
The sharing UI can be launched in reaction to a user click. The following JavaScript checks whether the Web Share API is supported then adds a button click handler which passes a ShareData object to navigator.share
:
// is Web Share API supported? if ( navigator.share ) { // share button click handler document.getElementById('share').addEventListener('click', () => { // share page information navigator.share({ url: 'https://example.com/', title: 'My example page', text: 'An example page implementing the Web Share API.' }); }); }
The ShareData object contains:
<title>
string)navigator.share
returns a Promise so .then()
and .catch()
blocks can be used if you need to perform other actions or react to failures.
The Web Share API has fairly limited support, especially on desktop browsers. For this reason, the following code provides a progressively-enhanced solution that implements a share button but also defines Twitter, Facebook, LinkedIn, and email options using the lightweight and secure URL-based APIs.
The full demonstration can be viewed on Codepen.io:
See the Pen
Simpler Sharing by Craig Buckler (@craigbuckler)
on CodePen.
There is no standard share icon across desktop or mobile platforms, but the three-node graphic is recognizable and the text label should make it obvious. When clicked, it displays the standard OS share UI such as the Android example shown above.
The Twitter, Facebook, and LinkedIn buttons open the share URLs in a small pop-up window or another tab on mobile devices:
Pop-ups are awful for user experience, but this is how the social buttons normally operate and it allows the user to return to the originating page.
Finally, the email button is a mailto: link which launches the default mail app.
Any number of unordered lists with a class of “share” can be added anywhere within the HTML.
The first item shown below is the share icon. This is assigned a class of “webshare” and the link href targets “#webshare” so it can be identified.
All other list items define sharing URLs with ${url}, ${title}, and ${text} placeholders so the same code can be used on any page.
<ul class="share"> <li class="webshare"> <a href="#webshare">share</a> </li> <li> <a href="https://twitter.com/intent/tweet?url=${url}&text=${title}">Twitter</a> </li> <li> <a href="https://www.facebook.com/sharer/sharer.php?u=${url}">Facebook</a> </li> <li> <a href="https://www.linkedin.com/shareArticle?mini=true&url=${url}&title=${title}">LinkedIn</a> </li> <li> <a href="mailto:?subject=${title}&body=${url}">email</a> </li> </ul>
(SVG icon code is not shown to aid readability.)
The sharing icons are hidden by default:
.share, .webshare { display: none; }
The JavaScript (see below) appends a .social class to the HTML head when it runs. An additional .webshareapi class is added when the Web Share API is available. The CSS will, therefore, display the list and share button only when they are supported:
/* URL sharing is enabled */ .social .share { display: flex; flex-wrap: wrap; } /* Web Share API is supported */ .webshareapi .webshare { display: block; }
Further properties define colors, styling, hover effects, etc.
/* basic share styling */ .share, .share li { list-style-type: none; padding: 0; margin: 0; } .share a { display: block; text-decoration: none; color: #fff; background-color: #557; border-radius: 1.5em; } .share a:hover, .share a:focus { background-color: #779; }
The JavaScript functionality is launched as soon as the DOMContentLoaded event triggers when the DOM is ready. The function extracts the following information from the page to create a pageInfo object:
<head>
or the page URL otherwise<title>
defined in the HTML <head>
The <html>
element has a .webshareapi class applied when navigator.share is available and another .social class applied to indicate the script is running. This triggers the CSS to display the links:
// web sharing detection document.addEventListener('DOMContentLoaded', () => { 'use strict'; // get page information const html = document.documentElement, canonical = document.querySelector('link[rel=canonical]'), desc = document.getElementsByName('description'), pageInfo = { url: canonical ? canonical.href : location.href, title: document.title || '', text: desc.length ? desc[0].content : '' }; // Web Share API support? if (navigator.share) html.classList.add('webshareapi'); // social sharing enabled html.classList.add('social'); //... });
A handler event is defined which listens for click events on the whole document. When triggered, it checks if a share button has been clicked within a .share list and cancels the default action:
// click event document.body.addEventListener('click', (e) => { // on share button? let t = e.target.closest('A'); if (!t || !t.closest('.share')) return; // cancel link e.preventDefault(); // ... });
The code then checks whether the share link has been clicked and passes the pageInfo object to the Web Share API before returning:
// Web Share API if (t.hash === '#webshare') { navigator.share(pageInfo); return; }
If any other link has been used, its href address is extracted and the placeholders are replaced with pageInfo information using the urlParse()
function:
// social media link let popup, newUrl = urlParse(t.href, pageInfo);
The urlParse() function (at the end of the code) uses regular expressions to replace and encode strings:
// URL template parser function urlParse(str, token) { for (let t in token) { str = str.replace( new RegExp('\\$\\{' + t + '\\}', 'g'), encodeURIComponent(token[t]) ); } return str; }
Finally, any http link handler is opened in a centered pop-up window measuring 600x600px or fitting within the available space on smaller screens:
// open popup if (t.protocol.startsWith('http')) { let sw = screen.availWidth || 1024, sh = screen.availHeight || 700, pw = Math.min(600, (sw - 40)), ph = Math.min(600, (sh - 40)), px = Math.floor((sw - pw) / 2), py = Math.floor((sh - ph) / 2); popup = window.open( newUrl, 'social', `width=${pw},height=${ph},left=${px},top=${py},\ location=0,menubar=0,toolbar=0,personalbar=0,\ status=0,scrollbars=1,resizable=1` ); }
Focus is set to the pop-up but, if this fails to open or a non-HTTP handler is required (such as mailto: links), the window location is set to the URL:
if (popup) popup.focus(); else location.href = newUrl;
The full demonstration can be viewed at Codepen.io.
The JavaScript above minifies to less than 1Kb of code and does not require a framework (it should be compatible with any). It permits sharing buttons to be added to your website without the performance, privacy, or security implications of those provided by social media companies.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowCompare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.