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 Sponsored App StoreIf 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