How to open target="_blank" links in WKWebView in iOS

Short post explaining why by default target _blank links don't do anything and how to fix it with example code.

Published: May 10, 2020
See books

If you ever worked with WKWebView in your iOS application you may have noticed, that some links just don’t work. Meaning nothing happens when you click them. This post explains why WKWebView does not open some links and what to do about it.

The culprit is HTML attribute target set to value _blank which is used to signal links that should be opened in new tab instead of the current one.

<a href="https://iosfeeds.com" target="_blank" >iOS Feeds</a>

This target setting is meant to tell the browser (which is WKWebView in this case) that this link should be open in new tab by default. Which is the root of the problem.

Fix

However if you have basic WKWebView setup, these links just don’t work. The fix is hidden inside WKUIDelegate, more specifically in this method:

webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?

It is pretty long and automatically called whenever user is trying to open link from WKWebView.

It is there to give you opportunity to create new screen/tab in your application to provide user with same behavior as Safari or any other browsers.

You don’t have to implement this and still have working _blank links with this implementation:

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
    if let frame = navigationAction.targetFrame,
        frame.isMainFrame {
        return nil
    }
    webView.load(navigationAction.request)
    return nil
}

You first check, whether the targetFrame is main frame, meaning your current WKWebView. If so, then do nothing and return. If not, you can simply load this request in your current instance and once again return nil.

Of course, don’t forget to set the WKUIDelegate otherwise this method won’t be called.

 webView.uiDelegate = self

And that is all!

Uses: Xcode 12 & Swift 5.3

Filip Němeček profile photo

WRITTEN BY

Filip Němeček @nemecek_f@iosdev.space

iOS blogger and developer with interest in Python/Django. Want to see most recent projects? 👀

iOS blogger and developer with interest in Python/Django. Want to see most recent projects? 👀