Flutter Webview - Opening External Links in Browser or Window
Asked Answered
W

5

9

I have an Android app made using Flutter Webview. When the user click on an external link, I want the link to open in the browser. How can I do it?

In fact, it would be nice to open external links in a window like Instagram does. Is there a way to do this?

Edit:

website.com is my app's homepage. That is not a external link. What I want is when trying to open a link other than website.com, it opens in a browser or a window.

Home Page:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class Forum extends StatefulWidget {
  @override
  _ForumState createState() => _ForumState();

}

class _ForumState extends State<Forum> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Forum',
        home: Scaffold(
          body: WebView(initialUrl: "https://website.com",
            javascriptMode: JavascriptMode.unrestricted,
          ),
        )
    );
  }
}
Wheelbase answered 14/12, 2020 at 16:4 Comment(1)
This question is exist in there sampleStickseed
C
24

I had exactly the same problem and it cost me to solve it. Akif, even 5 months after your question, I will post the solution, because I believe it will still help a lot of people.

The solution below is using the STANDART FLUTTER WEBVIEW and also using the URL LAUNCHER.

Add the url_launcher and webview_flutter to your file pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  
  webview_flutter: ^1.0.5
  url_launcher: ^5.7.10

Now in your webview it needs to contain the navigationDelegate

See below...

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Title Your App',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: Scaffold(
            body: Container(
          child: WebView(
            initialUrl: 'https://website.com',
            javascriptMode: JavascriptMode.unrestricted,
            onWebViewCreated: (WebViewController webViewController) {
              _controller.complete(webViewController);
            },
            navigationDelegate: (NavigationRequest request) {
              if (request.url.startsWith("https://website.com")) {
                return NavigationDecision.navigate;
              } else {
                _launchURL(request.url);
                return NavigationDecision.prevent;
              }
            },
          ),
        )));
  }

  _launchURL(String url) async {
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      throw 'Could not launch $url';
    }
  }
}

Don´t forget that you need to add URL LAUNCHER dependence.

import 'package:url_launcher/url_launcher.dart';

Explanation:

This code causes every request that is made within the webview to pass the following test:

  • If the request address starts with your webview's start address, it normally does it within the webview.
  • If the request address is different from the initial address of your webview, it launches that request to the phone's default browser.

I hope that maybe it will still help you or that it will help someone who needs it from now on.

Hugs.

Crosswind answered 15/5, 2021 at 21:29 Comment(0)
X
2

you can use url_launcher plugin for this job

For that you need to add the plugin in your pubspec.yaml

so add url_launcher: ^5.7.10 in your pubspec,yaml file under dependencies

here is an example which will launch the website

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

void main() {
  runApp(Scaffold(
    body: Center(
      child: RaisedButton(
        onPressed: _launchURL,
        child: Text('Show Flutter homepage'),
      ),
    ),
  ));
}

_launchURL() async {
  const url = 'https:website.com';
  if (await canLaunch(url)) {
    await launch(url);
  } else {
    throw 'Could not launch $url';
  }
}
Xylem answered 14/12, 2020 at 16:19 Comment(5)
website.com is my app's homepage. That is not a external link. What I want is when trying to open a link other than website.com, it opens in the browser.Wheelbase
Yes, you can replace website.com with any other link that you want to open in the browseXylem
But, I don't know the site link that should open in the browser.Wheelbase
then what the thing that you want to open in the browser, please be clearXylem
All links other than the site shown in WebviewWheelbase
B
1

If you want to open link in a external browser then.try this url_launcher

For open browser, paste your url and call this on click,

also you can check your url contain your website or not.after this you can perform action,

    onPressed: () {
            var myUrl="https://website.com";
            if(myUrl.contains("website.com")){
              //place your website code
              print("its my website ");
            }else{
              _launchURL(myUrl);
            }
          }



  _launchURL(String myUrl) async {
    if (await canLaunch(myUrl))
    {
      await launch(myUrl);
    } else {
      throw 'Could not launch $myUrl';
    }
  }
Bret answered 14/12, 2020 at 16:18 Comment(3)
website.com is my app's homepage. That is not a external link. What I want is when trying to open a link other than website.com, it opens in the browser.Wheelbase
check again, i update my code with your website url check,Bret
he meant external links in his website, this code handles links in flutter not in webview' homepage sitePeriotic
G
1

You can open the link in the native browser app, Google for Android and Safari for iOS, with the flutter_custom_tabs plugin.

To install it, you'd need to add the following line below dependencies: in your pubspec.yaml:

flutter_custom_tabs: "^0.6.0"

And use a function like the following:

void _launchURL(BuildContext context, String url) async {
    try {
      await launch(
        url,
          extraCustomTabs: <String>[
            'org.mozilla.firefox',
            'com.microsoft.emmx',
          ],        
        ),
      );
    } catch (e) {
      debugPrint(e.toString());
    }
}
Goebel answered 14/12, 2020 at 16:41 Comment(0)
R
0

Based on Thiago's answer. Since I was using webviewx_plus package and the answer is a bit old with new updates in launch url package, few minor changes were needed:

  1. ONLY if using webviewx_plus package, for navigationDelegate: (NavigationRequest request) {...} webviewx_plus uses request.content.source as the url instead of request.url. Replace this and it will work fine.
WebViewX(
.
.
.
 navigationDelegate: (NavigationRequest request) {
                var url = request.content.source;
                if (url.startsWith("https://website.com")) {
                  return NavigationDecision.navigate;
                }
                _launchURL(Uri.parse(url));
                return NavigationDecision.prevent;
              }
}
  1. canLaunch and launch have been replaced by canLaunchUrl and launchUrl respectively. So the updated code is:
_launchURL(Uri url) async {
  if (await canLaunchUrl(url)) {
    await launchUrl(url);
  } else {
    throw 'Could not launch $url';
  }
}

// Usage
_launchURL(Uri.parse(url));
Risa answered 26/7 at 5:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.