fix: make in-app webview back button tappable on iOS#29693
Conversation
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1f9720f. Configure here.
| () => ({ | ||
| __esModule: true, | ||
| default: jest.fn(() => ({ | ||
| header: () => null, |
There was a problem hiding this comment.
Test missing mock for useTailwind dependency
Medium Severity
The component now calls useTailwind() from @metamask/design-system-twrnc-preset, but the test file never mocks this module. There is no global mock for it in testSetup.js or app/__mocks__/. Every other test file in the codebase that renders components using useTailwind adds an explicit jest.mock('@metamask/design-system-twrnc-preset', () => ({ useTailwind: () => ({ style: () => ({}) }) })). Without this mock, the test will crash when useTailwind() is invoked without a provider context.
Reviewed by Cursor Bugbot for commit 1f9720f. Configure here.
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
Risk: The SimpleWebview is used across many features as a fallback browser for external links. The header change could affect:
Affected areas by feature:
The change is relatively contained (UI refactor, not logic change) but touches a widely-used shared component, warranting medium risk and broad coverage. Performance Test Selection: |
|





Description
After the React Navigation v5 → v6 migration (#26691) and the follow-up iOS overlap fix (#29020), the back arrow in the in-app
SimpleWebview(used e.g. when tapping "View on block explorer" after a swap) renders behind the iOS status bar / Dynamic Island and is unclickable, leaving the user trapped on the screen.Root cause:
SimpleWebviewwas injecting its header throughnavigation.setOptions({ header: () => <HeaderCompactStandard …/> }).@react-navigation/stackv6, customheaderfunctions do not receive automaticpaddingTop: headerStatusBarHeight(seenode_modules/@react-navigation/stack/src/views/Header/HeaderContainer.tsx); the custom header must own its safe-area inset.includesTopInset: Device.isAndroid(), which on iOS resulted in no top safe-area inset at all, so the back button rendered aty = 0underneath the status bar.Solution (matches the pattern already used by
WebviewModal.tsxin Deposit):HeaderCompactStandarddirectly insideSimpleWebviewwithincludesTopInsetalways on, souseSafeAreaInsets()(already used byHeaderBase) drives the top padding consistently on both platforms.Stack.Navigatorheaders in both webview wrappers (MainNavigator.jsandApp.tsx) viascreenOptions={{ headerShown: false }}so we don't double-render headers.setOptionscustom-header wiring; this also removes the need for theDevice.isAndroid()platform branch and therounded-t-2xlstyling that was masking the issue.The navigation contract used by callers (
navigation.navigate(Routes.WEBVIEW.MAIN, { screen: Routes.WEBVIEW.SIMPLE, params: { url } })) is unchanged, soBridgeTransactionDetails,BlockExplorersModal, and other consumers keep working as-is.Longer-term, the team has discussed routing all external links through a single service that selects between WebView and
inAppReborn(Pedro / Joao in the originating Slack thread); that refactor is intentionally out of scope here — this PR just unblocks the user.Changelog
CHANGELOG entry: Fixed an iOS bug where the back button in the in-app webview (e.g. "View on block explorer") was rendered behind the status bar and could not be tapped.
Related issues
Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-572
bug surfaced in the
#metamask-core-mobile-uxSlack thread on 2026-04-28 (browser back button unclickable after swap → "View on block explorer")Manual testing steps
```gherkin
Feature: In-app webview back button is reachable on iOS
Scenario: User exits the in-app webview opened from a swap transaction
Given the user has completed a swap on iOS
And the user is on the swap transaction details screen
Scenario: Header still renders correctly on Android
Given the user is on Android
When the user opens any flow that pushes Routes.WEBVIEW.MAIN / Routes.WEBVIEW.SIMPLE
Then the header is rendered with the correct top safe-area inset
And the share button on the right works
And the back button on the left works
Scenario: Header still renders correctly when the webview is presented as a modal during onboarding
Given the user is in the onboarding flow on iOS
When a screen pushes Routes.WEBVIEW.MAIN (modal presentation)
Then the in-app webview opens with the header below the status bar
And the back arrow is tappable and returns to the onboarding screen
```
Screenshots/Recordings
Screen.Recording.2026-05-04.at.23.18.02.mov
Before
iOS: back arrow rendered behind the status bar / Dynamic Island and not tappable — user is trapped on the webview screen (see Slack screenshot from Heyse Li, 2026-04-28).
After
iOS: header renders below the status bar with proper safe-area inset; back arrow is fully visible and tappable.
Pre-merge author checklist
Performance checks (if applicable)
For performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist
Made with Cursor
Note
Low Risk
Low risk UI/navigation change that primarily adjusts header rendering for
SimpleWebview; main risk is unintended header/spacing differences or missing headers in the webview stacks.Overview
Fixes an iOS layout regression where the in-app
SimpleWebviewback button could be obscured by the status bar/Dynamic Island by renderingHeaderCompactStandarddirectly insideSimpleWebview(alwaysincludesTopInset) instead of injecting a custom header vianavigation.setOptions().Updates the webview stack wrappers in
MainNavigatorandAppto hide the React Navigation header (screenOptions={{ headerShown: false }}) to avoid double headers, and adjusts tests to validate the new header rendering and callbacks (back + share).Reviewed by Cursor Bugbot for commit 972444a. Bugbot is set up for automated code reviews on this repo. Configure here.