fix(connect): stop components hanging on double quotes in init params by guido-stripe · Pull Request #2758 · stripe/stripe-react-native · GitHub
Skip to content

fix(connect): stop components hanging on double quotes in init params - #2758

Merged
guido-stripe merged 3 commits into
masterfrom
fix/connect-injected-object-escaping
Oct 21, 2026
Merged

guido-stripe merged 3 commits into
masterfrom
fix/connect-injected-object-escaping

Conversation

@guido-stripe

Copy link
Copy Markdown
Contributor

Summary

Fixes Connect embedded components loading forever, without calling onLoadError, when an init param (appearance, locale, fonts, or a component prop) contains a double quote, backslash, or backtick. An ordinary CSS font stack is enough to trigger it, e.g. fontFamily: '"Courier New", Courier, monospace'.

EmbeddedComponent now also passes the init params in injectedJavaScriptBeforeContentLoaded. That script defines window.ReactNativeWebView.injectedObjectJson() as a read-only property that returns the JSON from a JS string literal, so react-native-webview's own definition can't replace it. injectedJavaScriptObject is still passed, because react-native-webview 13.6.0–13.13.0 on Android serves injectedObjectJson() from a Java method instead.

This is based on #2680 by @BhodiSea, who found the root cause, wrote the fix and tests, and filed #2681. Their commit is kept as is, with their authorship. On top of it, this PR rebases onto master, drops the U+2028/U+2029 escaping (only needed for pre-ES2019 engines, which the SDK doesn't support), documents the double JSON.stringify, and moves the changelog entry to Unreleased.

Closes #2681

Motivation

react-native-webview embeds the injectedJavaScriptObject JSON in a JS template literal. It does this on iOS, and on Android from 13.13.1. The template literal turns \" into " and \\ into \, so the Connect page's startup JSON.parse throws and the page never reports load success or failure. Upstream: react-native-webview/react-native-webview#3957 (iOS) and react-native-webview/react-native-webview#3942 (Android). Their fixes (react-native-webview/react-native-webview#3958 and react-native-webview/react-native-webview#3929) are still open. Since our react-native-webview peer dependency is *, an upstream fix would only reach apps that upgrade.

Testing

  • I tested this manually
  • I added automated tests

Manual: example-stripe-connect, Retro preset with fontFamily: '"Courier New", Courier, monospace', Account onboarding → Show Onboarding.

Before After
iOS ios_before ios_after
Android android_before android_after

Automated: injectedObjectScript.test.ts runs the script in a Node vm context. It checks that quoted, backslash, newline, backtick, ${…}, U+2028/U+2029 and non-ASCII values round-trip exactly, and that the value survives react-native-webview's iOS and Android definitions running before or after it. EmbeddedComponent.test.tsx checks that the script carries the same init params as injectedJavaScriptObject; both of its new tests fail on master.

Documentation

Select one:

  • I have added relevant documentation for my changes.
  • This PR does not result in any developer-facing changes.

Added a CHANGELOG entry under Unreleased → Fixes.

@guido-stripe
guido-stripe requested review from a team as code owners October 20, 2026 16:49
BhodiSea and others added 3 commits October 21, 2026 10:32
react-native-webview's injectedJavaScriptObject embeds the JSON in a JS
template literal (iOS; Android from 13.13.1), so a double quote,
backslash, newline, or backtick in any init param stops the Connect page
from starting: the component never leaves its loader and never calls
onLoadError. A double-quoted family name in
appearance.variables.fontFamily is enough.

Also pass the init params as an injectedJavaScriptBeforeContentLoaded
script, replacing the empty placeholder. It defines
window.ReactNativeWebView.injectedObjectJson() read-only, with the JSON
in a string literal, so react-native-webview's definition can't replace
it. Keep injectedJavaScriptObject: on Android, react-native-webview
13.6.0-13.13.0 serves it from a Java method that page scripts can't
override and that never had this bug.
…cript

The escaping only mattered for pre-ES2019 engines, which the SDK's minimum
iOS and Android WebView versions don't include. Also document why the init
params are stringified twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Committed-By-Agent: claude
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Committed-By-Agent: claude
@guido-stripe
guido-stripe force-pushed the fix/connect-injected-object-escaping branch from a7a1bbc to f90a600 Compare October 21, 2026 08:32
@BhodiSea

Copy link
Copy Markdown
Contributor

@guido-stripe
guido-stripe merged commit 674f9c6 into master Oct 21, 2026
10 checks passed
@guido-stripe
guido-stripe deleted the fix/connect-injected-object-escaping branch October 21, 2026 14: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.

Connect embedded components never finish loading when fontFamily (or any init param) contains a double quote.

3 participants