Launch
The Launch facade provides a context-free static API for opening URLs, composing emails, initiating phone calls, and sending SMS messages, returning false on failure rather than throwing.
On this page
Introduction#
The Launch facade provides a context-free, static API for opening URLs, triggering email clients, initiating phone calls, and composing SMS messages. It wraps the url_launcher package and adds consistent error handling: all methods return false on failure and log errors via Log. They never throw.
Configuration#
Registering LaunchServiceProvider#
LaunchServiceProvider is not auto-registered. Add it explicitly to your providers in config/app.dart:
'providers': [
(app) => LaunchServiceProvider(app),
// ... other providers
],
This registers a LaunchService singleton in the Magic IoC container under the key 'launch'. The Launch facade resolves this singleton on every call.
URL Launching#
Open a URL using the Launch.url() method:
final opened = await Launch.url('https://flutter.dev');
LaunchMode Options#
The optional mode parameter controls how the URL is opened. It maps directly to url_launcher's LaunchMode enum:
| Mode | Behaviour |
|---|---|
LaunchMode.externalApplication |
Opens in the default external app (browser, app, etc.), default |
LaunchMode.inAppWebView |
Opens inside a WebView within the app |
LaunchMode.inAppBrowserView |
Opens in an in-app browser with browser chrome |
LaunchMode.externalNonBrowserApplication |
Opens in an external non-browser app |
LaunchMode.platformDefault |
Uses the platform's default behaviour |
// Open in the default external browser or app
await Launch.url('https://flutter.dev');
// Open inside an in-app WebView
await Launch.url(
'https://flutter.dev',
mode: LaunchMode.inAppWebView,
);
// Open in an in-app browser with navigation controls
await Launch.url(
'https://flutter.dev',
mode: LaunchMode.inAppBrowserView,
);
The Web Window#
On the web, webOnlyWindowName names the browsing context the URL opens in (_self, _blank, or a named window); every other platform ignores it. Leave it unset for a new tab.
Pass _self for a download whose URL you fetch first. Safari blocks a new window that is no longer opened inside the tap, and the web launcher still answers true, so nothing happens and nothing says so. Navigating the current tab is not a popup, and a response served with Content-Disposition: attachment downloads without leaving the page:
final String link = await controller.downloadLink(fileId);
await Launch.url(link, webOnlyWindowName: '_self');
Return Value#
Launch.url() returns Future<bool>. It returns false immediately for empty strings and false on any URI parse error or launch failure (errors are logged via Log.error).
Email#
Open the device's email client pre-addressed to a recipient:
// Address only
await Launch.email('[email protected]');
// With subject and body
await Launch.email(
'[email protected]',
subject: 'Bug Report',
body: 'I found an issue with the login screen.',
);
Special characters in subject and body are automatically URI-encoded. The method returns false immediately for an empty address.
Phone#
Open the device's phone dialer pre-filled with a number:
await Launch.phone('+1234567890');
The method returns false immediately for an empty number string.
SMS#
Open the device's SMS app addressed to a number, with an optional pre-filled message body:
// Number only
await Launch.sms('+1234567890');
// With pre-filled body
await Launch.sms('+1234567890', body: 'On my way!');
Special characters in body are automatically URI-encoded. The method returns false immediately for an empty number string.
Checking Availability#
Before launching, you can check whether the device can handle a given URL scheme using Launch.canLaunch():
if (await Launch.canLaunch('tel:+1234567890')) {
await Launch.phone('+1234567890');
} else {
// Phone calls not supported on this device
}
This works for any URL scheme: https://, mailto:, tel:, sms:, or custom deep-link schemes:
// Check before opening a deep link
if (await Launch.canLaunch('myapp://profile/42')) {
await Launch.url('myapp://profile/42');
}
Launch.canLaunch() returns false for empty strings and malformed URLs.