Apple's guideline 4.2 requires apps to offer functionality beyond what a mobile web browser can provide. A root <WebView> loading your website URL — or a tab navigator where every tab is a WebView — provides exactly zero native value and is rejected routinely. Google Play applies the same standard. Beyond rejection: a WebView wrapper offers worse performance than Safari/Chrome, no access to native APIs, broken back-button behavior on Android, and user interfaces that feel foreign on mobile. The rejection is not a technicality — the platforms genuinely won't distribute apps that are just website containers.
High because Apple guideline 4.2 minimum-functionality rejections are applied consistently — any app whose primary content is a WebView loading a URL will be rejected.
Replace WebView-based primary content with native components. Start with the root navigator.
// Before (rejected):
export default function HomeScreen() {
return <WebView source={{ uri: 'https://yoursite.com/home' }} style={{ flex: 1 }} />;
}
// After (native):
export default function HomeScreen() {
const { data } = useHomeData();
return (
<ScrollView>
<FlatList data={data} renderItem={({ item }) => <PostCard post={item} />} />
</ScrollView>
);
}
WebViews are permitted for: OAuth flows, in-app help browser, PDF preview, or one specific screen of third-party external content. Every tab in your tab navigator must render native components as its primary content.
ID: app-store-review-blockers.technical-requirements.not-web-view-wrapper
Severity: high
What to look for: Count all relevant instances and enumerate each. Look at the root navigator and main screens. If the primary content rendering is one or more WebView components loading a URL, this is a web view wrapper. Specifically look for: a root <WebView source={{ uri: 'https://yoursite.com' }} /> as the only content; a tab navigator where every tab is a WebView loading a different URL; WKWebView (iOS) or WebView (Android) as the primary rendering mechanism. Also check for expo-web-browser being used as the app's main content (not just for OAuth or help links). In Flutter, look for WebViewWidget or InAppWebView as the root widget. Contrast this with legitimate uses of WebView for: an in-app browser for help docs, OAuth authentication, showing a specific piece of external content.
Pass criteria: The app's primary content and navigation are rendered using native components (React Native components, Flutter widgets, SwiftUI views, Jetpack Compose composables). At least 1 implementation must be verified. WebView usage is limited to specific, justified uses (OAuth, in-app browser for external content).
Fail criteria: The app's core content is entirely or primarily rendered by a WebView loading a website URL, with no meaningful native navigation or functionality.
Skip (N/A) when: Never — all apps must provide meaningful native functionality.
Detail on fail: "App's main screen is a single WebView loading 'https://yoursite.com' — the app is a web view wrapper" or "All 4 tab bar screens render WebView components pointing to website URLs"
Remediation: Apple guideline 4.2 requires apps to provide functionality beyond what a mobile web browser can offer. Google Play similarly rejects pure web view wrappers.
Review the configuration in src/ or app/ directory for implementation patterns.