Technical
Using the Web Share API in Android TWAs
October 1, 2026 · 7 min read
Introduction to Native Sharing in TWAs
A seamless user experience is the primary goal of any mobile application wrapper. When converting a Progressive Web App (PWA) into an Android application using a Trusted Web Activity (TWA), developers often worry about losing native integration. One crucial feature is the system share sheet, which allows users to easily send content to contacts, social platforms, and utilities installed on their device.
While the Web Share Target API is used to register your application as a destination for shared content, the Web Share API does the opposite. It allows your web application to trigger the native Android share dialogue. In a TWA, this integration requires zero native Kotlin or Java code. The system automatically maps your standard JavaScript calls to native Android intents, creating a completely integrated platform experience.
How the Web Share API Maps to Android Intents
When your TWA processes a Web Share request, the underlying Android Custom Tab (typically powered by Google Chrome) intercepts the call. The browser engine constructs a native Android intent of type ACTION_SEND. This native intent commands the Android system to display its system-level sharing menu.
This menu displays applications that are registered to accept the specific MIME types or text formats you are sending. Because this is handled entirely by the operating system, it inherits the user's preferences, pinned contacts, and system themes. This preserves native device behaviour, ensuring your app feels like a first-class citizen on the device.
Security and Sandboxing in Chrome Custom Tabs
The security model of the Web Share API in a TWA matches that of modern browsers. Android enforces a security sandbox between the TWA and other applications. Because the share sheet relies on standard intents, you do not need to request dangerous system-level permissions in your Android manifest to share standard content. The browser securely passes the payload to the chosen target app without exposing your underlying TWA storage or user data.
Implementing Text and URL Sharing
The standard implementation of the Web Share API relies on the navigator.share method. Before calling this API, you must always perform feature detection, as some legacy browsers or older Android configurations might not support the feature.
Crucially, the Web Share API can only be triggered by an explicit user interaction. This means the code must run within a click, touch, or keydown event handler. Browsers enforce this security measure to prevent malicious sites from hijacking the user interface with unexpected pop-ups. Here is the implementation pattern for text and URL sharing:
function shareApplicationDetails() {
if (!navigator.share) {
console.log("Web Share API is not supported in this browser environment.");
return;
}
navigator.share({
title: "PWAtoApp Converter",
text: "Convert your progressive web app into a Google Play ready app easily.",
url: "https://pwatoapp.com"
})
.then(() => {
console.log("Content shared successfully");
})
.catch((error) => {
if (error.name === "AbortError") {
console.log("User cancelled the share action.");
} else {
console.error("An error occurred during sharing:", error);
}
});
}
If the user selects a contact in a messaging app, the text and URL are sent straight to that conversation. If they select a system note utility, the text is automatically pasted into a new file.
Sharing Files and Assets in a TWA
Modern applications frequently require sharing assets like PNG images, PDF reports, or CSV spreadsheets. The Web Share API supports file sharing, but requires a pre-flight validation check using navigator.canShare.
To share files, they must be formatted as JavaScript File objects. If you are generating a file dynamically, you can construct the file object using a blob. Alternatively, you can fetch an image from your server, convert it to a blob, and wrap it in a file object before calling the API. Below is an implementation showing how to fetch and share an image asset from your web application:
async function shareImageFile(imageUrl, filename) {
if (!navigator.share) {
return;
}
try {
const response = await fetch(imageUrl);
const blob = await response.blob();
const file = new File([blob], filename, { type: blob.type });
const shareData = {
files: [file],
title: "Shared Image",
text: "Check out this image from our application."
};
if (navigator.canShare && navigator.canShare(shareData)) {
await navigator.share(shareData);
} else {
console.log("File sharing is not supported on this platform.");
}
} catch (error) {
console.error("Failed to share file:", error);
}
}
Handling Large Files and Performance Overhead
When sharing files, keep in mind that Chrome must temporarily hold the file data in memory to pass it to the target application. Sharing excessively large files (above 10 megabytes) can cause performance drops or lead to memory crashes on lower-end Android devices. Always check file sizes before passing them to the sharing mechanism.
Managing User Disruption and Fallback Mechanisms
In a TWA, the user can easily dismiss the native share sheet by tapping the system back button or clicking the background. Your code must handle these cancellations without breaking the application flow. When a user cancels, the promise rejects with an AbortError. This should be treated as a normal user action, not a critical runtime failure.
For environments where the Web Share API is missing, you should provide a fallback mechanism. The most common solution is to copy the target URL to the clipboard using the Clipboard API and present a temporary notification alert to the user, or show a custom web-based modal listing direct share links to popular social platforms.
Web Share API Capabilities Matrix
Understanding which data types are supported helps you design robust sharing flows inside your TWA. The following table highlights standard behaviours across platforms:
| Data Type | Support Level | Requirements |
|---|---|---|
| Text and Title | Universal | HTTPS environment, triggered by direct user gesture. |
| URLs | Universal | Must be a valid, fully qualified absolute URL path. |
| Images (PNG, JPEG, GIF) | High | MIME type must be validated inside navigator.canShare(). |
| PDF Documents | Medium | Requires Chrome engine to pass raw binary files correctly. |
Ready to ship your Android app?
Paste your PWA URL, get a signed APK and a Google Play ready AAB in minutes.
Build my app