expo-web-browser
provides access to the system's web browser and supports handling redirects. On iOS, it uses SFSafariViewController
or SFAuthenticationSession
, depending on the method you call, and on Android it uses ChromeCustomTabs
. As of iOS 11, SFSafariViewController
no longer shares cookies with Safari, so if you are using WebBrowser
for authentication you will want to use WebBrowser.openAuthSessionAsync
, and if you just want to open a webpage (such as your app privacy policy), then use WebBrowser.openBrowserAsync
.Android Device | Android Emulator | iOS Device | iOS Simulator | Web |
---|---|---|---|---|
expo install expo-web-browser
If you're installing this in a bare React Native app, you should also follow these additional installation instructions.
import React, { Component } from 'react'; import { Button, Text, View } from 'react-native'; import * as WebBrowser from 'expo-web-browser'; export default class App extends Component { state = { result: null, }; render() { return ( <View> <Button title="Open WebBrowser" onPress={this._handlePressButtonAsync} /> <Text>{this.state.result && JSON.stringify(this.state.result)}</Text> </View> ); } _handlePressButtonAsync = async () => { let result = await WebBrowser.openBrowserAsync('https://expo.io'); this.setState({ result }); }; }
WebBrowser
window for authentication or another use case where you would like to pass information back into your app through a deep link, be sure to add a handler with Linking.addEventListener
before opening the browser. When the listener fires, you should call dismissBrowser -- it will not automatically dismiss when a deep link is handled. Aside from that, redirects from WebBrowser
work the same as other deep links. Read more about it in the Linking guide.import * as WebBrowser from 'expo-web-browser';
SFSafariViewController
, and Chrome in a new custom tab on Android. On iOS, the modal Safari will not share cookies with the system Safari. If you need this, use openAuthSessionAsync.#AARRGGBB
or #RRGGBB
format.done
, close
, or cancel
.#AARRGGBB
or #RRGGBB
format.false
#AARRGGBB
or #RRGGBB
format.{type: 'opened'}
if we were able to open browser.{ type: 'cancel' }
.dismissBrowser
, the Promise resolves with { type: 'dismiss' }
.SFAuthenticationSession
on iOS 11 and greater, and falling back on a SFSafariViewController
. The user will be asked whether to allow the app to authenticate using the given url.🚨This API can only be used in a secure environment (https
). You can useexpo start:web --https
to test this. Otherwise an error with codeERR_WEB_BROWSER_CRYPTO
will be thrown.
window.open()
API.WebBrowser.maybeCompleteAuthSession()
.WebBrowser.maybeCompleteAuthSession()
.expo start:web --https
.localstorage
. This ensures that auth cannot complete unless it's done from a page running with the same origin as it was started. Ex: if openAuthSessionAsync
is invoked on https://localhost:19006
, then maybeCompleteAuthSession
must be invoked on a page hosted from the origin https://localhost:19006
. Using a different website, or even a different host like https://128.0.0.*:19006
for example will not work.{ type: 'dismiss' }
.window.open()
which takes too long to fire after a user interaction. This method must be invoked immediately after a user interaction. If the event is blocked, an error with code ERR_WEB_BROWSER_BLOCKED
will be thrown.openBrowserAsync
's browserParams
object. If there is no native AuthSession implementation available (which is the case on Android) these params will be used in the browser polyfill. If there is a native AuthSession implementation, these params will be ignored.{ type: 'cancel' }
.{ type: 'cancel' }
.dismissBrowser
, the Promise resolves with { type: 'dismiss' }
.{ type: 'failed' }
:Not supported on this platform
: If the platform doesn't support this method (iOS, Android).Cannot use expo-web-browser in a non-browser environment
: If the code was executed in an SSR or node environment.No auth session is currently in progress
: (the cached state wasn't found in local storage). This can happen if the window redirects to an origin (website) that is different to the initial website origin. If this happens in development, it may be because the auth started on localhost
and finished on your computer port (Ex: 128.0.0.*
). This is controlled by the redirectUrl
and returnUrl
.Current URL "<URL>" and original redirect URL "<URL>" do not match.
: This can occur when the redirect URL doesn't match what was initial defined as the returnUrl
. You can skip this test in development by passing { skipRedirectCheck: true }
to the function.{ type: 'success' }
:ERR_WEB_BROWSER_REDIRECT
was thrown, it may mean that the parent window was reloaded before the auth was completed. In this case you'll need to close the child window manually.warmUp
method on CustomTabsClient for specified package.{ package: string }
mayLaunchUrl
method for browser specified by the package.{ package: string }
.warmUpAsync
or mayInitWithUrlAsync
. You should call this method once you don't need them to avoid potential memory leaks. However, those binding would be cleared once your application is destroyed, which might be sufficient in most cases.{ package: string }
when cooling is performed, or an empty object when there was no connection to be dismissed.{ type: 'dismiss' }
.PackageManager.getResolvingActivities
under the hood. (For example, some browsers might not be present in browserPackages
list once another browser is set to defult.){ browserPackages: string[], defaultBrowserPackage: string, servicePackages: string[], preferredBrowserPackage: string }
PackageManager
as capable of handling Custom Tabs. Empty array means there is no supporting browsers on device.PackageManager
as capable of handling Custom Tabs Service. This service is used by warmUpAsync
, mayInitWithUrlAsync
and coolDownAsync
.CustomTabsClient
to be used to handle Custom Tabs. It favors browser chosen by user as default, as long as it is present on both browserPackages
and servicePackages
lists. Only such browsers are considered as fully supporting Custom Tabs. It might be null
when there is no such browser installed or when default browser is not in servicePackages
list.servicePackage
list, it should be capable of performing warmUpAsync
, mayInitWithUrlAsync
and coolDownAsync
. For opening an actual web page, browser must be in browserPackages
list. A browser has to be present in both lists to be considered as fully supporting Custom Tabs.window.open()
method was invoked too long after a user input was fired.expo start:web --https
or expo start --web --https
to open your web page in a secure development environment.