# Adopting the iOS 26 WebView Safely with a Router
Table of Contents
Readeck is a reader. You save a link, it strips the page down to clean HTML, no ads, no cookie banners, no newsletter popup begging for your email, just text and images. And in a reader the article view is not a screen in the app, it is the app. If reading feels off, the whole thing feels off.
iOS 26 ships a native SwiftUI WebView, and I wanted it in that heart of the app immediately.
Trouble is, dropping a brand new .0 API on every user on day one is how you end up reading crash reports instead of articles.
There is always a RouterLink to heading
So I did not replace anything. I put a fork in the road:
struct ArticleReaderRouter: View { let bookmarkId: String
var body: some View { if #available(iOS 26.0, *) { ArticleReaderView(bookmarkId: bookmarkId) // new native SwiftUI WebView } else { ArticleReaderLegacyView(bookmarkId: bookmarkId) // proven WKWebView } }}That is it. The reader is no longer one view, it is whichever view fits the device you are holding.
Why bother with a fallback?Link to heading
Because this keeps both worlds alive at the same time.
New devices get the new renderer, which users tell me feels faster and smoother on long articles, and which collects the fewest bug reports on GitHub.
Fair warning: that is user feedback and issue counts talking, not benchmarks, so season it to taste.
Everyone on older iOS keeps the WKWebView reader that has carried the app for years.
It also quietly solves a problem I did not want to spend my life on. A handful of users on older iOS versions reported small rendering quirks in the old reader. I chose not to chase those fixes, and I sleep fine about it, because iOS 26 makes that entire code path obsolete over time. Polishing something you are actively walking away from is just a slow way to waste an afternoon.
Bonus: let the user cherry-pickLink to heading
Confidence is nice, but the native WebView is still young, and young code surprises you.
So on iOS 26 the user gets to cherry-pick their reader, no git required, and fall back to the old one if the new one misbehaves:
@AppStorage("useNativeWebView") private var useNativeWebView = true
// inside the iOS 26 branch:useNativeWebView ? ArticleReaderView(bookmarkId: bookmarkId) : ArticleReaderLegacyView(bookmarkId: bookmarkId)Most people will never touch it, and that is the point. It is a seatbelt, not a feature. If the shiny new reader ever acts up, the boring one that always worked is one tap away.