How do I open a web browser (URL) from my Flutter code?
Asked Answered
D

12

213

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?

Dupree answered 31/3, 2017 at 20:19 Comment(2)
gist.github.com/chinmaygarde/d778498418e30825d687147b79d070eb This may help.Diagonal
After some search, this issue can be solved via instructions listed here: groups.google.com/forum/#!topic/flutter-dev/J3ujgdOuG98 The above UrlLauncher is no longer usable.Setting
A
336

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.

Abednego answered 10/5, 2017 at 10:7 Comment(15)
Note that you might need to either create a new flutter project and copy over your Flutter specific stuff (lib, pubspec.yaml, etc.) or conversely update the platform specific folders in your old project for this to work.Wept
Note: Don't forget to add url_launcher: ^3.0.2 to the pubspec.yamlAeroscope
What do you mean with "added to existing apps"? Perhaps your files in 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
@Aeroscope Now url_launcher: ^5.0.2 Keep checking.Exuberance
How to open link for flutter_web where url_launcher plug-in is not available ?Illinois
Why would it not be available? You can write the code yourself. The urllauncher plugin is open source and you can check out its source and learn what it does. You can do the same in your applications code.Magnesium
@GünterZöchbauer, may I ask you to have a look at a Flutter related question here : #60566158 ?Kirkland
If you get Unhandled Exception: MissingPluginException just stop the app and then run it againInjurious
This works fine, the problem is that when I try to open a Facebook Messenger url, it is redirecting to intent:// and fails with ERR_UNKNOWN_URL_SCHEMEBenign
Only Android knows about that scheme. You'd need to call into Android (create a plugin in Java) to resolve the URL there and load the content from it, and then pass it back to Flutter. That's not a simple task. What exactly is the original URL for?Magnesium
is it possible to open Chrome in desktop mode in mobile?Kirchhoff
Great solution~ Just updating it a bit since launch and canLaunch are now deprecated. Future<bool> launchURL(url) async { if (await canLaunchUrl(url)) { await launchUrl(url); print("launched URL: $url"); return true; } else { print('Could not launch $url'); return false; } }Afterimage
url_launcher does not open if https has cert issues. doesnt look like an alternative is available.Reasoning
This solution is not true. launchUrl does not open the link in an external browser like Chrome or Firefox, it just open the link in the Android basic web browser. You need to add ` mode: LaunchMode.externalApplication`Pissed
thx, this is really works for me. The _launchUrl method can be assigned as void too.Unprofitable
P
78

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.

Pinafore answered 27/1, 2021 at 9:35 Comment(7)
Can you describe exactly where to place the <queries> portion in XML file?Taproot
It should be directly under <manifest> so at the same level as things like <uses-permissions> and <application>Pinafore
This method is deprecated now. It tells me to use launchUrl instead of launch. However, launchUrl opens a webview inside my app. This is not what I want. Got any tips?Angelaangele
@Angelaangele I've updated the answer to use the non-deprecated url and added details on where the url will launch with modePinafore
Suppose we want to connect to Facebook, how can we be directed to FB app , if it is installed, else browser ?Dunleavy
This 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
@Anteino, to open on the extranal browser use : launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication))Approachable
A
19

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';
  }
}

Output : enter image description here

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 in enableJavaScript: 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.

Aholla answered 10/12, 2020 at 15:10 Comment(3)
Is it possible to close the app after the URL is launched? I tried it with exit(0) but it also closes the browser.Zaria
@ManoHaran You can use forceSafariVC to open URL in default browser of the phone: await launch(URL, forceSafariVC: false);Nadya
care canLaunch is now deprecated ;)Ezarra
V
17

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.

Viscus answered 30/6, 2019 at 6:29 Comment(1)
The url_launcher package supports web nowTextual
N
14

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);
Nadya answered 25/3, 2021 at 7:57 Comment(1)
This is what I need as I have to launch a Firebase Dynamic Link from a QR code scanner that is provided in the app. I need the URL to launch externally so it is then recognised as a dynamic link in the app and handled appropriately.Plotkin
A
9

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

Output

Austere answered 13/7, 2022 at 12:16 Comment(0)
P
5

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).

Primulaceous answered 20/3, 2019 at 21:55 Comment(0)
G
2

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
Gwenora answered 31/8, 2022 at 19:0 Comment(0)
D
1

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 with void _launchURL() async { gives an error This expression has a type of 'void' so its value can't be used.
  • onPressed: _launchURL with Future<void> _launchURL() async { gives an error The argument type 'Future<void>' can't be assigned to the parameter type 'void Function()?'.
  • onPressed: _launchURL with _launchURL() async { launches automatically and throws an Exception type 'Future<dynamic>' is not a subtype of type '(() => void)?'
  • canLaunchUrl and canLaunchUrlString give messages I/UrlLauncher( 2899): component name for https://google.com is null and I/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');
  }
}
Decile answered 11/4 at 0:27 Comment(0)
J
0

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.

Jea answered 29/11, 2022 at 8:21 Comment(0)
B
0

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);
Broadway answered 2/2 at 11:47 Comment(0)
S
0

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

Spinoza answered 28/4 at 11:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.