Opening WebView links in a native browser

Posted in Fuse Tools on Feb 20, 2017

At the time of publishing of this article, Fuse's WebView implementation (v0.34) is still under development.

One of the limitations or, should I say, things that don't work out of the box, is the fact that clicking on links in a WebView will open the URLs in the same WebView. Of course sometimes that is exactly what you need to happen, but in the case of a help page or an "About this app" one, you may want links to actually open in the native browser, leaving the initial page in place.

With the mention that I have only tested this on iOS (although I don't see an issue with Android), here goes.

So, consider we have a WebView created in a very straightforward manner:

<DockPanel>
    <NativeViewHost>
        <WebView Dock="Fill" Url="{url}" UrlChanged="{onUrlChanged}" BeginLoading="{onBeginLoading}" Visibility="{visible}" />
    </NativeViewHost>
</DockPanel>

Well, not that straightforward. I have just bound a few attributes to JS variables. Let's see how the javascript would look like:

var Observable = require('FuseJS/Observable'),
    baseUrl = 'https://keypoint.ro',
    url = Observable(baseUrl),
    visible = Observable('Visible');

function onUrlChanged()
{
    if (baseUrl != url.value) {
        var InterApp = require("FuseJS/InterApp");
        InterApp.launchUri(url.value);

        // reset our URL
        url.value = baseUrl;
    } else {
        visible.value = 'Visible';
    }
}

function onBeginLoading()
{
    visible.value = 'Hidden';
}

module.exports = {
    url: url,
    visible: visible,
    onUrlChanged: onUrlChanged,
    onBeginLoading: onBeginLoading
};

A few explanations: first of all, it is not a flawless implementation. The (small) issue is that the URL a link points to will be loaded twice; once in the WebView and once in the native browser.

"But, hey!..." Yeah, I know - that's why that visible property manipulation is going on over there: it hides the WebView until the base URL is loaded back into the WebView. The effect is that when clicking on a link, the WebView goes blank, presumably to open the native browser (which actually happens). When you go back to the app, what you will see is your initial content page back in place. Without this workaround, before switching to the native browser you would get a glimpse of the target page loading over your initial one.

This works pretty well for my "About" page and until the framework handles it more gracefully, I hope some of you will find it useful.

Enjoy it with the metal track of the day: