Skip to content

Launch

View raw .md

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:

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:

dart
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 Behavior
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 behavior
dart
// 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:

dart
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:

dart
// Basic — 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:

dart
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:

dart
// 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():

dart
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:

dart
// 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.

esc

Search index did not load.

No match for "".

Try a class like rounded-lg or a widget like WButton.