question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Inconsistent onNavigationStateChange behaviour between iOS and Android for SPAs

See original GitHub issue

Bug description: When navigating on an SPA that modifies the URL (history) without making any request, iOS will trigger the onNavigationStateChange event and Android will not.

Investigating the cause of this it seems that the iOS implementation deliberately injects JavaScript with a history shim using the pushState API. This posts back messages that are intercepted and used to trigger an onLoadingFinish, that in turn generates the onNavigationStateChange.

This injected history shim is simply not present on Android. The pushState API did not used to be available pre-Android 5.0, but should be in all versions currently supported by React Native.

This being missing on Android is problematic for custom hardware back handling with SPAs in web views.

Can we add this history shim functionality to match on Android? There have been reports of problems with this functionality on Android in the past but they were closed due to inactivity.

If this is desirable, but no-one is able to pick this up soon, would you be open to a contribution implementing it?

To Reproduce: Point webview at an SPA and an onNavigationStateChange handler.

Expected behavior: Same behaviour on each platform.

Environment: Tested on:

  • OS: iOS and Android
  • OS version: iOS 15.5, Android 13
  • react-native version: 0.70.0
  • react-native-webview version: 11.23.1

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:7

github_iconTop GitHub Comments

2reactions
markwilcoxcommented, Sep 15, 2022

You can also inject JavaScript that shims the History API like they do on iOS, but entirely from the JS side, then track whether you can go back in the onMessage handler. That’s what I’m doing while waiting for some response on whether a PR (like the patch above) would be accepted.

2reactions
jcarioticommented, Sep 14, 2022

We’ve actually patched our usage of web view for this problem:

@@ -930,6 +940,17 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
       }
     }
 
+    @Override
+    public void doUpdateVisitedHistory(WebView webView, String url, boolean isReload) {
+      super.doUpdateVisitedHistory(webView, url, isReload);
+
+      if (!mLastLoadFailed) {
+        RNCWebView reactWebView = (RNCWebView) webView;
+
+        emitFinishEvent(webView, url);
+      }
+    }
+
     @Override
     public void onPageStarted(WebView webView, String url, Bitmap favicon) {
       super.onPageStarted(webView, url, favicon);
Read more comments on GitHub >

github_iconTop Results From Across the Web

React Native Webview "onNavigationStateChange" returning ...
On Android it works perfectcly, however on iOS the document.title is always returned as "". REACT NATIVE SECTION: const INJECTED_JAVASCRIPT = ` ...
Read more >
react-native-webview - bytemeta
$500 Bounty - Official SwipeRefreshLayout for Android (PTR for iOS ... Inconsistent onNavigationStateChange behaviour between iOS and Android for SPAs.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found