Search code examples
javascriptcordovawhatsappinappbrowser

How do I gracefully interrupt loading of a certain URL in Cordova's InAppBrowser and open it in the system browser?


I am using Cordova's inappbrowser plugin to display web parts in my app. On the website, there are sharing links, e.g. for WhatsApp:

<a href="whatsapp://send?text=Check this out">Share on WhatsApp</a>

Now when clicking these links in inappbrowser, it simply tries to load whatsapp://send?... as a URL and displays an error page.

What I want to do instead is open links that start with whatsapp:// using the given system's browser/URI handler so it resembles the behavior when clicking such link in the system's browser. To do that, I did the following:

urlChanged = function(event) {
    // when a "whatsapp://" link is clicked, open it in the system browser
    if(event.url.startsWith("whatsapp://")) {
        window.open(event.url, "_system");
        return;
    } 
}
// Add an "loadstart" event listener to the inappbrowser:    
browser.addEventListener("loadstart", urlChanged);

So far, this somewhat works, but with quirks:

  1. While the event immediately fires when the user clicks a WhatsApp link (checked that by firing an alert), it takes like two or three seconds for the system browser to actually open.
  2. While waiting these 2-3 seconds and when returning to the app, the user sees an inappbrowser error page that the whatsapp:// link could not be opened ("unknown url scheme").

To mitigate point 2, I also tried the following in the event listener, without success (the behavior is exactly the same):

urlChanged = function(event) {
    if(event.url.startsWith("whatsapp://")) {
        // stop loading the whatsapp:// link in inappbrowser
        browser.stop(); 
        // go back in history to display page where whatsapp:// link was on
        browser.history.back(); 
        window.open(event.url, "_system");
        return;
    } 
}
browser.addEventListener("loadstart", urlChanged);

Can you guide me how to solve points 1 and 2?


Solution

  • So I ended up with the following code:

    openWithSystemBrowser = function(url) {
        window.open(url, "_system");
        location.href = "index.html";
    };
    
    shareOnWhatsapp = function(url) {
        openWithSystemBrowser(url);
    };
    
    /**
     * Handles URL changes in in-app browser, e.g. to handle logouts or
     * unsuccessful logins
     */
    urlChanged = function(event) {
        if(event.url.startsWith("http://whatsapp://")) {
            shareOnWhatsapp(event.url.substr("http://".length));
            return;
        }
        if(event.url.startsWith("whatsapp://")) {
            shareOnWhatsapp(event.url);
            return;
        }
    };
    

    This is of course slightly lame as you're always brought back to index.html, but for my purposes it was enough. Interested to see if anyone's found a more elegant solution.

    It also solved the 2-3 second delay before opening the system browser, but I don't have any clue why, frankly.