launchify 1.0.8
launchify: ^1.0.8 copied to clipboard
Customizable Flutter widgets for launching WhatsApp, Maps, and social links with app checks and RTL support.
๐ Launchify โ Flutter URL Launcher UI Kit #
The complete Flutter package for launching URLs, deep links, and native apps โ with beautiful ready-to-use UI widgets, zero boilerplate, and production-grade reliability.
Launch WhatsApp, Phone, Email, SMS, Maps, Instagram, TikTok, LinkedIn, Facebook, X (Twitter), Threads, GitHub, Calendar, and any custom URI โ all from a single widget with one line of code.
๐ฌ Demo #

Why Launchify? #
url_launcher is great for opening URLs. But in real apps you need:
- A button that opens WhatsApp without writing URI logic
- A settings screen row that dials a phone number
- A fallback when Instagram isn't installed
- Confirmation dialogs before leaving the app
- RTL layout flipping for Arabic/Urdu users
- Link previews with OpenGraph metadata
Launchify gives you all of that in a single LaunchLink widget.
๐ Launchify vs url_launcher #
| Feature | url_launcher | ๐ Launchify |
|---|---|---|
| Ready-to-use UI widgets | โ | โ |
| WhatsApp / Social deep links | โ Manual URI | โ One line |
| App-not-installed dialog | โ | โ Built-in |
| Web fallback handling | โ | โ Auto / Prompt / None |
| Confirmation dialog before launch | โ | โ |
| Link preview card (OpenGraph) | โ | โ
LaunchPreviewCard |
| RTL layout support | โ | โ Automatic |
| Tap debouncing | โ | โ Per-widget |
| Analytics tracking | โ | โ Built-in + external sink |
| Scheme allowlist enforcement | โ | โ |
| Press animation on buttons | โ | โ |
โจ Features at a Glance #
- 16 built-in launch types โ WhatsApp, Phone, Email, SMS, Website, Map, Instagram, TikTok, LinkedIn, Facebook, X, Threads, GitHub, Calendar, Share, Custom
- 2 display modes โ
ActionButton(CTA button) andLinkRow(settings-style row) - Smart URI builders โ auto-formats phone numbers, encodes emails, builds map queries
- Fallback strategies โ automatic web fallback, user-prompt, or none
- App installation check โ detects if native app is installed, shows dialog with App Store link
- Confirmation dialogs โ ask user before leaving the app
- Multi-choice app chooser โ let users pick between Google Maps, Apple Maps, Waze, etc.
- Link preview card โ fetches OpenGraph / Twitter Card metadata with caching
- Full style control โ colors, fonts, border radius, icons, padding, outlined/filled, animations
- Custom icons โ
IconData, local assets, network images, SVG - RTL/LTR โ automatic layout flipping for Arabic, Urdu, Hebrew, and more
- Analytics โ built-in launch tracking +
setExternalTracker()for Firebase / Amplitude - Production safe โ all logs stripped in release builds, scheme validation enforced
๐ฆ Installation #
dependencies:
launchify: ^1.0.8
flutter pub get
Android setup #
Add to android/app/src/main/AndroidManifest.xml inside <manifest>:
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.DIAL" />
</intent>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="sms" />
</intent>
<package android:name="com.whatsapp" />
<package android:name="com.instagram.android" />
<package android:name="com.linkedin.android" />
<package android:name="com.facebook.katana" />
</queries>
iOS setup #
Add to ios/Runner/Info.plist:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>whatsapp</string>
<string>instagram</string>
<string>linkedin</string>
<string>fb</string>
<string>tiktok</string>
<string>comgooglemaps</string>
<string>waze</string>
<string>tel</string>
<string>sms</string>
<string>mailto</string>
</array>
App setup (required for dialogs) #
Wrap your app with the Launchify localization delegate so confirmation and fallback dialogs render correctly:
MaterialApp(
localizationsDelegates: [
AppLocalizations.delegate, // from launchify
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [Locale('en')],
home: MyHomePage(),
);
๐ Quick Start #
One import, one widget:
import 'package:launchify/launchify.dart';
// Open WhatsApp
LaunchLink(
type: LaunchType.whatsapp,
value: '+1234567890',
label: 'Chat on WhatsApp',
)
// Call a number
LaunchLink(
type: LaunchType.phone,
value: '+1234567890',
label: 'Call Us',
)
// Send an email
LaunchLink(
type: LaunchType.email,
value: 'hello@example.com',
queryParameters: {'subject': 'Hello', 'body': 'Hi there!'},
label: 'Email Us',
)
// Open a website
LaunchLink(
type: LaunchType.website,
value: 'https://flutter.dev',
label: 'Visit Website',
)
// Open map location
LaunchLink(
type: LaunchType.map,
value: 'Eiffel Tower, Paris',
label: 'Get Directions',
)
// Share text
LaunchLink(
type: LaunchType.share,
label: 'Share App',
queryParameters: {'text': 'Check out Launchify!'},
)
๐จ Display Modes #
Action Button (default) #
A CTA button โ URL is hidden, only the label is shown. Perfect for contact sections.
LaunchLink(
type: LaunchType.whatsapp,
value: '+1234567890',
label: 'Chat on WhatsApp',
style: LaunchStyle(
backgroundColor: Color(0xFF25D366),
textColor: Colors.white,
borderRadius: 12,
),
)
Link Row #
A horizontal row showing the visible text โ ideal for settings screens and profile pages.
LaunchLink(
mode: LaunchDisplayMode.linkRow,
type: LaunchType.email,
value: 'support@myapp.com',
// visibleText defaults to value if not set
)
LaunchLink(
mode: LaunchDisplayMode.linkRow,
type: LaunchType.phone,
value: '+1 555 010 999',
visibleText: '+1 (555) 010-999 โ Support Line',
icon: Icons.support_agent,
)
๐ฑ All Supported Launch Types #
// Communication
LaunchType.whatsapp // Opens WhatsApp chat
LaunchType.phone // Dials phone number
LaunchType.email // Opens email client
LaunchType.sms // Opens SMS app
// Web & Navigation
LaunchType.website // Opens browser
LaunchType.map // Opens Maps (Google Maps / Apple Maps)
LaunchType.custom // Any custom URI scheme
// Social Media
LaunchType.instagram // Instagram profile or post
LaunchType.tiktok // TikTok profile or video
LaunchType.linkedin // LinkedIn profile or page
LaunchType.facebook // Facebook profile or page
LaunchType.x // X (Twitter) profile
LaunchType.threads // Threads profile
LaunchType.github // GitHub profile or repository
// Productivity
LaunchType.calendar // Creates a Google Calendar event
LaunchType.share // Opens native share sheet
๐จ Styling #
Full control over every visual property:
LaunchLink(
type: LaunchType.website,
value: 'https://flutter.dev',
label: 'Visit Flutter',
style: LaunchStyle(
backgroundColor: Colors.blue,
textColor: Colors.white,
iconColor: Colors.white,
borderRadius: 16,
fontSize: 15,
fontWeight: FontWeight.w600,
height: 52,
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 14),
),
)
// Outlined style
LaunchLink(
type: LaunchType.website,
value: 'https://pub.dev',
label: 'View on pub.dev',
style: LaunchStyle(
isOutlined: true,
borderColor: Colors.indigo,
borderWidth: 2,
textColor: Colors.indigo,
borderRadius: 8,
),
)
// Press animation
LaunchLink(
type: LaunchType.phone,
value: '+1234567890',
label: 'Call Now',
style: LaunchStyle(
backgroundColor: Colors.green,
isAnimated: true,
animationDuration: Duration(milliseconds: 100),
),
)
Theme Presets #
Apply your app's color scheme instantly:
LaunchLink(
type: LaunchType.email,
value: 'hello@example.com',
label: 'Email Us',
style: LaunchStyle(themePreset: LaunchThemePreset.primary),
)
// Available presets:
// LaunchThemePreset.primary
// LaunchThemePreset.secondary
// LaunchThemePreset.accent
// LaunchThemePreset.neutral
// LaunchThemePreset.destructive
๐ผ๏ธ Custom Icons #
// Material icon
LaunchLink(
type: LaunchType.website,
value: 'https://flutter.dev',
label: 'Flutter',
icon: Icons.rocket_launch,
)
// Local SVG / PNG asset
LaunchLink(
type: LaunchType.website,
value: 'https://flutter.dev',
label: 'Flutter',
customIcon: LaunchIcon.fromAsset('assets/icons/flutter.svg'),
)
// Network image
LaunchLink(
type: LaunchType.whatsapp,
value: '+1234567890',
label: 'WhatsApp',
customIcon: LaunchIcon.fromNetwork('https://example.com/whatsapp.png'),
)
// Hide icon completely
LaunchLink(
type: LaunchType.website,
value: 'https://flutter.dev',
label: 'Flutter',
showIcon: false,
)
๐ Social Media Deep Links #
Pass the full URL โ Launchify handles native app opening with automatic web fallback:
// Instagram
LaunchLink(
type: LaunchType.instagram,
value: 'https://www.instagram.com/yourhandle/',
label: 'Follow on Instagram',
style: LaunchStyle(backgroundColor: Color(0xFFE1306C)),
)
// TikTok
LaunchLink(
type: LaunchType.tiktok,
value: 'https://www.tiktok.com/@yourhandle',
label: 'Follow on TikTok',
style: LaunchStyle(backgroundColor: Colors.black),
)
// LinkedIn
LaunchLink(
type: LaunchType.linkedin,
value: 'https://www.linkedin.com/in/yourprofile',
label: 'Connect on LinkedIn',
style: LaunchStyle(backgroundColor: Color(0xFF0077B5)),
)
// Facebook
LaunchLink(
type: LaunchType.facebook,
value: 'https://www.facebook.com/yourpage',
label: 'Follow on Facebook',
style: LaunchStyle(backgroundColor: Color(0xFF1877F2)),
)
// X (Twitter)
LaunchLink(
type: LaunchType.x,
value: 'yourhandle',
label: 'Follow on X',
)
// GitHub
LaunchLink(
type: LaunchType.github,
value: 'your-org/your-repo', // or just 'username'
label: 'View on GitHub',
style: LaunchStyle(backgroundColor: Color(0xFF333333)),
)
๐ Calendar Events #
LaunchLink(
type: LaunchType.calendar,
label: 'Add to Calendar',
calendarEvent: CalendarEvent(
title: 'Team Standup',
description: 'Daily sync meeting',
startDate: DateTime(2025, 8, 1, 9, 0),
endDate: DateTime(2025, 8, 1, 9, 30),
location: 'Google Meet',
allDay: false,
),
style: LaunchStyle(backgroundColor: Colors.deepOrange),
)
๐ก๏ธ Advanced Options via LaunchOptions #
Confirmation dialog before launch #
LaunchLink(
type: LaunchType.website,
value: 'https://external-site.com',
label: 'Open External Site',
options: LaunchOptions(
requireConfirmation: true,
confirmationDialogTitle: 'Leave App?',
confirmationDialogMessage: 'You are about to open an external website.',
),
)
App not installed โ show dialog with App Store link #
LaunchLink(
type: LaunchType.whatsapp,
value: '+1234567890',
label: 'Chat on WhatsApp',
options: LaunchOptions(
checkAppInstallation: true,
appStoreLink: 'https://apps.apple.com/app/whatsapp/id310633997',
appNotInstalledDialogTitle: 'WhatsApp Not Found',
appNotInstalledDialogMessage: 'Install WhatsApp to use this feature.',
),
)
Web fallback strategies #
// Automatically open browser if app is unavailable
options: LaunchOptions(fallbackMode: LaunchFallbackMode.automatic)
// Ask the user first
options: LaunchOptions(fallbackMode: LaunchFallbackMode.prompt)
// No fallback โ fail silently
options: LaunchOptions(fallbackMode: LaunchFallbackMode.none)
Multi-choice app chooser #
LaunchLink(
type: LaunchType.map,
value: 'New York City',
label: 'Open in Maps',
options: LaunchOptions(
useMultiChoiceDialog: true,
dialogTitle: 'Choose a Maps App',
),
)
Allowed URI schemes (security) #
LaunchLink(
type: LaunchType.custom,
value: 'myapp://dashboard',
label: 'Open Dashboard',
allowedSchemes: ['myapp', 'https'],
)
Result callbacks #
LaunchLink(
type: LaunchType.phone,
value: '+1234567890',
label: 'Call Us',
onTap: () => print('Button tapped'),
onResult: (success) {
if (!success) showErrorSnackbar('Could not open phone app');
},
options: LaunchOptions(
onLaunchResult: (type, uri, success) {
analytics.logEvent('launch_attempt', {'type': type.name, 'success': success});
},
),
)
๐ Link Preview Card #
Fetches OpenGraph metadata and displays a rich preview before the user taps:
LaunchPreviewCard(
url: 'https://flutter.dev',
onTap: () => print('Card tapped'),
style: LaunchPreviewStyle(
borderRadius: 16,
elevation: 3,
imageHeight: 200,
),
)
Previews are cached in memory for 10 minutes โ safe to use inside lists.
๐ Analytics #
Track every successful launch automatically:
// Read counts
final count = LaunchAnalytics.getLaunchCount(LaunchType.whatsapp);
final last = LaunchAnalytics.getLastLaunchTimestamp(LaunchType.email);
final all = LaunchAnalytics.allLaunchCounts;
// Wire up Firebase or any external service (call once at app startup)
LaunchAnalytics.setExternalTracker((type, uri) {
FirebaseAnalytics.instance.logEvent(
name: 'launchify_open',
parameters: {'type': type.name, 'uri': uri.toString()},
);
});
// Per-widget callback via LaunchOptions
options: LaunchOptions(
onTrackLaunch: (type, uri) => print('Launched $type โ $uri'),
)
๐ RTL Support #
Layout direction flips automatically based on the device locale. No extra code needed:
// In an Arabic/Urdu locale this renders right-to-left automatically
LaunchLink(
mode: LaunchDisplayMode.linkRow,
type: LaunchType.whatsapp,
value: '+923001234567',
visibleText: 'ุชูุงุตู ู
ุนูุง ุนุจุฑ ูุงุชุณุงุจ',
)
// Force RTL in a specific widget tree
Directionality(
textDirection: TextDirection.rtl,
child: LaunchLink(
mode: LaunchDisplayMode.linkRow,
type: LaunchType.phone,
value: '+1234567890',
visibleText: 'ุงุชุตู ุจูุง',
),
)
๐ ๏ธ Programmatic Launching (no widget) #
Launch from business logic without a widget:
// Check if a launch is possible
final canOpen = await LaunchifyLauncher.canLaunch(
type: LaunchType.whatsapp,
value: '+1234567890',
);
// Launch programmatically
final success = await LaunchifyLauncher.launchAction(
context,
type: LaunchType.email,
value: 'hello@example.com',
queryParameters: {'subject': 'Hello'},
);
๐๏ธ Full API Reference #
LaunchLink parameters #
| Parameter | Type | Description |
|---|---|---|
type |
LaunchType |
Required. The action to perform |
value |
String? |
Phone number, email, URL, username, etc. |
mode |
LaunchDisplayMode |
actionButton (default) or linkRow |
label |
String? |
Button label (actionButton mode) |
visibleText |
String? |
Displayed text (linkRow mode) |
style |
LaunchStyle? |
Visual styling |
icon |
IconData? |
Override default icon |
customIcon |
LaunchIcon? |
Asset, network, or SVG icon |
showIcon |
bool |
Show/hide icon (default: true) |
queryParameters |
Map<String,dynamic>? |
Extra URI params (subject, body, etc.) |
shareText |
String? |
Text for LaunchType.share |
shareSubject |
String? |
Subject for LaunchType.share |
calendarEvent |
CalendarEvent? |
Event for LaunchType.calendar |
options |
LaunchOptions? |
Advanced behavior options |
allowedSchemes |
List<String>? |
Scheme security allowlist |
onTap |
VoidCallback? |
Called on tap (before launch) |
onResult |
Function(bool)? |
Called after launch with success status |
alignment |
MainAxisAlignment? |
Row alignment (linkRow mode) |
showUnderline |
bool? |
Underline on link text (linkRow mode) |
LaunchStyle parameters #
| Parameter | Type | Description |
|---|---|---|
backgroundColor |
Color? |
Button/row background |
textColor |
Color? |
Label color |
iconColor |
Color? |
Icon tint |
borderRadius |
double? |
Corner radius |
padding |
EdgeInsetsGeometry? |
Inner padding |
fontSize |
double? |
Label font size |
fontWeight |
FontWeight? |
Label font weight |
height |
double? |
Widget height |
iconWidth / iconHeight |
double? |
Icon dimensions |
isOutlined |
bool |
Outlined button style |
borderColor |
Color? |
Outline color |
borderWidth |
double? |
Outline width |
showUnderline |
bool? |
Underline on text |
themePreset |
LaunchThemePreset? |
Auto color preset |
isAnimated |
bool? |
Enable press animation |
animationDuration |
Duration? |
Animation speed |
LaunchOptions parameters #
| Parameter | Type | Description |
|---|---|---|
fallbackMode |
LaunchFallbackMode |
automatic, prompt, or none |
requireConfirmation |
bool |
Show confirmation dialog |
checkAppInstallation |
bool |
Detect if native app is installed |
appStoreLink |
String? |
URL to App Store / Play Store |
useMultiChoiceDialog |
bool |
Show app chooser dialog |
bypassAppDetectionAndFallback |
bool |
Skip checks, launch directly |
appNotInstalledDialogTitle |
String? |
Custom dialog title |
appNotInstalledDialogMessage |
String? |
Custom dialog message |
confirmationDialogTitle |
String? |
Custom confirm title |
confirmationDialogMessage |
String? |
Custom confirm message |
onLaunchAttempt |
Function(type, uri)? |
Called before launch |
onLaunchResult |
Function(type, uri, bool)? |
Called after launch |
onTrackLaunch |
Function(type, uri)? |
Analytics callback |
๐๏ธ Real-World Examples #
Contact section in a business app #
Column(
children: [
LaunchLink(
type: LaunchType.whatsapp,
value: '+1234567890',
label: 'Chat on WhatsApp',
style: LaunchStyle(backgroundColor: Color(0xFF25D366)),
),
const SizedBox(height: 12),
LaunchLink(
type: LaunchType.phone,
value: '+1234567890',
label: 'Call Us',
style: LaunchStyle(backgroundColor: Colors.blue),
),
const SizedBox(height: 12),
LaunchLink(
type: LaunchType.email,
value: 'support@myapp.com',
queryParameters: {'subject': 'Support Request'},
label: 'Email Support',
style: LaunchStyle(backgroundColor: Colors.orange),
),
],
)
Settings / Profile screen #
Card(
child: Column(
children: [
LaunchLink(
mode: LaunchDisplayMode.linkRow,
type: LaunchType.website,
value: 'https://myapp.com/privacy',
visibleText: 'Privacy Policy',
icon: Icons.privacy_tip_outlined,
),
const Divider(indent: 48),
LaunchLink(
mode: LaunchDisplayMode.linkRow,
type: LaunchType.website,
value: 'https://myapp.com/terms',
visibleText: 'Terms of Service',
icon: Icons.gavel_outlined,
),
const Divider(indent: 48),
LaunchLink(
mode: LaunchDisplayMode.linkRow,
type: LaunchType.email,
value: 'feedback@myapp.com',
visibleText: 'Send Feedback',
icon: Icons.feedback_outlined,
),
],
),
)
Social media bar #
Wrap(
spacing: 8,
children: [
LaunchLink(
type: LaunchType.instagram,
value: 'https://instagram.com/yourhandle',
label: 'Instagram',
style: LaunchStyle(backgroundColor: Color(0xFFE1306C)),
),
LaunchLink(
type: LaunchType.linkedin,
value: 'https://linkedin.com/in/yourprofile',
label: 'LinkedIn',
style: LaunchStyle(backgroundColor: Color(0xFF0077B5)),
),
LaunchLink(
type: LaunchType.x,
value: 'yourhandle',
label: 'X',
style: LaunchStyle(backgroundColor: Colors.black),
),
],
)
Map with app chooser #
LaunchLink(
type: LaunchType.map,
value: '37.7749,-122.4194', // or place name
label: 'Get Directions',
options: LaunchOptions(
useMultiChoiceDialog: true,
dialogTitle: 'Open in Maps',
),
)
๐ง Troubleshooting #
WhatsApp button does nothing on Android
Add <package android:name="com.whatsapp" /> to your AndroidManifest.xml queries block.
Links open in browser instead of native app on iOS
Add the app's scheme to LSApplicationQueriesSchemes in Info.plist and use checkAppInstallation: true in LaunchOptions.
Dialog strings are missing / crash
Make sure AppLocalizations.delegate is in your localizationsDelegates list.
Preview card shows plain URL instead of rich preview Some sites block metadata fetching by origin. This is expected for those domains โ the widget falls back to a tappable plain-text link automatically.
๐ Changelog #
See CHANGELOG.md for the full version history.
๐ License #
MIT โ see LICENSE.
โค๏ธ Maintained by GreenLogix #
GreenLogix โ Flutter, Laravel & AI Development Agency
๐ greelogix.com ยท ๐ฉ hello@greelogix.com
Need a custom Flutter app, package customization, or enterprise integration? We'd love to help.
๐ฆ More Flutter Packages by GreenLogix #
| Package | Description |
|---|---|
| quick_popup_manager | Smart popup, dialog & overlay management |
| smart_form_toolkit | Advanced form widgets with built-in validation |
| safe_json_mapper | Type-safe JSON parsing utilities |
| best_form_validator | Robust form validation library |
| flutter_telescope | Flutter debugging & app insights toolkit |
If Launchify saves you time, please give it a โญ on pub.dev โ it helps other developers discover it.