To discuss and provide feedback on our products, join the official AdMob Discord channel in the Google Advertising and Measurement Community server.

Optimize WKWebView click behavior

  • WKWebView has limitations with tabbed browsing, ad clicks opening in the same tab, AutoFill for credit cards, and Google Sign-in, which can negatively affect user experience and monetization.

  • Optimizing click behavior in WKWebView involves setting WKUIDelegate and WKNavigationDelegate to handle different link types and targets.

  • You can determine whether to optimize a click by checking the navigationType and targetFrame properties of the WKNavigationAction object.

  • Depending on your criteria, you can choose to open URLs in an external browser, SFSafariViewController, or the existing web view to manage click behavior effectively.

If your app utilizes WKWebView to display web content, you might want to consider optimizing click behavior for the following reasons:

  • WKWebView doesn't support tabbed browsing. Ad clicks that attempt to open a new tab do nothing by default.

  • Ad clicks that open in the same tab reload the page. You might want to force ad clicks to open outside the WKWebView, for example if you host H5 games and want to maintain the state of each game.

  • AutoFill doesn't support credit card information in WKWebView. This could lead to less ecommerce conversions for advertisers, negatively affecting the web content's monetization.

This guide provides recommended steps to optimize the click behavior in mobile web views while preserving the web view content.

Prerequisites

Implementation

Ad links can have the href target attribute set to either _blank, _top, _self, or _parent. Ad links can also contain JavaScript functions such as window.open(url, "_blank").

The following table describes how each of these links behave in a web view.

href target attribute Default WKWebView click behavior
target="_blank" Link not handled by the web view.
target="_top" Reload link in the existing web view.
target="_self" Reload link in the existing web view.
target="_parent" Reload link in the existing web view.
JavaScript function Default WKWebView click behavior
window.open(url, "_blank") Link not handled by the web view.

Follow these steps to optimize the click behavior in your WKWebView instance:

  1. Set the WKUIDelegate on your WKWebView instance.

  2. Set the WKNavigationDelegate on your WKWebView instance.

  3. Determine whether to optimize the behavior of the click URL.

    • Check if the navigationType property on the WKNavigationAction object is a click type you want to optimize. The code example checks for .linkActivated which only applies to clicks on a link with an href attribute.

    • Check the targetFrame property on the WKNavigationAction object. If it returns nil, it means the target of the navigation is a new window. Since WKWebView can't handle that click, these clicks must be handled manually.

  4. Decide whether to open the URL in an external browser, SFSafariViewController, or the existing web view. The code snippet shows how to open URLs navigating away from the site by presenting a SFSafariViewController.

Code example

The following code snippet shows how to optimize the web view click behavior. As an example, it checks if the current domain is different than the target domain. This is just one approach as the criteria you use could vary.

Swift

importGoogleMobileAds
importSafariServices
importWebKit
classViewController:UIViewController,WKNavigationDelegate,WKUIDelegate{
overridefuncviewDidLoad(){
super.viewDidLoad()
// ... Register the WKWebView.
// 1. Set the WKUIDelegate on your WKWebView instance.
webView.uiDelegate=self;
// 2. Set the WKNavigationDelegate on your WKWebView instance.
webView.navigationDelegate=self
}
// Implement the WKUIDelegate method.
funcwebView(
_webView:WKWebView,
createWebViewWithconfiguration:WKWebViewConfiguration,
fornavigationAction:WKNavigationAction,
windowFeatures:WKWindowFeatures)->WKWebView?{
// 3. Determine whether to optimize the behavior of the click URL.
ifdidHandleClickBehavior(
currentURL:webView.url,
navigationAction:navigationAction){
print("URL opened in SFSafariViewController.")
}
returnnil
}
// Implement the WKNavigationDelegate method.
funcwebView(
_webView:WKWebView,
decidePolicyFornavigationAction:WKNavigationAction,
decisionHandler:@escaping(WKNavigationActionPolicy)->Void)
{
// 3. Determine whether to optimize the behavior of the click URL.
ifdidHandleClickBehavior(
currentURL:webView.url,
navigationAction:navigationAction){
returndecisionHandler(.cancel)
}
decisionHandler(.allow)
}
// Implement a helper method to handle click behavior.
funcdidHandleClickBehavior(
currentURL:URL,
navigationAction:WKNavigationAction)->Bool{
guardlettargetURL=navigationAction.request.urlelse{
returnfalse
}
// Handle custom URL schemes such as itms-apps:// by attempting to
// launch the corresponding application.
ifnavigationAction.navigationType==.linkActivated{
ifletscheme=targetURL.scheme,!["http","https"].contains(scheme){
UIApplication.shared.open(targetURL,options:[:],completionHandler:nil)
returntrue
}
}
guardletcurrentDomain=currentURL.host,
lettargetDomain=targetURL.hostelse{
returnfalse
}
// Check if the navigationType is a link with an href attribute or
// if the target of the navigation is a new window.
if(navigationAction.navigationType==.linkActivated||
navigationAction.targetFrame==nil)&&
// If the current domain does not equal the target domain,
// the assumption is the user is navigating away from the site.
currentDomain!=targetDomain{
// 4. Open the URL in a SFSafariViewController.
letsafariViewController=SFSafariViewController(url:targetURL)
present(safariViewController,animated:true)
returntrue
}
returnfalse
}
}

Objective-C

@importGoogleMobileAds;
@importSafariServices;
@importWebKit;
@interface ViewController()<WKNavigationDelegate,WKUIDelegate>
@property(nonatomic,strong)WKWebView*webView;
@end
@implementation ViewController
- (void)viewDidLoad{
[superviewDidLoad];
// ... Register the WKWebView.
// 1. Set the WKUIDelegate on your WKWebView instance.
self.webView.uiDelegate=self;
// 2. Set the WKNavigationDelegate on your WKWebView instance.
self.webView.navigationDelegate=self;
}
// Implement the WKUIDelegate method.
- (WKWebView*)webView:(WKWebView*)webView
createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration
forNavigationAction:(WKNavigationAction*)navigationAction
windowFeatures:(WKWindowFeatures*)windowFeatures{
// 3. Determine whether to optimize the behavior of the click URL.
if([selfdidHandleClickBehaviorForCurrentURL:webView.URL
navigationAction:navigationAction]){
NSLog(@"URL opened in SFSafariViewController.");
}
returnnil;
}
// Implement the WKNavigationDelegate method.
- (void)webView:(WKWebView*)webView
decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction
decisionHandler:
(void(^)(WKNavigationActionPolicy))decisionHandler{
// 3. Determine whether to optimize the behavior of the click URL.
if([selfdidHandleClickBehaviorForCurrentURL:webView.URL
navigationAction:navigationAction]){
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
// Implement a helper method to handle click behavior.
- (BOOL)didHandleClickBehaviorForCurrentURL:(NSURL*)currentURL
navigationAction:(WKNavigationAction*)navigationAction{
NSURL*targetURL=navigationAction.request.URL;
// Handle custom URL schemes such as itms-apps:// by attempting to
// launch the corresponding application.
if(navigationAction.navigationType==WKNavigationTypeLinkActivated){
NSString*scheme=targetURL.scheme;
if(![schemeisEqualToString:@"http"] && ![schemeisEqualToString:@"https"]){
[UIApplication.sharedApplicationopenURL:targetURLoptions:@{}completionHandler:nil];
returnYES;
}
}
NSString*currentDomain=currentURL.host;
NSString*targetDomain=targetURL.host;
if(!currentDomain||!targetDomain){
returnNO;
}
// Check if the navigationType is a link with an href attribute or
// if the target of the navigation is a new window.
if((navigationAction.navigationType==WKNavigationTypeLinkActivated
||!navigationAction.targetFrame)
// If the current domain does not equal the target domain,
// the assumption is the user is navigating away from the site.
 && ![currentDomainisEqualToString:targetDomain]){
// 4. Open the URL in a SFSafariViewController.
SFSafariViewController*safariViewController=
[[SFSafariViewControlleralloc]initWithURL:targetURL];
[selfpresentViewController:safariViewControlleranimated:YES
completion:nil];
returnYES;
}
returnNO;
}

Test your page navigation

To test your page navigation changes, load

https://google.github.io/webview-ads/test/#click-behavior-tests

into your web view. Click each of the different link types to see how they behave in your app.

Here are some things to check:

  • Each link opens the intended URL.
  • When returning to the app, the test page's counter doesn't reset to zero to validate the page state was preserved.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025年12月11日 UTC.