Search code examples
flutterflutterwebviewplugin

how to allow mailto schemes in webview flutter


I am working on Flutter webview apps using Flutter Webview plugin.

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: SafeArea(
              child : const WebView(
                initialUrl: 'https://google.com',
                javascriptMode: JavascriptMode.unrestricted,
              ),
            )
        )
    );
  }
}

However, if any links inside the opened web page is an app link, like: fb://profile, I will get net::ERR_UNKNOWN_URL_SCHEME.

In android, I found the solution is to override shouldOverrideUrlLoading as mentioned here, but what should I do in flutter?

I'm trying the solution mentioned here.

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: SafeArea(
              child : const WebView(
                initialUrl: 'https://google.com',
                javascriptMode: JavascriptMode.unrestricted,
                navigationDelegate: (NavigationRequest request)  {
                  if (request.url.contains("mailto:")) {
                    launch(request.url);
                    return NavigationDecision.navigate;
                  }
                },
              ),
            )
        )
    );
  }
}

But it is throwing errors like

Error: Not a constant expression. if (request.url.contains("mailto:")) {


Solution

  • You can copy paste run full code below
    Step 1: You can remove const keyword from const WebView
    Step 2: You can use NavigationDecision.prevent

    working demo

    enter image description here

    full code

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

    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                body: SafeArea(
          child: WebView(
            initialUrl:
                'https://google.com', //'''https://www.scottseverance.us/mailto.html',
            javascriptMode: JavascriptMode.unrestricted,
            navigationDelegate: (NavigationRequest request) {
              print(request.url);
              if (request.url.contains("mailto:")) {
                launch(request.url);
                return NavigationDecision.prevent;
              } else {
                return NavigationDecision.navigate;
              }
            },
          ),
        )));
      }
    }