I am building a Flutter app, and I'd like to open a URL into a web browser or browser window (in response to a button tap). How can I do this?
TL;DR
This is now implemented as Plugin
final Uri url = Uri.parse('https://flutter.dev');
if (!await launchUrl(url)) {
throw Exception('Could not launch $_url');
}
Full example:
import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; void main() { runApp(new Scaffold( body: new Center( child: new RaisedButton( onPressed: _launchURL, child: new Text('Show Flutter homepage'), ), ), )); } _launchURL() async { final Uri url = Uri.parse('https://flutter.dev'); if (!await launchUrl(url)) { throw Exception('Could not launch $_url'); } }
In pubspec.yaml
dependencies:
url_launcher: ^6.1.11
Check out the latest url_launcher package.
Special Characters:
If the url
value contains spaces or other values that are now allowed in URLs, use
Uri.encodeFull(urlString)
or Uri.encodeComponent(urlString)
and pass the resulting value instead.
lib
, pubspec.yaml
, etc.) or conversely update the platform specific folders in your old project for this to work. –
Wept url_launcher: ^3.0.2
to the pubspec.yaml –
Aeroscope android/
or ios/
are outdated. If it works in a new app then compare the files and update them in your project. You can also delete these directories and run flutter create .
and then re-apply manual changes. –
Magnesium intent://
and fails with ERR_UNKNOWN_URL_SCHEME
–
Benign If you target sdk 30 or above canLaunch
will return false by default due to package visibility changes: https://developer.android.com/training/basics/intents/package-visibility
in the androidManifest.xml
you'll need to add the following directly under <manifest>
:
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
</queries>
Then the following should word - for flutter 3 upwards:
const uri = Uri.parse("https://flutter.io");
if (await canLaunchUrl(uri)){
await launchUrl(uri);
} else {
// can't launch url
}
or for older versions of flutter use this instead:
const url = "https://flutter.io";
if (await canLaunch(url)){
await launch(url);
} else {
// can't launch url
}
launchUrl
has a mode
parameter which can be used to control where the url gets launched.
So, passing in launchUrl(uri, mode: LaunchMode.platformDefault)
leaves the decision of how to launch the URL to the platform
implementation. But you can also specify
LaunchMode.inAppWebView
which will use an in-app web view
LaunchMode.externalApplication
for it to be handled by an external application
Or LaunchMode.externalNonBrowserApplication
to be handled by a non-browser application.
launchUrl
instead of launch
. However, launchUrl
opens a webview inside my app. This is not what I want. Got any tips? –
Angelaangele mode
–
Pinafore AndroidManifest.xml
step is not needed for this question, which is about actually opening a URL. It's only needed for canLaunchUrl
(and the deprecated canLaunch
). –
Reservation launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication))
–
Approachable The best way is to use url_launcher package .
Add url_launcher as a dependency in your pubspec.yaml
file.
dependencies:
url_launcher:
An example of how to use it :
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flutter is beautiful'),),
body: Center(
child: RaisedButton(
onPressed: _launchURL,
child: Text('Show Flutter homepage'),
),
),
)),
);
}
_launchURL() async {
const url = 'https://flutter.dev';
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
} else {
throw 'Could not launch $url';
}
}
The launch method takes a string argument containing a URL . By default, Android opens up a browser when handling URLs. You can pass
forceWebView: true
parameter to tell the plugin to open a WebView instead. If you do this for a URL of a page containing JavaScript, make sure to pass inenableJavaScript: true
, or else the launch method will not work properly. On iOS, the default behavior is to open all web URLs within the app. Everything else is redirected to the app handler.
For Flutter:
As described above by Günter Zöchbauer
For Flutter Web:
import 'dart:html' as html;
Then use:
html.window.open(url, name);
Make sure that you run flutter clean
if the import
doesn't resolve.
For those who wants to implement LAUNCH BROWSER AND EXIT APP by using url_launcher. Remember to use (forceSafariVC: false) to open the url in default browser of the phone. Otherwise, the launched browser exit along with your APP.
await launch(URL, forceSafariVC: false);
This is now implemented as Plugin
const url = "https://flutter.io"; final Uri _url = Uri.parse(url); await launchUrl(_url,mode: LaunchMode.externalApplication);
pubspec.yaml
Add dependencies
dependencies: url_launcher: ^6.0.12
If you want to use url_launcher than please use it in this form
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
url_launcher: ^5.0.2
flutter:
sdk: flutter
This answer is also for absolute beginners: They are thinking behind the flutter sdk. No that was a failure. The packages were extras and not in the flutter Sdk. These were secondary packages (single small framework helpers).
The PLUGIN plugin works great, as you explain in your examples.
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
final Uri _url = Uri.parse('https://flutter.dev');
void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: ElevatedButton(
onPressed: launchUrlStart(url: "https://flutter.dev"),
child: Text('Show Flutter homepage'),
),
),
),
),
);
Future<void> launchUrlStart({required String url}) async {
if (!await launchUrl(Uri.parse(url))) {
throw 'Could not launch $url';
}
}
But when trying to open PDF https://www.orimi.com/pdf-test.pdf it remained blank, the problem was that the browser handled it in its own way. Therefore the solution was to tell it to open with an external application and it worked as expected.
Future<void> launchUrlStart({required String url}) async {
if (!await launchUrl(Uri.parse(url),mode: LaunchMode.externalApplication)) {
throw 'Could not launch $url';
}
}
In pubspec.yaml
#https://pub.dev/packages/url_launcher
url_launcher: ^6.1.5
Since the question doesn't ask the link being a button, I have two solutions.
1. With the button
Many users here provide solutions that are similar, but for me they don't quite work for different reasons.
Use url_launcher and add it to the dependencies in pubspec.yaml.
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(new Scaffold(
body: new Center(
child: new ElevatedButton( //RaisedButton doesn't exist
onPressed: () async { // URL launching is an async function, the button must wait for press
_launchURL(Uri.https('google.com', ''));
},
child: new Text('Show Google homepage'),
),
),
));
}
Future<void> _launchURL(url) async { //you can also just use "void" or nothing at all - they all seem to work in this case
if (!await launchUrl(url)) {
throw Exception('Could not launch $url');
}
}
Wrong
onPressed: _launchURL
withvoid _launchURL() async {
gives an errorThis expression has a type of 'void' so its value can't be used.
onPressed: _launchURL
withFuture<void> _launchURL() async {
gives an errorThe argument type 'Future<void>' can't be assigned to the parameter type 'void Function()?'.
onPressed: _launchURL
with_launchURL() async {
launches automatically and throws an Exceptiontype 'Future<dynamic>' is not a subtype of type '(() => void)?'
canLaunchUrl
andcanLaunchUrlString
give messagesI/UrlLauncher( 2899): component name for https://google.com is null
andI/UrlLauncher( 2899): component name for https://flutter.dev is null
and the app never launches your URL.
Short way for using this:
...
child: new ElevatedButton(
onPressed: () async {
if (!await launchUrl(Uri.https('google.com', ''))) {
throw Exception('Could not launch');
}
},
...
Using !await launchUrl
checks if the URL can be launched and if not, then throws an Exception.
2. Without the button (just text, like a hyperlink)
Use url_launcher and add it to the dependencies in pubspec.yaml.
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(new Scaffold(
body: new Center(
child: new InkWell (
onTap: () async {
_launchURL(Uri.https('google.com', ''));
},
child: new Text('Show Google homepage'),
),
),
));
}
Future<void> _launchURL(url) async {
if (!await launchUrl(url)) {
throw Exception('Could not launch $url');
}
}
using the url_launcher package to do the following:
dependencies:
url_launcher: ^latest_version
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
}
Note: Ensure you are trying to open a URI, not a String.
If you want to open it in a local browser, the url_launcher package has a feature like this:
launchUrlString('https://exemple.com,mode: LaunchMode.externalApplication);
click on the blue texts for images
Make sure to make changes according to the url_launcher
package as this may change in new versions:Change sdkVersion
then make changes in your AndroidManisfest.xml file as below
Add the action and data in
then finally make changes for ios devices in the info.plist
file as below
Add permissions in info.plist
then finally implement the code yow will see it redirected to the flutter website took mine 4 hours just because I did not place the intents correctly
this image has the source code [4]: https://i.sstatic.net/196vJug3.png
Sorry I had ho use pictures as I am new here but wanted to help and this stupid rules. Moreover you should keep eye on the imports too as the link is also available in "dart:\io" package avoid it and use import of the url
launcher
© 2022 - 2024 — McMap. All rights reserved.
UrlLauncher
is no longer usable. – Setting