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.
Status of This Document
This section describes the status of this
document at the time of its publication. A list of current W3C
publications and the latest revision of this technical report can be found
in the W3C technical reports index at
https://www.w3.org/TR/.
This is a work in progress. Wide review and feedback welcome.
Publication as a Working Draft does not
imply endorsement by W3C and its Members.
This is a draft document and may be updated, replaced or obsoleted by other
documents at any time. It is inappropriate to cite this document as other
than work in progress.
This document was produced by a group
operating under the
W3C Patent
Policy.
W3C maintains a
public list of any patent disclosures
made in connection with the deliverables of
the group; that page also includes
instructions for disclosing a patent. An individual who has actual
knowledge of a patent which the individual believes contains
Essential Claim(s)
must disclose the information in accordance with
section 6 of the W3C Patent Policy.
Note that a 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 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.
1.2
Sharing a file
This example shows how to share a file. Note that the
files member is an array, allowing for multiple files to
be shared.
const file = new File([], "some.png", { type: "image/png" });
// Check if files are supportedif (navigates.canShare({files: [file]})) {
// Sharing a png file would probably be ok...
}
// Check if a URL is ok to share...if (navigates.canShare({ url: someURL })) {
// The URL is valid and can probably be shared...
}
1.4
Checking if members are supported
Because of how WebIDL dictionaries work, members passed to
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 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",
};
// Things that are not supported...const unsupported = Object.entries(data).filter(([key, value]) => {
return !navigator.canShare({ [key]: value });
});
1.5
Enabling the API in third-party contexts
The default allowlist of '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
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.
The this.[[sharePromise]] is a promise that
represents a user's current intent to share some data with a
share target. It is initialized to null.
2.1.2
share() method
When the share() method is called with argument
data, 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 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 title might be
used by an attacker to trick a user into misinterpreting the nature
of the content.
As with any user of DOMException, implementors need to
carefully consider what information is revealed in the error
message when 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.
Present the user with a choice of one more share
targets and the ability abort the operation. This UI
surface serves as a security confirmation, ensuring that
websites cannot silently send data to native applications. The
user agent SHOULD show intermediary UI through which the user
can verify the shared content (if the OS-level UI does not
provide this functionality).
If titleTextOrUrl is false and data's
files member is empty, return false.
Note
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.
If the implementation does not support file sharing, return
false.
If the user agent believes sharing any of the files in
files would result in a potentially hostile share (i.e., the
user agent determines a file is malicious in some way, because
of its contents, size, or other characteristic), return false.
The ShareData dictionary consists of several optional
members:
files member
Files to be shared.
text member
Arbitrary text that forms the body of the message being shared.
title member
The title of the document being shared. May be ignored by the
target.
url member
A URL string referring to a resource being shared.
Note
3.
Share targets
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.
Note
Mapping the ShareData to the share target's (or operating system's)
native format can be tricky as some platforms will not have an
equivalent set of members. For example, if the target has a "text"
member but not a "URL" member (as is the case on Android), one solution
is to concatenate both the text and url
members of ShareData and pass the result in the "text" member of
the target.
Each share target MAY be made conditionally available depending on the
ShareData payload delivered to the share() method.
3.1
Examples of share targets
This section is non-normative.
The list of share targets can be populated from a variety of sources,
depending on the user agent and host operating system. For example:
Built-in service (e.g., "copy to clipboard").
Native applications written for the host operating system.
Contacts (e.g., the user agent directly shares to a person from
the user's address book, using a specific app).
Websites (e.g., the user agent fills in a template URL with the
members of the ShareData, then navigates to that URL in a new
browsing context).
Note
There is an attempt to standardize the registration of websites to
receive share data for that final use case; see Web Share Target.
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.
4.
Permissions Policy integration
Issue 1: Feature at risk
This specification defines a policy-controlled permission identified by
the string "web-share". Its
default allowlist is 'self'.
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.
6.
Privacy considerations
By design, the API cannot be used by a website to learn which
share targets are available, or which share target the user chose
from share(). This is to prevent leaking information that
could be used for fingerprinting, as well as leaking details about the
user's device or user's preferred share targets.
Use of share() from a private browsing mode
might leak private data to a third-party application that does not
respect the user's privacy setting. User agents could present
additional warnings or MAY disable the feature entirely when in a
private browsing mode, but this is not mandated as the chooser UI could
be considered sufficient warning.
7. Conformance
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, and SHOULD in this document
are to be interpreted as described in
BCP 14
[RFC2119] [RFC8174]
when, and only when, they appear in all capitals, as shown here.
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.