Telerik blogs

Learn how the Web Share API works to enhance the experience of users sharing links, text and other data. See some common use cases and how to implement it.

The Web Share API allows users to share text, links, files and other content to an arbitrary destination based on the user’s preferences. It facilitates a way to trigger the native share interface of a device when sharing data directly from an application to the device-specific share target. The possible share targets vary depending on the device, but they typically include the system clipboard, contacts, email contacts, Bluetooth, etc.

The API eliminates the need to depend on third-party means to enable the share feature. It utilizes the sharing mechanisms of the underlying operating system of the host device.

In this article, we’ll look at the Web Share API and how to use its helper methods to share and validate data. We’ll also look at how the Web Share API behaves when used in different contexts, such as iframes.

Prerequisites

This guide assumes you at least have a basic understanding of HTML and JavaScript.

An Overview of the API

Native applications can leverage the device’s native sharing mechanism, allowing users to exchange data easily. On the other hand, web applications were limited in their ability to share materials because they had to create their own sharing mechanism from scratch. However, the Web Share API offers a simple mechanism to access native sharing functionality from web applications.

With the Web Share API, we can now create applications that allow users to share data as they would from a native application, providing a more seamless user experience.

The Web Share API outsources the share logic to the user agent and provides a single call-up point for sharing data. This is a better and more efficient approach than creating a distinct button on a webpage for each share target in an application.

Custom sharing is an important feature of the Web Share API. It allows us to select the title, text and URL of the content to be shared, giving more control over the content than simply sharing a webpage’s URL. The API also provides users with a familiar and smooth sharing experience with native and user-friendly share dialogs.

The Web Share API is currently supported by some browsers and is cross-platform compatible. See a list of browsers supporting the Web Share API.

Browser support of the Web Share API

Highlighted below are some of the limitations of the Web Share API:

  • The API is only accessible through HTTPS (in secured contexts).
  • It requires transient activation. It can be triggered only in response to some UI event (e.g., click event).

The Web Share API exposes a share() and canShare() method for sharing and validating data to be shared. Let’s take a look at these functions.

The share() Method

This method invokes the native sharing mechanism of the underlying operating system and passes the specified data, which can be text, URLs or files. This method must be called when a button is clicked or a user action occurs.

The syntax of the share() method:

navigator.share(data);

The share functionality is triggered by calling the share() method on the Navigator object and passing an object containing the data to be shared as an argument. Possible key-values pairs of the data object may include:

  • text: A string that represents a text to be shared.
  • url: A string representing a URL to be shared. This can be an absolute or relative URL and, when set to an empty string, refers to the current page URL.
  • title: A string representing a title to be shared.
  • files: An array of File objects representing files to be shared. The type of files the method accepts includes audio, image, text, applications and video files.

It is worth noting that properties unknown to the user agent are ignored. Only properties understood by the user agent are used to evaluate share data. Although all the properties are optional, at least one known data property must be provided.

When called, the share() method returns a promise that resolves with undefined if the data passed was successfully sent to a share target or otherwise rejected with one of the exceptions highlighted below:

  • TypeError: This occurs when the data specified to be shared cannot be validated. It may result from specifying poorly formatted data or defining data with unknown values.
  • AbortError: This is returned if the user cancels the share operation or there are no share targets available.
  • DataError: This is returned if there is a problem when starting the share target or transmitting the data.
  • NotAllowedError: This is returned if a web-share permissions policy has been applied to prevent this functionality from being used, a file share is prohibited for security reasons, or the window does not have transient activation.

The user agent will display a picker dialog in response to a successful call to the share() method, allowing the user to select a target to share the given data.

Displayed below is a basic code snippet showing how to use the share() method:

buttonElement.addEventListener("click", async () => {
  try {
    await navigator.share({
      title: "Test",
      text: "This is a test share",
      url: "https://www.google.com/",
    });
    console.log("Data was shared successfully");
  } catch (err) {
    console.error("error:", err.message);
  }
});

This is how you would use it to share files:

buttonElement.addEventListener("click", async () => {
  try {
    await navigator.share({
      title: "File share test",
      files: [
        /* one or more files */
      ],
    });
    console.log("File was shared successfully");
  } catch (err) {
    console.error("error", err.message);
  }
});

In the code snippets shown above, we defined a click event on the buttonElement, which makes an asynchronous call to the share() method. Next, we passed the data and file to be shared, respectively.

A success message is logged to the console if the share is successful; otherwise, an error message is logged.

The canShare() Method

The canShare() method with a data object passed as its argument can be used to validate the data to be shared before calling the share() method on it. Unlike the share() method, it can be invoked without being triggered by a UI event.

Before using the share() method to trigger the native sharing feature, it is recommended that the data to be shared be validated using the canShare() method. The method returns a boolean indicating if the provided data is shareable.

The code below shows how you can use the canShare() method:

if (navigator.canShare(data)) {
  //we can now call the share() method
} else {
  // fallback if the data cannot be shared
}

With this, we can provide a fallback mechanism when there is a problem with the data to be shared.

When called without an argument, the canShare() method checks if the current device and browser support the Web Share API.

Shown below is a sample code snippet:

buttonElement.addEventListener("click", async () => {
  if (!navigator.canShare()) {
    console.log("You can't share!");
    return;
  }
  if (navigator.canShare(/* sample data object */)) {
    try {
      await navigator.share({
        /* sample data object */
      });
      console.log("Shared successfully");
    } catch (error) {
      console.error("error", err.message);
    }
  } else {
    console.log("The data is unsharable, check data");
  }
});

In the code above, rather than just sharing the specified data with a click event, we added mechanisms to check if the browser supports the Web Share API and validates the transmitted data.

Share Targets

A share target is a destination to which the user agent will send the share data. The user agent determines what constitutes a share target.

If a user wants to share a web page on WhatsApp, the share target is the WhatsApp application. If the user wishes to send the content by email, the share target is an email client application.

Based on the user agent and host operating system, the list of share targets might be generated from various sources. These include contacts, built-in services (Clipboard), websites, native applications, etc.

Using the Share API in Third-Party Contexts

The default configurations of the Web Share API make it available only in first-party contexts. However, third parties can be allowed to use this API using the iframe’s allow attribute, as shown below:

<iframe src="https://sample-third-party.com" allow="web-share"></iframe>

Here, we set the iframe’s allow attribute to web-share. Failing to provide this attribute will result in a NotAllowedError.

Privacy Policies When Using the Web Share API

When using the Web Share API, it is important to emphasize user privacy. This includes gaining user consent, notifying users about potential privacy risks, and taking steps to protect the data provided over the API. It is necessary to be transparent about data handling policies and ensure user data is handled securely and responsibly. See the permissions and privacy policies defined by W3C here.

Demo

We have looked at the Web Share API and its methods. Now, let’s try it out.

In a directory of your choice, create an index.html file and add the following to it:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <div>
        <button style="margin: 2rem 3rem; padding: 1rem 3rem">Share</button>
      </div>
      <p class="status" style="margin: 0 3rem"></p>
    </body>
    <script type="text/javascript" src="./script.js""></script>
    </html>

In the code above, we added a <button> that will be used to trigger the share feature and a <p> tag to hold the share status.

Next, create a script.js file and add the following to it:

const buttonEl = document.querySelector("button");
const statusEl = document.querySelector(".status");
buttonEl.addEventListener("click", async () => {
  try {
    await navigator.share({
      title: "Test",
      text: "This is a test share",
      url: "https://www.google.com/",
    });
    statusEl.textContent = "Data was shared successfully";
  } catch (err) {
    statusEl.textContent = `${err.message}`;
  }
});

Here, we added a click event to the button element. It triggers the share feature when clicked.

Open your index.html file in a browser to preview the share functionality.

A preview of share functionality

To share files, update your index.html file by adding an input element as shown below:

    <body>
     <div style="margin: 2rem 3rem;"">
        <label for="files">Select images:</label>
        <input id="files" type="file" accept="image/*" multiple />
      </div>
      <div>
        <button style="margin: 2rem 3rem; padding: 1rem 3rem">Share</button>
      </div>
      <p class="status" style="margin: 0 3rem"></p>
    </body>

Next, open your script.js file and replace the code in it with the following:

const buttonEl = document.querySelector("button");
const statusEl = document.querySelector(".status");
const filesInput = document.getElementById("files");
buttonEl.addEventListener("click", async () => {
  const files = filesInput.files;
  //ensures at least an image file is selected
  if (files.length === 0) {
    statusEl.textContent = "No files selected.";
    return;
  }
  //checks if the Web Share API is supported
  if (!navigator.canShare) {
    statusEl.textContent = `Your browser doesn't support the Web Share API.`;
    return;
  }
  //validates the files
  if (navigator.canShare({ files })) {
    try {
      await navigator.share({
        files,
        title: "Image Files",
        text: "some sample image files",
      });
      statusEl.textContent = "Shared successfully!";
    } catch (error) {
      statusEl.textContent = `${error.message}`;
    }
  } else {
    statusEl.textContent = `Your system doesn't support sharing these files.`;
  }
});

In the code above, we added an input element that accepts multiple image files. Next, we added a click event on the button element, which triggers the share functionality.

We also used the canShare() method to check if the Web Share API is supported and the files are sharable.

Share functionality with validation

Conclusion

The Web Share API provides a uniform mechanism for triggering data sharing, which enhances the user experience by making it easy to share links, text and other data across devices and platforms. This article explores some common use cases for this API and provides a foundation for using it in our future apps.


Ifeoma-Imoh
About the Author

Ifeoma Imoh

Ifeoma Imoh is a software developer and technical writer who is in love with all things JavaScript. Find her on Twitter or YouTube.

Related Posts

Comments

Comments are disabled in preview mode.