Search code examples
c#androidwebviewmauivisual-studio-2022

Why is it that the .NET MAUI WebView is unable to open links to websites that are not its source?


I am developing with Visual Studio 2022 a NET MAUI mobile app that contains a WebView object. The source website, mywebsite.com, is loaded correctly and all its internal links work.

My aim is making sure that when a link to a different website, say, microsoft.com, is clicked, the website opens in the default browser of the user's mobile phone.

Problem is, when I click on microsoft.com (or whatever other external link), nothing happens.

Navigating event is not triggered with these external links whether the target in the HTML is set to _blank or not; the solutions provided here (MAUI Webview target="_blank" href redirects not working on android) and here (Intercept all links user clicks on in WebView (.NET Maui)) did not work for me.

The navigating event is regularly triggered when clicking on links internal to mywebsite.com.

My MainPage.xaml.cs contains:

public MainPage()
{
    InitializeComponent();
    // Subscribe to the Navigating event
    proteoWebView.Navigating += OnNavigating;
    // Subscribe to the Navigated event
    proteoWebView.Navigated += OnNavigated;
}

private void OnNavigating(object sender, WebNavigatingEventArgs e)
{
    // Check if the URL is external
    if (!e.Url.StartsWith("https://mywebsite.com"))
    {
        // Cancel the navigation in the WebView
        e.Cancel = true;
        // Open the URL in the default browser of the user's phone
        Launcher.TryOpenAsync(e.Url);
    }
}

My MainPage.xaml contains:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ProteoApp.MainPage"
             NavigationPage.HasNavigationBar="False">
    <Grid>
        <WebView 
                 x:Name="proteoWebView"
                 Source="https://mywebsite.com"
                 Grid.Row="0"
                 Grid.Column="0"
                 VerticalOptions="FillAndExpand"
                 HorizontalOptions="FillAndExpand"/>
    </Grid>
</ContentPage>

Other information: I am developing with Visual Studio 2022, .NET 7.0, and I have experienced the issue with the Pixel 5 – API 33 (13.0 Android) emulator.


Solution

  • I should correct myself.

    Foreign links with a target="_blank" property do not trigger OnNavigating event. Foreing links without a target="_blank" property do trigger OnNavigating event.

    Furthermore, in order to open the user's phone default browser, an async call must be performed:

    private void OnNavigating(object sender, WebNavigatingEventArgs e)
        {
            if (!e.Url.StartsWith("https://mywebsite.com"))
            {
                e.Cancel = true;
                Task.Run(async () =>
                {
                    await Launcher.OpenAsync(e.Url);
                });
            }
    

    As I have mentioned, the above code works only for foreign links without a target="_blank" property. In order to make it work also for foreign links with a target="_blank" property, it is necessary to add this code to the OnNavigated event:

    private void OnNavigated(object sender, WebNavigatedEventArgs e)
        {
            //The following code changes the target of all the links in _self
            proteoWebView.EvaluateJavaScriptAsync(@"(function() {
                var links = document.getElementsByTagName('a');
                for (var i = 0; i < links.length; i++)
                {
                    links[i].setAttribute('target', '_self');
                }
            })()");
        }
    

    This solved the issue for me.