Help users share the website they are on

Letting the user share the website they are on is a common web apps pattern that you can find on many news sites, blogs, or shopping sites. Since linking is one of the web's super powers, the hope is to acquire traffic from users who see the shared link on social networking sites, or who receive it in chat messages or even plain old school with email.

Use the Web Share API

The Web Share API lets the user share data like the URL of the page they are on, along with a title and descriptive text. The navigator.share() method of the Web Share API invokes the device's sharing mechanism. It returns a promise and takes a single argument with the to-be-shared data. Possible values are:

  • url: A string representing the URL to be shared.
  • text: A string representing text to be shared.
  • title: A string representing a title to be shared. May be ignored by the browser.

Browser Support

  • Chrome: 128.
  • Edge: 93.
  • Firefox: behind a flag.
  • Safari: 12.1.

Source

Use a social networking site's share intent

Not all browsers support the Web Share API yet. A fallback is thus to integrate with your target audience's most popular social networking sites. A popular example is Twitter, whose Web Intent URL allows for a text and a URL to be shared. The method typically consists of crafting a URL and opening it in a browser.

UI considerations

It's a best practice to respect the platform's established share icon according to the UI guidelines of the operating system vendors.

    Windows icon

    Apple icon

    Android and other operating systems

Progressive enhancement

The snippet uses the Web Share API when it is supported, then falls back to the Twitter Web Intent URL.

// DOM references
const button = document.querySelector('button');
const icon = button.querySelector('.icon');
const canonical = document.querySelector('link[rel="canonical"]');

// Find out if the user is on a device made by Apple.
const isMac = navigator.platform.toLowerCase().includes('mac');

// Find out if the user is on a Windows device.
const isWin = navigator.platform.toLowerCase().includes('win');

// For Apple devices or Windows, use the platform-specific share icon.
icon.classList.add(`share${isMac? 'mac' : (isWin? 'windows' : '')}`);

button.addEventListener('click', async () => {
  // Title and text are identical, since the title may actually be ignored.
  const title = document.title;
  const text = document.title;
  // Use the canonical URL, if it exists, else, the current location.
  const url = canonical?.href || location.href;

  // Feature detection to see if the Web Share API is supported.
  if ('share' in navigator) {
    try {
      await navigator.share({
        url,
        text,
        title,
      });
      return;
    } catch (err) {
      // If the user cancels, an `AbortError` is thrown.
      if (err.name !== "AbortError") {
        console.error(err.name, err.message);
      }
    }
  }
  // Fallback to use Twitter's Web Intent URL.
  const shareURL = new URL('https://twitter.com/intent/tweet');
  const params = new URLSearchParams();
  params.append('text', text);
  params.append('url', url);
  shareURL.search = params;
  window.open(shareURL, '_blank', 'popup,noreferrer,noopener');
});

Demo

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>How to let the user share the website they are on</title>
    <link rel="stylesheet" href="style.css" />
    <!-- TODO: Devsite - Removed inline handlers -->
    <!-- <script src="script.js" defer></script> -->
  </head>
  <body>
    <h1>How to let the user share the website they are on</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin at libero
      eget ante congue molestie. Integer varius enim leo. Duis est nisi,
      ullamcorper et posuere eu, mattis sed lorem. Lorem ipsum dolor sit amet,
      consectetur adipiscing elit. In at suscipit erat, et sollicitudin lorem.
    </p>
    <img src="https://placekitten.com/400/300" width=400 height=300>
    <p>
      In euismod ornare scelerisque. Nunc imperdiet augue ac porttitor
      porttitor. Pellentesque habitant morbi tristique senectus et netus et
      malesuada fames ac turpis egestas. Curabitur eget pretium elit, et
      interdum quam.
    </p>
    <hr />
    <button type="button"><span class="icon"></span>Share</button>
  </body>
</html>

CSS


        :root {
  color-scheme: dark light;
}

html {
  box-sizing: border-box;
}

*, *:before, *:after {
  box-sizing: inherit;
}

body {
  margin: 1rem;
  font-family: system-ui, sans-serif;
}

img,
video {
  height: auto;
  max-width: 100%;
}

button {
    display: flex;
    background: #9c9c9c;
    padding: 12px;
    color:  #fff;
    border: 1px solid #9c9c9c;
    border-radius: 8px;
}

button .icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  background-size: 1em;
}

button:hover {
  background: #5089d3ff;
}

@media (prefers-color-scheme: dark) {
  button .icon {
    filter: invert();
  }
}

.share {
  background-image: url('windows.svg');
  color: #fff;
}

.sharemac {
  background-image: url('mac.svg');
  color: #fff;
}
        

JS


        // DOM references
const button = document.querySelector('button');
const icon = button.querySelector('.icon');
const canonical = document.querySelector('link[rel="canonical"]');

// Find out if the user is on a device made by Apple.
const isMac = navigator.platform.toLowerCase().includes('mac');

// Find out if the user is on a Windows device.
const isWin = navigator.platform.toLowerCase().includes('win');

// For Apple devices or Windows, use the platform-specific share icon.
icon.classList.add(`share${isMac? 'mac' : (isWin? 'windows' : '')}`);

button.addEventListener('click', async () => {
  // Title and text are identical, since the title may actually be ignored.
  const title = document.title;
  const text = document.title;
  // Use the canonical URL, if it exists, else, the current location.
  const url = canonical?.href || location.href;

  // Feature detection to see if the Web Share API is supported.
  if ('share' in navigator) {
    try {
      await navigator.share({
        url,
        text,
        title,
      });
      return;
    } catch (err) {
      // If the user cancels, an `AbortError` is thrown.
      if (err.name !== "AbortError") {
        console.error(err.name, err.message);
      }
    }
  }
  // Fallback to use Twitter's Web Intent URL.
  const shareURL = new URL('https://twitter.com/intent/tweet');
  const params = new URLSearchParams();
  params.append('text', text);
  params.append('url', url);
  shareURL.search = params;
  window.open(shareURL, '_blank', 'popup,noreferrer,noopener');
});