How to handle popups and alerts in WKWebView

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
Search for a command to run...

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
No comments yet. Be the first to comment.
WWDC26 kicked off on June 8, 2026. The information in this article reflects the information published by Apple on that date. There are 14 new frameworks. Name Description AccessoryAccess Manage

WWDC25 kicked off on June 9, 2025. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AlarmKitSchedule prominent alarms and countdowns to help people manage their time. AVR...

WWDC25 is almost here, and I couldn’t be more excited! Whether you're attending the official events, community meetups, or just soaking in the energy around Cupertino, there’s no better time to connect, share ideas, and celebrate everything we love a...

In this blog post, I’ll share an observation and advice regarding the caching behavior of network responses by Apple’s APIs. If you are unfamiliar with caching of network responses then I recommend Apple’s article Accessing cached data that introduce...
WWDC24 kicked off on June 10, 2024. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AccessorySetupKitUse AccessorySetupKit to discover accessories with Bluetooth or Wi-Fi...

In this blog post, I'll explain how you can support popups and alerts in WKWebView because this is not supported out of the box.
The following cases do not work in a WKWebView automatically:
<a> HTML element with attribute target="_blank"<a> HTML element with href="javascript:alert('Hello World!');"window.open and window.close` functionsYou can verify that yourself by using this HTML page to manually test the three use cases.
<!DOCTYPE html>
<html>
<body>
<h1>WKWebView and WKUIDelegate</h1>
<h2>Testing a href with target="_blank"</h2>
<a href="https://www.google.com" target="_blank">Visit Google</a>
<h2>Testing a href with javascript:alert</h2>
<a href="javascript:alert('Hello World!');">Execute JavaScript</a>
<h2>Testing window.open() and window.close() Methods</h2>
<button onclick="openWin()">Open "myWindow" which will be closed after 3 seconds</button>
<script>
function openWin() {
myWindow = window.open("https://www.apple.com", "", "width=200,height=100");
setTimeout(function() { myWindow.close() }, 3000);
}
</script>
</body>
</html>
We start with a WKWebView without any delegate implementation.
let webView = WKWebView()
And let's load the HTML page, which can be bundled as a resource in an iOS application.
if let url = Bundle.main.url(forResource: "local", withExtension: "html") {
webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
}
Clicking on any other links or buttons has no effect.

Why is that?
The default web view implementation assumes one window per web view, so nonconventional user interfaces might implement a user interface delegate.
This quote is from the WKUIDelegate documentation.
WKUIDelegate is a protocol with several optional functions that can be implemented.
Web view user interface delegates implement this protocol to control the opening of new windows, augment the behavior of default menu items displayed when the user clicks elements, and perform other user interface-related tasks. These methods can be invoked as a result of handling JavaScript or other plug-in content.
extension ViewController: WKUIDelegate {}
let webView = WKWebView()
webView.uiDelegate = self // or whoever conforms to WKUIDelegate protocol
Let's implement the first function: webView(_:createWebViewWith:for:windowFeatures:)
If you do not implement this method, the web view will cancel the navigation.
A rudimentary implementation can be that such links are opened in the Safari app.
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
UIApplication.shared.open(navigationAction.request.url!, options: [:])
}
return nil
}
Later comes a more sophisticated example to allow handling navigation actions with the app itself. So keep on reading :)
First, you have to configure your WKWebView to allow JavaScript !!
let webView = WKWebView()
webView.uiDelegate = self
webView.configuration.preferences.javaScriptEnabled = true // !!
Then it's time to implement one of the runJavascript related functions in WKUIDelegate.
For the test case above the function webView(_:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:) needs to be implemented.
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let ac = UIAlertController(title: nil,
message: message,
preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Ok",
style: .default) { _ in
completionHandler()
})
present(ac, animated: true)
}
First, you have to configure your WKWebView that JavaScript can open windows !!
let webView = WKWebView()
webView.uiDelegate = self
webView.configuration.preferences.javaScriptEnabled = true
webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true // !!
| JavaScript | Triggered WKUIDelegate function |
window.open() | webView(_:createWebViewWith:for:windowFeatures:) |
window.close() | webViewDidClose(_:) |
You can achieve an in-app popup experience by implementing those two delegate functions and managing multiple WKWebInstances. For more details and an example project please check out the following GitHub repository:
You can support popups and alerts in a WKWebView by implementingWKUIDelegate.
