Skip to content

feat: add additionalMessageHandlers prop to iOS WebView - #80

Merged
meltingice1337 merged 3 commits into
mainfrom
feat/TRAM-4019
Sep 15, 2026
Merged

meltingice1337 merged 3 commits into
mainfrom
feat/TRAM-4019

Conversation

@meltingice1337

@meltingice1337 meltingice1337 commented Sep 14, 2026

Copy link
Copy Markdown

Description

Adds an iOS-only additionalMessageHandlerNames prop that registers extra native WKScriptMessageHandler names alongside the built-in ReactNativeWebView handler. A page can call window.webkit.messageHandlers.<name>.postMessage(...) and the message is delivered to onMessage exactly like a ReactNativeWebView message.

The motivating case is enableApplePay, which strips every injected user script and therefore breaks the usual window.ReactNativeWebView.postMessage bridge. Third-party checkout pages (for example Coinbase Onramp posting to cbOnramp) can still reach the app through a native handler, so this prop keeps messaging working in Apple Pay mode without any injected JavaScript.

Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-4019

Changes

  • New additionalMessageHandlerNames?: string[] prop on IOSWebViewProps and the Fabric native component spec, with a JSDoc description.
  • RNCWebViewImpl stores the names, registers a RNCWeakScriptMessageDelegate for each one in resetupScripts (both the Apple Pay path and the normal path), and removes them on teardown and whenever the prop changes.
  • userContentController:didReceiveScriptMessage: now accepts messages from any registered additional handler. Non-string bodies are JSON-serialized so event.nativeEvent.data is always a string, matching existing behavior.
  • The built-in ReactNativeWebView name is skipped if passed, so it cannot be double-registered or accidentally removed.
  • Fabric (RNCWebView.mm) and Paper (RNCWebViewManager.mm) prop plumbing.
  • Docs added to docs/Reference.md, entry added to the Unreleased section of CHANGELOG.md.
  • New AdditionalMessageHandlers example screen in the example app, reachable from a MessageHandlers button on iOS.

Testing

  • Run the example app on iOS and open the MessageHandlers screen. The page posts to a custom handler name with enableApplePay on, and the message should appear via onMessage.
  • Verify the existing Messaging and ApplePay examples still behave as before.
  • Confirm no handler leaks by navigating away from the screen and back (no WKScriptMessageHandler duplicate-name exception).

Notes

  • iOS only. Android ignores the prop.
  • Only main-frame messages are delivered, consistent with the existing ReactNativeWebView handler.
  • Handlers are registered when the WebView is created, so pass the prop on mount.

Note

Medium Risk
Changes iOS WebView script message routing used with Apple Pay and third-party checkout pages; behavior is additive but affects payment-adjacent messaging paths.

Overview
Adds an iOS-only additionalMessageHandlerNames prop so apps can register extra native WKScriptMessageHandler names (e.g. third-party checkout handlers like cbOnramp) that deliver to onMessage the same way as ReactNativeWebView.

Native code registers and tears down these handlers in resetupScripts, including when enableApplePay is on and injected messaging scripts are not used. Messages from registered names are accepted alongside the default handler; non-string postMessage bodies are JSON-serialized so event.nativeEvent.data stays a string, and only main-frame posts are forwarded (unchanged policy). Prop updates re-register handlers to avoid duplicate handler crashes.

TypeScript/Fabric/Paper wiring, Reference.md and CHANGELOG, plus an example MessageHandlers screen with enableApplePay are included. Android exposes a no-op stub only.

Reviewed by Cursor Bugbot for commit 2aaacb1. Bugbot is set up for automated code reviews on this repo. Configure here.

@joaoloureirop joaoloureirop left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this — the approach looks right for Apple Pay / third-party checkout, and the docs + example make the intent easy to follow. CI looking green after the main merge is great.

One optional hardening note, nothing blocking for the cbOnramp path.

addAdditionalMessageHandlers only skips ReactNativeWebView. Names that are already on the config (ReactNativeHistoryShim, base64Handler) or duplicate entries in the array would make addScriptMessageHandler:name: throw. Unlikely if the app always passes a single known name like cbOnramp, but if this stays a public prop it might be worth uniquing the list, dropping empties, and skipping reserved names. remove is already safe for missing names.

A couple of small nits if you feel like tidying:

  • PR title says additionalMessageHandlers; the prop is additionalMessageHandlerNames
  • Docs say handlers are registered on mount, but the setter + resetupScripts already supports updates
  • Changelog could use past participle (Added …) for Keep a Changelog consistency

When this lands in Ramp checkout, validating event.nativeEvent.url (and the payload) before treating it as Coinbase would be a good follow-up — same trust model as ReactNativeWebView.

@meltingice1337
meltingice1337 merged commit 97034ce into main Sep 15, 2026
11 checks passed
@meltingice1337
meltingice1337 deleted the feat/TRAM-4019 branch September 15, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants