# App is not merely a web view wrapper around a website

- **Pattern:** `ab-000507` (`app-store-review-blockers.technical-requirements.not-web-view-wrapper`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000507
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000507)

## Why it matters

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.

## Severity rationale

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.

## Remediation

Replace WebView-based primary content with native components. Start with the root navigator.

```tsx
// 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.

## Detection

- **ID:** `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.
  1. Migrate primary content to native components:
     - React Native: Replace WebView with native FlatList, ScrollView, and custom components
     - Flutter: Use native Material/Cupertino widgets instead of WebView
     - Swift/Kotlin: Use native UIKit/SwiftUI or Jetpack Compose
  2. WebViews are permitted for: OAuth, in-app help browser, previewing external documents, one specific screen of external content
  3. At minimum, the app must have a meaningful native shell (navigation, authentication, state management) even if some content is web-based

  Review the configuration in `src/` or `app/` directory for implementation patterns.

## External references

- external apple-guideline-4.2-minimum-functionality — https://developer.apple.com/app-store/review/guidelines/#minimum-functionality

Taxons: regulatory-conformance, user-experience

HTML version: https://auditbuffet.com/patterns/ab-000507
