All answers

React Native

How do I get the current URL from a WebView in React Native?

Pass onNavigationStateChange to the WebView and read navState.url, which gives you the current URL each time a page starts or finishes loading. For single-page sites that change the address without loading a new page, inject a small script that sends window.location.href back with postMessage.

Updated October 31, 2026

If you’re showing a website inside your app and need to know which page the user is on, for example to close the WebView once a payment or sign-in finishes, you can get the URL from a callback in react-native-webview. There’s no method on the WebView that returns the current URL, so you keep the latest one in state as it changes.

How it works

onNavigationStateChange runs when the WebView starts or finishes loading a page, and the object it receives includes url, title, loading, canGoBack, and canGoForward. The source={{ uri }} prop isn’t the current URL either, since it’s only the page you told the WebView to open first, and it stays the same as the user taps around.

How to get it

  1. Track the URL with onNavigationStateChange:

    import { useState } from "react";
    import { WebView } from "react-native-webview";
    
    const START_URL = "https://example.com";
    
    export default function Browser() {
      const [currentUrl, setCurrentUrl] = useState(START_URL);
    
      return (
        <WebView
          source={{ uri: START_URL }}
          onNavigationStateChange={(navState) => setCurrentUrl(navState.url)}
        />
      );
    }

    We’re using https://example.com as the site in these examples, so swap in your own start page and success URL.

  2. Act on a page once it has loaded. The callback can fire more than once per page, so check loading when you only want to react to the finished page:

    onNavigationStateChange={(navState) => {
      setCurrentUrl(navState.url);
      if (!navState.loading && navState.url.startsWith("https://example.com/checkout/success")) {
        navigation.goBack();
      }
    }}
  3. Stop a page from loading at all with onShouldStartLoadWithRequest. Return true to let the request load and false to block it, which suits opening outside links in the phone’s browser instead. On Android, it isn’t called for the first load.

    onShouldStartLoadWithRequest={(request) =>
      /^https:\/\/example\.com(?:[/?#]|$)/.test(request.url)
    }

    The pattern matches the whole host, because a check like startsWith("https://example.com") would also let through addresses such as https://example.com.attacker.test/ and https://example.com@attacker.test/.

  4. Handle single-page sites. Some sites change the address with JavaScript (history.pushState or a # change) without loading a new page, and onNavigationStateChange may not fire for those changes. Inject a script that reports the URL instead:

    const reportUrl = `
      (function () {
        function send() {
          window.ReactNativeWebView.postMessage(window.location.href);
        }
        ["pushState", "replaceState"].forEach(function (name) {
          var original = history[name];
          history[name] = function () {
            original.apply(history, arguments);
            send();
          };
        });
        window.addEventListener("popstate", send);
        window.addEventListener("hashchange", send);
        send();
      })();
      true;
    `;
    
    <WebView
      source={{ uri: START_URL }}
      injectedJavaScript={reportUrl}
      onMessage={(event) => setCurrentUrl(event.nativeEvent.data)}
    />;

    Keep the trailing true;, because the injected string has to evaluate to a valid value. On iOS, the script also only runs when an onMessage handler is set.

How you know it works

If you show currentUrl in a small debug label above the WebView and tap through a few pages, the label changes with every page, including route changes on single-page sites once the script is in place. Your success check runs exactly once, when you reach that page.

If the URL is wrong or missing

Redirects pass through every URL on the way, so match on the final page rather than an exact string, and use loading to skip the in-between ones. Navigation inside an iframe doesn’t change the page’s own URL, and the injected script only runs in the main frame by default. And if the site opens links in a new window (target="_blank" or window.open), you can catch those with onOpenWindow.

Ask the agent

If your app is in Draftbit, paste this into the agent, and it can read your code and make the change for you.

Track the current URL of the WebView on this screen with onNavigationStateChange and keep it in state. When the URL reaches our checkout success page, close the WebView and go back. If the site is a single-page app, also report URL changes with an injected script and onMessage.

Open Draftbit

More React Native answers