Handle outgoing links in Xamarin WebView

When coding a Xamarin app that used a web view, I needed certain links to open in the existing view and some to open in Safari instead. To do this, you need to hook into the event on navigating for the web view.

I then create a white-list of allowed URLs and check the target of the event.

Edit the XAML code-behind file in the main Xamarin project and adjust the constructor as:

/// <summary>
/// Initializes a new instance of the <see cref="MainPage"/> class.
/// </summary>
public MainPage()
{
    InitializeComponent();

    // Note: this property was declared on class level and loaded from a resource file
    WebView.Source = new UrlWebViewSource { Url = BaseUrl };

    // Force links that open to other sites to open in the native web browser,
    // not in our app or during login attempts
    WebView.Navigating += (s, e) =>
        {
            var url = e.Url.ToLowerInvariant();
            var external = !url.Contains(".msftauth.net") && !url.Contains("login.microsoftonline.com")
                                                          && !url.Contains("lekman.com")
                                                          && !url.Contains(BaseUrl);
            var force = url.Contains("_top") || url.Contains("_blank");
            if (url.StartsWith("http") && external | force)
            {
                try
                {
                    var uri = new Uri(e.Url);
                    Device.OpenUri(uri);
                }
                catch (Exception)
                {
                    // Ignore
                }

                e.Cancel = true;
            }
        };
}

The Device.OpenUri call will force opening Safari instead. I also added the option to change a link by adding, for example, "&_top" in the URL to open in the external browser.

If you don't want to use Safari but instead Edge or Chrome then you could amend it to use a deep link instead. Edge, for example, uses "microsoft-edge-https://" as a deep link and can be forced by changing lines 24-25 to:

var uri = new Uri(e.Url);
if (DeviceInfo.Platform == DevicePlatform.iOS)
{
    // Change link to force into Edge
    uri = new Uri("microsoft-edge-" + e.Url);
}

Device.OpenUri(uri);

Hope this helps!