A link or window.open inside a WebView does not open a new tab — it does nothing, silently. On Android the default is setSupportMultipleWindows(false), which ignores every request to open a new window; to make it work the app must enable multiple windows and implement onCreateWindow and onCloseWindow, and most never do. On iOS, WKWebView's createWebViewWithConfiguration delegate returns nil by default, so target=_blank is silently dropped unless the app implements WKUIDelegate — and when developers do, they often spawn a second WebView whose back and forward history is disconnected from the first. A host-owned runtime ships one window manager that maps popups to in-app tabs or a consistent external handoff, keeps navigation history intact, and never lets a link die silently.
Android: new windows ignored by default
The Android docs are blunt: by default the system ignores requests to open new windows, whether via JavaScript or a target attribute. To honor target=_blank the app must call setSupportMultipleWindows(true) and override onCreateWindow (and onCloseWindow to clean up). Skip the flag and onCreateWindow is never called — the tap produces no navigation, no error, nothing. The practical result across the app ecosystem is a long tail of dead "open in new tab" links that work in a real browser and vanish in the WebView.
iOS: the delegate that returns nil
WKWebView has no built-in tab or window model; when a page asks for a new browsing context it asks the app through WKUIDelegate.createWebViewWithConfiguration. The default implementation returns nil, which means target=_blank and window.open are silently discarded. Developers must set the uiDelegate and implement the method; the common workaround loads the request back into the same view (losing the intended new-tab semantics) or creates a brand-new WKWebView — whose back and forward stack is separate from the original, so the user gets stuck with no way back.
What you lose without a window manager
- Dead links with no feedback. target=_blank taps do nothing, so users assume the page is broken.
- Broken history. A second WebView has its own back/forward stack, disconnecting the user from where they came from.
- No consistent external-link policy. Some links should stay in-app, some should hand off to the system browser; a stock WebView has no rule.
- Lost session context. A popup that should inherit login or cart state instead starts cold in a separate context.
- Silent divergence. The same HTML opens a real tab in Safari and does nothing in the embedded view.
The runtime fix
A host-owned runtime ships one window manager below the page. It maps every new-window request to a predictable outcome — an in-app tab that shares the navigation history and session, or a clearly-labeled external handoff to the system browser — and it never swallows a link silently. The page author writes standard target=_blank, and the runtime decides, consistently and per policy, what happens next, on both platforms.
| Dimension | WebView | Host-owned runtime |
|---|---|---|
| New window default | Ignored (Android) / nil delegate (iOS) | Mapped to in-app tab or handoff |
| Android flag | setSupportMultipleWindows + onCreateWindow | Handled by the runtime |
| iOS path | WKUIDelegate.createWebViewWithConfiguration | Handled by the runtime |
| Navigation history | Broken across a second view | Shared, intact |
| External-link policy | None, per-app guesswork | Consistent, configurable |
| Silent dead links | Common | Never |
A browser treats target=_blank as a promise: a new, reachable context. A stock WebView treats it as a request it is free to ignore. A runtime restores the promise — one window manager, intact history, and a link that always goes somewhere the user can see.
Sources
- Android Developers — WebView 'Managing windows': new-window requests ignored by default; needs setSupportMultipleWindows + onCreateWindow — the default that drops popups.
- Stack Overflow — onCreateWindow not called unless setSupportMultipleWindows(true) — the missing flag that kills the link.
- Apple Developer — WKUIDelegate createWebViewWithConfiguration: default nil drops target=_blank — the silent iOS path.
- Filip Němeček — How to open target=_blank links in WKWebView in iOS — why the links do nothing and the delegate fix.
- MDN — target=_blank attribute reference — the web standard the WebView silently violates.