Skip to content

fix(windows): explicit CoreWebView2 environment + surface init failure to JS - #3981

Open
FaithfulAudio wants to merge 1 commit into
react-native-webview:masterfrom
FacilitronWorks:wv1-webview2-environment-init-error
Open

FaithfulAudio wants to merge 1 commit into
react-native-webview:masterfrom
FacilitronWorks:wv1-webview2-environment-init-error

Conversation

@FaithfulAudio

Copy link
Copy Markdown

Part of the hardening series offered in #3980. This is WV-1: explicit CoreWebView2 environment + surfacing init failure to JS.

Problem

InitializeContentIsland calls m_webView.EnsureCoreWebView2Async(); with no explicit environment and no failure handling. Two consequences:

  • The default user-data folder is created next to the executable. A packaged app's install directory (Program Files\WindowsApps\...) is read-only, so this can fail to create there.
  • On a machine without the WebView2 Evergreen Runtime installed (stripped/managed images, some Server SKUs), CoreWebView2 creation fails and the view just stays permanently blank — nothing is surfaced to JS, OnCoreWebView2Initialized's early-return (if (!m_webView || !m_webView.CoreWebView2()) return;) silently swallows it.

Real-world failure mode

An app ships fine in dev/CI (Evergreen Runtime present) but a <WebView> silently renders nothing on a subset of user machines or locked-down corporate images — with no error event to build a fallback UI or diagnostics around, and no way to distinguish "runtime missing" from "still loading" from JS.

Fix

  • InitializeCoreWebView2Async() creates the environment explicitly via CoreWebView2Environment::CreateWithOptionsAsync(L"", <writable user-data folder>, nullptr), using ApplicationData.LocalFolder (falling back to %TEMP% for unpackaged/dev builds) instead of the default next-to-exe folder.
  • OnCoreWebView2Initialized now checks args.Exception() and emits onLoadingError with the failing HRESULT if set.
  • The catch around environment creation covers the case where the Runtime is missing entirely (that failure never reaches CoreWebView2Initialized, because EnsureCoreWebView2Async is never called).

Questions for maintainers

  • User-data-folder policy: is a fixed ApplicationData.LocalFolder subfolder (what this PR does) the right default, or would you rather see a prop/static setter so apps can share a profile with their own WebView2 environments?
  • We deliberately did not add a retry-after-failure mechanism (re-attempting EnsureCoreWebView2Async on a later prop change) to keep this diff focused — happy to add it as a follow-up if useful.

Validation status

Not compiled against this repo. No Windows build was run this pass (no bun run windows / MSBuild) — verified by hand, side-by-side against RCTWebView2ComponentView.cpp, not by building. The CoreWebView2InitializedEventArgs.Exception() API surface in particular needs your Windows CI to confirm.

The explicit-environment + init-error pattern is production-proven in a parallel, independently-built Windows new-arch WebView2 Fabric component running in Facilitron FIT (react-native-windows 0.83.2, WinAppSDK 1.8, ARM64) — see the production twin: FacilitronWorks/react-native-webview-windows. Renamed symbols, hand-ported to this repo's codegen/class shape — not a copy-paste.

Related: #3980

…e to JS

EnsureCoreWebView2Async() was called with no explicit environment and no
failure handling. Two consequences in production:

- The default user-data folder is created next to the executable, which is
  read-only for a packaged app's install directory.
- On a machine without the WebView2 Evergreen Runtime installed (stripped
  or managed images, some Server SKUs), CoreWebView2 creation fails and the
  WebView just stays permanently blank -- nothing is surfaced to JS.

This creates the environment explicitly with a writable, packaged-safe
user-data folder (ApplicationData.LocalFolder, falling back to %TEMP% for
unpackaged/dev builds), and emits onLoadingError with the failing HRESULT
from both failure points: CoreWebView2Environment::CreateWithOptionsAsync
throwing directly (Runtime entirely missing), and
CoreWebView2InitializedEventArgs.Exception() being set (failure after an
environment was created).

Validation: this is the same environment-creation + failure-surfacing
pattern running in production in a parallel Windows new-arch WebView2
Fabric component (Facilitron FIT, react-native-windows 0.83.2) -- see
FacilitronWorks/react-native-webview-windows. Not compiled against this
repo in this change; needs CI here to validate the exact WinUI3 API
surface (CoreWebView2InitializedEventArgs.Exception() in particular).
@FaithfulAudio

Copy link
Copy Markdown
Author

Friendly bump — this has been open for a while without a decision. Is there anything you need from me to move it along (rebase onto current main, splitting it, extra tests)? Happy to update it either way.

This branch has not been deployed

No deployments
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