This specification defines an API for sharing text, links and other content to an arbitrary destination of the user's choice.
The available share targets are not specified here; they are provided by the user agent. They could, for example, be apps, websites or contacts.
The ability to share content is often dependent on the underlying operating system providing a "share" capability and also on OS UI conventions. For example, some OSs present a "share sheet", while others rely on an pop-up menu. Due to these aforementioned dependencies, there is ongoing work by implementers to bring the Web Share API to all OSs. This ongoing effort is reflected as failures in the implementation report, which is generated by running tests on a limited set of OSs. However, the Working Group is optimistic that the Web Share API will become more available across all OSs over time, and is already widely available on popular OSs across a range of devices.
This example shows a basic share operation. In response to a button click, this JavaScript code shares the current page's URL.
shareButton.addEventListener("click", async () => { try { await navigator.share({ title: "Example Page", url: "" }); console.log("Data was shared successfully"); } catch (err) { console.error("Share failed:", err.message); } });
Note that a {{ShareData/url}} of `''` refers to the current page URL, just as it would in a link. Any other absolute or relative URL can also be used.
In response to this call to {{Navigator/share()}}, the user agent would display a picker or chooser dialog, allowing the user to select a target to share this title and the page URL to.
This example shows how to share a file. Note that the {{ShareData/files}} member is an array, allowing for multiple files to be shared.
shareButton.addEventListener("click", async () => { const file = new File(data, "some.png", { type: "image/png" }); try { await navigator.share({ title: "Example File", files: [file] }); } catch (err) { console.error("Share failed:", err.message); } });
Calling {{Navigator/canShare()}} method with a {{ShareData}} dictionary [=validate share data|validates=] the shared data. Unlike {{Navigator/share()}}, it can be called without [=transient activation=].
const file = new File([], "some.png", { type: "image/png" }); // Check if files are supported if (navigator.canShare({files: [file]})) { // Sharing a png file would probably be ok... } // Check if a URL is ok to share... if (navigator.canShare({ url: someURL })) { // The URL is valid and can probably be shared... }
Because of how WebIDL dictionaries work, members passed to {{Navigator/share()}} that are unknown to the user agent are ignored. This can be a problem when sharing multiple members, but the user agent doesn't support sharing one of those members. To be sure that every member being passed is supported by the user agent, you can pass them to {{Navigator/canShare()}} individually to check if they are supported.
const data = { title: "Example Page", url: "https://example.com", text: "This is a text to share", someFutureThing: "some future thing", }; const allSupported = Object.entries(data).every(([key, value]) => { return navigator.canShare({ [key]: value }); }); if (allSupported) { await navigator.share(data); }
Alternatively, you can adjust application's UI to not show UI components for unsupported members.
const data = { title: "Example Page", url: "https://example.com", text: "This is a text to share", someFutureThing: "some future thing", }; // Things that are not supported... const unsupported = Object.entries(data).filter(([key, value]) => { return !navigator.canShare({ [key]: value }); });
The [=policy-controlled feature/default allowlist=] of [=default allowlist/'self'=] makes Web Share API available by default only in first-party contexts.
Third-party can be allowed to use this API via an [^iframe^]'s [^iframe/allow^] attribute:
Alternatively, the API can be disabled in a first-party context by specifying an HTTP response header:
See the [[[permissions-policy]]] specification for more details and for how to control the permission policies on a per-origin basis.
partial interface Navigator { [SecureContext] Promise<undefined> share(optional ShareData data = {}); [SecureContext] boolean canShare(optional ShareData data = {}); };
This API adds the following internal slot to the {{Navigator}} interface.
When the {{Navigator/share()}} method is called with argument |data:ShareData|, run the listed steps listed below while taking into consideration the following security implications.
Web Share enables data to be sent from websites to a [=share target=], which can be a native applications. While this ability is not unique to Web Share, it does come with a number of potential security risks that can vary in severity (depending on the underlying platform).
The data passed to {{Navigator/share()}} might be used to exploit buffer overflow or other remote code execution vulnerabilities in the [=share target=] that receive shares. There is no general way to guard against this, but implementors will want to be aware that it is a possibility (particularly when sharing files).
[=Share targets=] that dereference a shared URL and forward that information on might inadvertently forward information that might be otherwise confidential. This can lead to unexpected information leakage if shares reference content that is only accessible by that application, the host on which it runs, or its network location.
Malicious sites might exploit share targets that leak information by providing URLs that ultimately resolve to local resources, including, but not limited to, "file:" URLs or local services that might otherwise be inaccessible. Even though this API limits shared URLS to a restricted set of [=sharable schemes=], use of redirects to other URLs or tweaks to DNS records for hosts in those URLs might be used to cause applications to acquire content.
To avoid being used in these attacks, share targets can consume the URL, retrieve the content, and process that information without sharing it. For instance, a photo editing application might retrieve an image that is "shared" with it. A share target can also share the URL without fetching any of the referenced content.
Share targets that fetch content for the purposes of offering a preview or for sharing content risk information leakage. Content that is previewed and authorized by a user might be safe to forward, however it is not always possible for a person to identify when information should be confidential, so forwarding any content presents a risk. In particular, the {{ShareData/title}} might be used by an attacker to trick a user into misinterpreting the nature of the content (see also [[[#a11y]]]).
As with any user of {{DOMException}}, implementors need to carefully consider what information is revealed in the error message when {{Navigator/share()}} is rejected. Even distinguishing between the case where no [=share targets=] are available and user cancellation could reveal information about which share targets are installed on the user's device.
When the canShare() method is called with argument {{ShareData}} |data:ShareData|, run the following steps:
A sharable scheme is any of the following [=URL=] [=URL/schemes=]:
To validate share data with |data:ShareData| and |base:URL|, run the following steps:
This causes a `{ files: [] }` dictionary to be treated as an empty dictionary. However, passing a dictionary like `{text: "text", files: []}` is fine, as `files` is just ignored.
dictionary ShareData { sequence<File> files; USVString title; USVString text; USVString url; };
The ShareData dictionary consists of several optional members:
A share target is the abstract concept of a destination that the user agent will transmit the share data to. What constitutes a share target is at the discretion of the user agent.
A share target might not be directly able to accept a {{ShareData}} (due to not having been written with this API in mind). However, it MUST have the ability to receive data that matches some or all of the concepts exposed in {{ShareData}}. To convert data to a format suitable for ingestion into the target, the user agent SHOULD map the members of {{ShareData}} onto equivalent concepts in the target. It MAY discard or combine members if necessary. The meaning of each member of the payload is at the discretion of the share target.
Each share target MAY be made conditionally available depending on the {{ShareData}} payload delivered to the {{Navigator/share()}} method.
The list of share targets can be populated from a variety of sources, depending on the user agent and host operating system. For example:
In some cases, the host operating system will provide a sharing or intent system similar to Web Share. In these cases, the user agent can simply forward the share data to the operating system and not talk directly to native applications.
This specification defines a policy-controlled permission identified by
the string "web-share"
. Its
[=policy-controlled feature/default allowlist=] is [=default
allowlist/'self'=], which means third-party contexts are not [=allowed
to use=] the API by default.
It is OPTIONAL for user agents to support [[[PERMISSIONS-POLICY]]]'s `Permissions-Policy` HTTP header.
Developers can use the means afforded by the [[[permissions-policy]]] specification to control if and when a third-party context is [=allowed to use=] this API.
When this specification is used to present information in the user interface, implementors will want to follow the OS level accessibility guidelines for the platform. Further, as sharing can have potential security implications for end-users, as outlined as part of the {{Navigator/share()}} method, the share UI needs to be presented in an accessible manner, while also taking into consideration a platform's security guidelines for user interfaces. Some key considerations are to:
Together, these elements can help users with a range of visual, motor or cognitive disabilities to better understand the nature of the content being shared by a web page.
The following normative changes were made to the specification during the Proposed Recommendation phase. Please see the commit log for a complete list of changes.
The following normative changes were made to the specification since it was published as a First Public Working Draft to Candidate Recommendation. Please see the commit log for a complete list of changes.
The editors would like to thank the following W3C groups for their invaluable feedback, which greatly improved this specification: Accessible Platform Architectures Working Group, the Internationalization Working Group, the Privacy Interest Group, and the Technical Architecture Group.
Thanks to the Web Intents team, who laid the groundwork for the web app interoperability use cases. In particular, Paul Kinlan, who did a lot of early advocacy for Web Share.