Skip to content

Modus-Logo-Long-BlackCreated with Sketch.

  • Services
  • Work
  • Blog
  • Resources

    OUR RESOURCES

    Innovation Podcast

    Explore transformative innovation with industry leaders.

    Guides & Playbooks

    Implement leading digital innovation with our strategic guides.

    Practical guide to building an effective AI strategy
  • Who we are

    Our story

    Learn about our values, vision, and commitment to client success.

    Open Source

    Discover how we contribute to and benefit from the global open source ecosystem.

    Careers

    Join our dynamic team and shape the future of digital transformation.

    How we built our unique culture
  • Let's talk
  • EN
  • FR

For anyone who has had the pleasure of working with Cordova you may hit this wall if you had to deal with external links. Tapping on a link opens the URL right in the WebView that your application is sitting in. The contents of the new page take over your application entirely and the user has no choice but to force close the app.

There are a couple of solutions to tackle this issue from a Cordova perspective.:

Note: These solutions are for Cordova 2.0.0. Earlier Cordova versions have minor differences, but these techniques can be applied.

Open all URLs externally in Mobile Safari

  1. In XCode, open the MainViewController.m class.
  2. Find the method: shouldStartLoadWithRequest, it should be commented out by default
    - (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
    {
        return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
    }
    
  3. Implement the following:
    - (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        NSURL *url = [request URL]; // URL that was requested
    
        // Test that URL scheme is either HTTP(S)
        if ([[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"https"]) {
            [[UIApplication sharedApplication] openURL:url]; // forward to application router
            return NO;
        }
        else {
            return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
        }   
    }
    

The shouldStartLoadWithRequest method gets called before a WebView is about to load a URL. Here we intercept the request and pass it on to UIApplication. UIApplication serves as a global application router. Mobile Safari is registered to handle http hrefs (Mail.app to mailto, other applications to their custom protocols, etc..). So when we call the openURL method, Mobile Safari is invoked. We return NO (false) to the method to tell the WebView that we will not load the frame internally.

ChildBrowser Plugin

Let’s say you don’t want the user to leave your application, why would you? This is where Cordova’s ChildBrowser plugin comes into play. The ChildBrowser creates a WebView inside your main Cordova WebView. It has a bottom toolbar with necessary buttons (Done, Back, Forward, etc..).

Installing the ChildBrowser plugin is straightforward, you can follow this excellent tutorial:

  • Bridging the PhoneGap: ChildBrowser Plugin

To get it to do what we need, open ALL URLs through the ChildBrowser we must do the following:

  1. In XCode, open the MainViewController.m class.
  2. Find the method: shouldStartLoadWithRequest, it should be commented out by default
  3. Include the necessary ChildBrowser classes at the top of your Controller implementation class
    #import "MainViewController.h"
    #include "ChildBrowserViewController.h" // Include ChildBrowserViewController so we can use it later
    
    @implementation MainViewController
    
  4. Implement the shouldStartLoadWithRequest with the following:
    - (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
    
        NSURL *url = [request URL]; // URL that was requested
    
        // Test that URL scheme is either HTTP(S)
        if ([[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"https"]) {
            [theWebView sizeToFit];
            ChildBrowserViewController* childBrowser = [ [ ChildBrowserViewController alloc ] initWithScale:FALSE ];
            childBrowser.modalPresentationStyle = UIModalPresentationFormSheet;
            childBrowser.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
            [super presentModalViewController:childBrowser animated:YES ];
            NSString* urlString=[NSString stringWithFormat:@"%@",[url absoluteString]];
            [childBrowser loadURL:urlString];
            [childBrowser release];
            return NO;
        }
        else {
            return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
        }   
    }
    
  5. In your JavaScript, all that is necessary is to “install ChildBrowser” (ChildBrowser.install()). There is no need to invoke it directly to open URL. All URL requests are now intercepted.
    Here we take the same approach as the Safari method. However, instead of passing on to the UIApplication reference we invoke the ChildBrowser directly.

A note on iFrames and YouTube

Cordova has a nasty bug/feature/issue that it opens all iFrames as they are added to the DOM. Thus if you have a YouTube video in an iFrame that you append to the DOM, it will open the ChildBrowser right away and begin displaying the video. Unfortunately we do not know where the URL request came from in the MainViewController implementation, all we have is the URL. Thus we can make conditions based on the destination (for example YouTube or Vimeo) and handle it by default with Cordova.

In Cordova.plist you can set the following properties to allow inline media playback. This will allow your YouTube video to play inside your original content and not take over the entire WebView.

References

  • PhoneGap + ChildBrowser – Opening all non-app links in ChildBrowser
  • PhoneGap External Link
Posted in Application Development
Share this

Stan Bershadskiy

Stan Bershadskiy specializes in all things JavaScript with vast knowledge in Sencha frameworks. Recently, he has directed his focus towards React Native and has co-authored The React Native Cookbook. Stan is located in New York City and can be found presenting at conferences around the country. During his time with Modus Create, Stan filled the role of Architect.
Follow

Related Posts

  • Cordova Logos
    New in Cordova 6: App Templates Using Git

    Along with the usual bug fixes, platform and plugin upgrades, a new feature was added…

  • Swift
    Writing a Cordova Plugin in Swift 3 for iOS

    This blog post is an update to one I wrote back in April 2016 and…

Want more insights to fuel your innovation efforts?

Sign up to receive our monthly newsletter and exclusive content about digital transformation and product development.

What we do

Our services
AI and data
Product development
Design and UX
IT modernization
Platform and MLOps
Developer experience
Security

Our partners
Atlassian
AWS
GitHub
Other partners

Who we are

Our story
Careers
Open source

Our work

Our case studies

Our resources

Blog
Innovation podcast
Guides & playbooks

Connect with us

Get monthly insights on AI adoption

© 2025 Modus Create, LLC

Privacy PolicySitemap
Scroll To Top
  • Services
  • Work
  • Blog
  • Resources
    • Innovation Podcast
    • Guides & Playbooks
  • Who we are
    • Careers
  • Let’s talk
  • EN
  • FR