All articles

Technical

Handling tel, mailto, and Custom Schemes in Android TWAs

September 13, 2026 · 7 min read

When you convert a Progressive Web App into an Android application using a Trusted Web Activity, your web application runs inside a secure, full-screen instance of the user system browser. While this provides excellent rendering performance and high feature parity with modern browsers, it introduces unique challenges when handling non-HTTP protocols. On a standard desktop browser, clicking a tel link might trigger a prompt or do nothing. Within an installed Android application, users expect clicking a telephone link, email link, or geographic coordinate link to seamlessly open their preferred native application.

Understanding Custom Protocols in a Web-to-App Environment

In a standard web browser, navigation is primarily limited to HTTP and HTTPS protocols. However, mobile devices rely on custom URI schemes to pass data between applications. When a user taps a link with a scheme like tel, mailto, or sms, the underlying operating system uses an intent filter to resolve which native application should handle the action. Inside a Trusted Web Activity, these actions must be correctly handed off from the browser context to the native Android OS. If your TWA is not configured correctly, or if your service worker attempts to intercept these external protocols, the application can display a navigation error, throw an unresolved intent exception, or simply fail silently.

Default TWA Behaviour for Common Protocols

Trusted Web Activities inherit the protocol handling capabilities of the underlying browser engine, which is typically Google Chrome. Chrome has built-in mechanisms to forward standard mobile schemes to the Android operating system. However, the exact behaviour depends on how the link is opened and whether your TWA configuration restricts outbound navigations. The following table highlights the standard web protocol schemes, their purpose, and how the Android operating system typically resolves them when triggered inside a properly configured TWA wrapper.

SchemePurposeTarget Native Android Application
tel:Initiate voice callsDefault Android Dialer or Phone application
mailto:Compose electronic mailDefault Email Client, such as Gmail or Outlook
sms:Send text messagesDefault SMS Messaging application
geo:Display map locationsGoogle Maps or default navigation application
intent:Launch specific Android appsTarget application registered to the custom intent

Preventing the Unknown URL Scheme Error

The most common bug developers encounter when packaging their PWA for Google Play is the net::ERR_UNKNOWN_URL_SCHEME error screen. This error occurs when the web application attempts to navigate to a protocol that the browser engine cannot resolve directly, or when the Android wrapper app intercepts the navigation but lacks the permission or instructions to delegate it to the operating system. To prevent this, you must ensure that your service worker does not attempt to fetch or cache requests containing non-HTTP schemes. Your service worker fetch event listener should always check the protocol of the incoming request before attempting to serve a cached response or fetch it from the network.

if (!event.request.url.startsWith("http")) { return; }

By adding this simple guard clause to the top of your service worker fetch handler, you prevent your service worker from trying to hijack tel, mailto, or app-specific schemes. This allows the request to bubble up directly to the browser custom tab instance, which then correctly prompts the Android OS to open the appropriate handler application.

Handling Native Outbound Intents via Android Manifest

For custom proprietary schemes, such as launching a third-party application like WhatsApp or a banking portal from within your TWA, you must configure intent filters inside your Android wrapper manifest file. If your application attempts to open an external app using a custom URI scheme, the Android operating system requires that your wrapper application has permission to query those schemes. This is especially true on Android 11 and later, which introduced strict package visibility requirements. You must declare the custom schemes your application intends to interact with within the queries element of your AndroidManifest.xml file.

<queries>

<intent>

<action android:name="android.intent.action.VIEW" />

<data android:scheme="tel" />

</intent>

</queries>

Declaring these schemes ensures that the operating system permits your TWA to check if there is an eligible native app installed to handle the request, avoiding silent failures when users attempt to contact support or navigate to coordinates from your application interface.

Designing Safe UI Fallbacks in Your Web App

Even with correct TWA configuration, some device configurations might not have an application capable of handling specific schemes. For example, a tablet device without cellular capabilities may not have a dialer application registered to handle tel links. To build a robust user experience, you should perform feature detection or implement graceful fallbacks within your web application frontend. You can use native web APIs or standard exception handling if you invoke external actions via JavaScript.

When using standard HTML links, consider using target blank attributes for custom schemes, which forces the browser to handle the navigation in a new context, lowering the risk of interrupting the main application state if the target application is missing. Additionally, ensure that your user interface design clearly distinguishes external links from native app interactions, giving users clear visual cues that they are about to transition away from your PWA to a native system tool.

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