Do it yourself
$109 per platform, one-time
The WebViewGold license: a finished Xcode or Android Studio project. Paste your URL, set name and icon, switch on features, build and submit. Free updates forever.
See plans on the main pageChatGPT & Codex
Guideline 4.0 rejections and one-star reviews often come from the same few pixels: a header under the notch, a tab bar behind the home indicator, a tiny close button, an input that zooms the page when tapped. Codex can find most of these in your code and prove the fixes in a headless browser, while a few WebViewGold settings decide who owns the safe area. Here is the audit as a repeatable workflow.
From $109 one-time per platform, or let our team do it all from $698.
App Review installs the build on current hardware, often an iPhone with a Dynamic Island and also an iPad, because WebViewGold apps run on iPad unless you restrict them (iPad support for web-wrapped apps). The reviewer taps through the main flows with a thumb, not a mouse. Anything hidden under the status bar, a button that needs three tries, a form that zooms in and stays zoomed, or a page that scrolls sideways reads as "this is a website", and the rejection usually cites Guideline 4.0 Design or 2.1 (the 4.0 rejection explained). Google files the same problems under broken functionality.
The goal of the audit is boring on purpose: nothing overlaps system UI, every control is comfortably tappable, no page scrolls horizontally at 320 pixels, inputs do not trigger focus zoom, and the status bar matches your header in light and dark mode.
| Setup | WebViewGold settings | Your CSS | Good for |
|---|---|---|---|
| WebViewGold keeps content inside the safe area (default) | iOS: autoAdjustSafeAreaInsets stays true; color the bars with statusBarBackgroundColor and, for the home indicator area, bottombar with bottombarBackgroundColor (dark mode variants exist). Android: TRANSPARENT_STATUS_BAR false, bar color from colorPrimaryDark in style.xml | No inset padding; make sure no component adds its own notch spacer | Most apps, least work |
| Your web app draws edge to edge | iOS: transparentStatusBar true and autoAdjustSafeAreaInsets false. Android: TRANSPARENT_STATUS_BAR true, blackStatusBarText to match your header | viewport-fit=cover plus env(safe-area-inset-top) and env(safe-area-inset-bottom) on fixed headers, tab bars and sheets; test Android on a device | Full-bleed headers, maps, media |
| Native tab bar | iOS: showNavFooter with FooterBar.json. Android: ENABLE_NAVIGATION_FOOTER with res/menu/menu_drawer.xml | Hide your own web tab bar when isNativeApp() is true, or users see two | Apps with three to five top-level sections |
codex exec runs Codex without the interactive interface; --sandbox read-only means it can read every file but change none, and -o saves its final answer to a file. Run it from the repository root. The second command is optional and shows Codex what the device shows: -i attaches screenshots to the prompt.
# Pass 1: Codex reads, changes nothing, and the CLI saves the report.
codex exec --sandbox read-only -o ui-audit.md "Read AGENTS.md. This web app runs inside
native iOS and Android WebViews (WebViewGold). Audit every route and shared layout
component and REPORT ONLY, do not edit. For each finding: file:line, severity
(blocker, major, minor), what breaks on a phone, and the smallest fix. Check:
- viewport meta: width=device-width, initial-scale=1, viewport-fit=cover
- fixed or sticky elements at the top or bottom edge and how they handle safe areas
- interactive elements smaller than 44x44 CSS px, or closer than 8px to each other
- input, select and textarea font size under 16px (iOS focus zoom)
- hover-only menus, tooltips and actions
- 100vh layouts, horizontal overflow below 360px width, fixed pixel widths
- modals and sheets without a visible close button
End with a summary table by severity."
# Optional: attach device screenshots from TestFlight or internal testing
codex --sandbox workspace-write -i iphone-home.png,ipad-settings.png "These screenshots
are from the TestFlight build. Add everything visible here that ui-audit.md misses."
Great way of converting your web app to a native app! Fast turn-around, and a great way to get your apps into the app stores without the need to develop a full native app!
Reading code finds most problems; a browser proves the fixes. The fix prompt below asks Codex to add this test, and it is worth keeping in CI. It is strict on purpose: expect a few false positives, such as inline text links or checkboxes, and let Codex add them to the reviewed allowlist rather than loosening the thresholds.
// tests/mobile-ui.spec.js (run: npx playwright test tests/mobile-ui.spec.js)
import { test, expect } from "@playwright/test";
const ROUTES = ["/", "/login", "/settings", "/projects/demo"];
const WIDTHS = [320, 375, 430, 768]; // small phone, phone, large phone, iPad portrait
const ALLOW = ["a.inline-link", "input[type=checkbox]"]; // reviewed exceptions
for (const width of WIDTHS) {
for (const route of ROUTES) {
test(route + " at " + width + "px", async ({ page }) => {
await page.setViewportSize({ width, height: 860 });
await page.goto(route);
// 1. No sideways scrolling
const overflow = await page.evaluate(
() => document.documentElement.scrollWidth - window.innerWidth);
expect(overflow, "horizontal overflow in px").toBeLessThanOrEqual(0);
// 2. Tap targets of at least 44 x 44 CSS px
const small = await page.$$eval("a, button, [role=button], [role=tab], select",
(els, allow) => els
.filter((el) => !allow.some((sel) => el.matches(sel)))
.filter((el) => { const r = el.getBoundingClientRect();
return r.width > 0 && (r.width < 44 || r.height < 44); })
.map((el) => (el.getAttribute("aria-label") || el.textContent || el.tagName)
.trim().slice(0, 40)),
ALLOW);
expect(small, "tap targets under 44px").toEqual([]);
// 3. No iOS focus zoom: form fields at 16px or more
const tiny = await page.$$eval("input, select, textarea",
(els) => els.filter((el) => parseFloat(getComputedStyle(el).fontSize) < 16).length);
expect(tiny, "form fields under 16px").toBe(0);
});
}
}Start an interactive session with codex --sandbox workspace-write --ask-for-approval on-request. Installing Playwright and its browser needs network access, so Codex asks for approval at that step; approve it or install Playwright yourself first. Keep option A or B from the table and delete the other.
Read AGENTS.md and ui-audit.md. Fix every blocker and major finding with the smallest change that works. Do not redesign, rename components or change colors unless a finding requires it. Safe areas (keep one option, delete the other): A) WebViewGold keeps content inside the safe area (autoAdjustSafeAreaInsets stays true in Config.swift). Do not add safe-area padding; remove any notch spacer components instead. B) We draw edge to edge (transparentStatusBar = true and autoAdjustSafeAreaInsets = false in Config.swift, TRANSPARENT_STATUS_BAR = true in Config.java). Add viewport-fit=cover and give fixed headers, tab bars and bottom sheets padding of max(their normal padding, env(safe-area-inset-top)) or env(safe-area-inset-bottom). Rules: - Interactive elements at least 44x44 CSS px. Enlarge the hit area with padding or a ::before pseudo-element; do not scale icons. Keep 8px between neighbors. - input, select and textarea at 16px or more. Never add maximum-scale or user-scalable=no. - Replace 100vh with 100dvh and keep a 100vh line before it as a fallback. - Hover-only interactions get a tap equivalent. - If the app has light and dark themes: when the theme changes and isNativeApp() is true, navigate to statusbarcolor://R,G,B with the header color so the native status bar follows. - If we enable WebViewGold's native tab bar (showNavFooter on iOS, ENABLE_NAVIGATION_FOOTER on Android), hide our web tab bar when isNativeApp() is true. Then add Playwright (ask before installing), a playwright.config with baseURL pointing to npm run dev, and tests/mobile-ui.spec.js that checks horizontal overflow, tap targets and form font size on [list your main routes] at 320, 375, 430 and 768 px. Run it until it passes. Finally update ui-audit.md with three lists: fixed, deliberately not fixed (and why), needs a device check.
Choose a row from the table and set it in the WebViewGold projects (the iOS safe area docs cover the bottom bar). Decide this first, because every CSS fix depends on it.
Pass 1 produces ui-audit.md with file, line, severity and the proposed fix for each finding. Nothing in the repository changes.
Delete findings you disagree with and mark deliberate design decisions. Ten minutes here keeps Codex from "fixing" your brand.
Paste the fix prompt, then /review and git diff. The Playwright test must be green before you deploy.
TestFlight on a notched iPhone and an iPad, internal testing on a small Android phone with gesture navigation and a large system font. Screenshot anything odd and hand it back with codex -i. The free App Store readiness check catches the URL-level basics.
Leave the Playwright test in CI and add a review rule for new small tap targets to AGENTS.md, so Codex code review flags regressions on future pull requests.
statusbarcolor://R,G,B (or statusbartextcolor://white / black) so the bar follows (Dynamic UI API).INPUT_SCROLL_HELPER can help).MAX_TEXT_ZOOM if a layout cannot stretch.preventoverscroll on iOS removes the rubber band, pulltorefresh needs it off, Android uses ENABLE_PULL_REFRESH.EXIT_APP_BY_BACK_BUTTON_HOMEPAGE, EXIT_APP_DIALOG).maximum-scale=1 or user-scalable=no. It also blocks pinch zoom for people who need it; fix the font size instead. WebViewGold offers preventZoom on iOS, but think twice before using it.100vh full-screen layouts that end up taller than the visible area. Use 100dvh with 100vh as the fallback.Apple's Human Interface Guidelines recommend at least 44 by 44 points, Material Design recommends 48 by 48 dp, and WCAG 2.2 sets 24 by 24 CSS pixels as the minimum. Reviewers do not measure, but they notice controls that need several tries. Aim for 44 on iOS and 48 on Android.
It reads your code, and it can look at images you attach: start Codex with -i and a screenshot from TestFlight or an Android device, and ask it to compare the screenshot with the code. That combination finds problems neither catches alone.
Only if your web app draws edge to edge, with a transparent status bar and WebViewGold's safe-area adjustment turned off. With the default handling, the page already sits inside the safe area; just check on a notched device that no component adds a second spacer.
iOS zooms into form fields with a font size under 16 CSS pixels. Set inputs, selects and textareas to 16px or more and the zoom disappears without disabling pinch zoom.
The Playwright test should; it is cheap. The read-only Codex audit is worth repeating before each store submission or after a larger redesign, and a review rule in AGENTS.md lets Codex code review flag new problems in between.
Same result, different amount of work on your side. All three come with the approval guarantee and 24/7 human support.
$109 per platform, one-time
The WebViewGold license: a finished Xcode or Android Studio project. Paste your URL, set name and icon, switch on features, build and submit. Free updates forever.
See plans on the main page$349 per license, one-time add-on
No Mac, no Xcode, no Android Studio: configure in the browser, we build both apps in the cloud and hand them to App Store Connect and the Play Console.
How the Cloud Builder works Try the free demo$698 per platform $798
Send us your URL and icon. Our team configures, builds and delivers your app within 72 hours, white-label, with source projects. Both platforms for $1,158.
Full Service details Powered byWinter Sale prices valid until December 31, 2026.
App Store & Google Play approval guarantee – or your money back within 14 days
Rather hand it over? Full Service: we configure, build and deliver within 72 hours, from $698 per platform. Questions? Chat with us 24/7.
Refunds are granted under the conditions listed in our FAQ: a non-content rejection by Apple and/or Google, claimed within 14 days after purchase.