Open Xamarin Forms WebView links in external browser

On occasions you may find a need to display a block of HTML in your app, for a bit of legal blurb for example, and you'll reach for the trusty WebView.

The WebView control is great for displaying a page of HTML, however it comes "as is". If a user clicks on a link within the WebView, it opens the link within the same view, but the user is unable to go back, as the WebView has no navigation controls.

By intercepting the WebView.Navigating event, we can block the WebView from opening the url and instead take advantage of Xamarin.Essentials Browser.OpenAsync method. In order to make this re-usable, I've wrapped it in a Behavior so it can be easily applied to any WebViews that require it.

View the sample code for this on GitHub

WebViewBrowserLinkBehavior

public class WebViewBrowserLinkBehavior : BehaviorBase<WebView>
{
    protected override void OnAttachedTo(WebView webView)
    {
		base.OnAttachedTo(webView);
		webView.Navigating += WebViewOnNavigating;
	}

	protected override void OnDetachingFrom(WebView webView)
	{
		base.OnDetachingFrom(webView);
		webView.Navigating -= WebViewOnNavigating;
	}

	private void WebViewOnNavigating(object sender, WebNavigatingEventArgs e)
	{
		if (!e.Url.StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
			return;

        e.Cancel = true;
		_ = Browser.OpenAsync(e.Url, this.LaunchOptions);
	}
}

In the behavior we subscribe and unsubscribe to the WebView's Navigating() event via the OnAttachedTo and OnDetachingFrom methods respectively.

In the event handler, we check to see if the url that's been clicked starts with "http" and if so, we cancel the WebView's navigation and call Browser.OpenAsync with the url.

You could omit the check to see if the url starts with Http if you want, and use the Launcher.OpenAsync method instead.

Using the behavior

As with most other Xamarin Forms controls, WebView contains a Behaviors property and so we can just add our behavior to that:

<ContentPage x:Class="PrivacyPolicyLinks.MainPage"
             xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:behaviors="clr-namespace:PrivacyPolicyLinks.Behaviors">
    ...
    
    <WebView>
        <WebView.Source>
            <HtmlWebViewSource Html="{Binding DocumentText}" />
        </WebView.Source>
    
        <WebView.Behaviors>
            <behaviors:WebViewBrowserLinkBehavior />
        </WebView.Behaviors>
    </WebView>
</ContentPage>

And there we have it a simple behavior that will automatically launch hyperlinks in an external browser, leaving the original content of the webview in tact.

Source

You can find a full working sample of the code with some additional properties for cusomization on GitHub