• Stars
    star
    1,266
  • Rank 37,161 (Top 0.8 %)
  • Language
    Java
  • License
    MIT License
  • Created about 6 years ago
  • Updated 12 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

📱InAppBrowser for React Native (Android & iOS) 🤘

MIT license Current npm package version Maintenance Tidelift Subscription Downloads Total downloads Follow @jdnichollsc

InAppBrowser for React Native

Provides access to the system's web browser and supports handling redirects

Chrome Custom Tabs for Android & SafariServices/AuthenticationServices for iOS.

Who is using InAppBrowser?

Do you want to see this package in action? Check these awesome projects, yay! 🎉

  • MyApp - A template to create awesome Apps easily ⚡️
  • OLIO - Share more. Waste less.
  • Alpe Audio - Courses On The Go.
  • VibePay - A simple, smarter, better way to get paid.
  • Opinio - Allows the population to be surveyed on social issues.
  • medpex: Online Apotheke - Online pharmacy for medicines & cosmetics with over 5 million customers.
  • CONTACT Software - Energizing your digital business.

Share your awesome project here! ❤️

Getting started

$ npm install react-native-inappbrowser-reborn --save

Mostly automatic installation

Using React Native >= 0.60

Linking the package manually is not required anymore with Autolinking.

  • iOS Platform:

    $ cd ios && pod install && cd .. # CocoaPods on iOS needs this extra step

  • Android Platform with Android Support:

    Using Jetifier tool for backward-compatibility.

    Modify your android/build.gradle configuration:

    buildscript {
      ext {
        buildToolsVersion = "28.0.3"
        minSdkVersion = 16
        compileSdkVersion = 28
        targetSdkVersion = 28
        // Only using Android Support libraries
        supportLibVersion = "28.0.0"
      }
    
  • Android Platform with AndroidX:

    Modify your android/build.gradle configuration:

    buildscript {
      ext {
        buildToolsVersion = "30.0.2"
        minSdkVersion = 21
        compileSdkVersion = 30
        targetSdkVersion = 30
        ndkVersion = "21.4.7075529"
        // Remove 'supportLibVersion' property and put specific versions for AndroidX libraries
        androidXAnnotation = "1.2.0"
        androidXBrowser = "1.3.0"
        // Put here other AndroidX dependencies
      }
    

Using React Native < 0.60

$ react-native link react-native-inappbrowser-reborn

Manual installation

iOS

  1. In XCode, in the project navigator, right click LibrariesAdd Files to [your project's name]
  2. Go to node_modulesreact-native-inappbrowser-reborn and add RNInAppBrowser.xcodeproj
  3. In XCode, in the project navigator, select your project. Add libRNInAppBrowser.a to your project's Build PhasesLink Binary With Libraries
  4. Run your project (Cmd+R)<

iOS with Podfile

  1. Open up ios/Podfile
  • Add pod 'RNInAppBrowser', :path => '../node_modules/react-native-inappbrowser-reborn'
  1. Run pod install

Android

  1. Open up android/app/src/main/java/[...]/MainApplication.java
  • Add import com.proyecto26.inappbrowser.RNInAppBrowserPackage; to the imports at the top of the file
  • Add new RNInAppBrowserPackage() to the list returned by the getPackages() method
  1. Append the following lines to android/settings.gradle:
    include ':react-native-inappbrowser-reborn'
    project(':react-native-inappbrowser-reborn').projectDir = new File(rootProject.projectDir, 	'../node_modules/react-native-inappbrowser-reborn/android')
    
  2. Insert the following lines inside the dependencies block in android/app/build.gradle:
      implementation project(':react-native-inappbrowser-reborn')
    
  3. Update ProGuard config (Optional)
  • Append the following lines to your ProGuard config (proguard-rules.pro)
    -keepattributes *Annotation*
    -keepclassmembers class ** {
      @org.greenrobot.eventbus.Subscribe <methods>;
    }
    -keep enum org.greenrobot.eventbus.ThreadMode { *; }
    

Usage

Methods Action
open Opens the url with Safari in a modal on iOS using SFSafariViewController, and Chrome in a new custom tab on Android. On iOS, the modal Safari will not share cookies with the system Safari.
close Dismisses the system's presented web browser.
openAuth Opens the url with Safari in a modal on iOS using SFAuthenticationSession/ASWebAuthenticationSession, and Chrome in a new custom tab on Android. On iOS, the user will be asked whether to allow the app to authenticate using the given url (OAuth flow with deep linking redirection).
closeAuth Dismisses the current authentication session.
isAvailable Detect if the device supports this plugin.
onStart Initialize a bound background service so the application can communicate its intention to the browser. After the service is connected, the client can be used to Warms up the browser to make navigation faster and indicates that a given URL may be loaded in the future. - Android Only.
warmup Warm up the browser process - Android Only.
mayLaunchUrl Tells the browser of a likely future navigation to a URL. The most likely URL has to be specified first. Optionally, a list of other likely URLs can be provided. They are treated as less likely than the first one, and have to be sorted in decreasing priority order. These additional URLs may be ignored. All previous calls to this method will be deprioritized - Android Only.

iOS Options

Property Description
dismissButtonStyle (String) The style of the dismiss button. [done/close/cancel]
preferredBarTintColor (String) The color to tint the background of the navigation bar and the toolbar. [white/#FFFFFF]
preferredControlTintColor (String) The color to tint the control buttons on the navigation bar and the toolbar. [gray/#808080]
readerMode (Boolean) A value that specifies whether Safari should enter Reader mode, if it is available. [true/false]
animated (Boolean) Animate the presentation. [true/false]
modalPresentationStyle (String) The presentation style for modally presented view controllers. [automatic/none/fullScreen/pageSheet/formSheet/currentContext/custom/overFullScreen/overCurrentContext/popover]
modalTransitionStyle (String) The transition style to use when presenting the view controller. [coverVertical/flipHorizontal/crossDissolve/partialCurl]
modalEnabled (Boolean) Present the SafariViewController modally or as push instead. [true/false]
enableBarCollapsing (Boolean) Determines whether the browser's tool bars will collapse or not. [true/false]
ephemeralWebSession (Boolean) Prevent re-use cookies of previous session (openAuth only) [true/false]
formSheetPreferredContentSize (Object) Custom size for iPad formSheet modals [{width: 400, height: 500}]

Android Options

Property Description
showTitle (Boolean) Sets whether the title should be shown in the custom tab. [true/false]
toolbarColor (String) Sets the toolbar color. [gray/#808080]
secondaryToolbarColor (String) Sets the color of the secondary toolbar. [white/#FFFFFF]
navigationBarColor (String) Sets the navigation bar color. [gray/#808080]
navigationBarDividerColor (String) Sets the navigation bar divider color. [white/#FFFFFF]
enableUrlBarHiding (Boolean) Enables the url bar to hide as the user scrolls down on the page. [true/false]
enableDefaultShare (Boolean) Adds a default share item to the menu. [true/false]
animations (Object) Sets the start and exit animations. [{ startEnter, startExit, endEnter, endExit }]
headers (Object) The data are key/value pairs, they will be sent in the HTTP request headers for the provided url. [{ 'Authorization': 'Bearer ...' }]
forceCloseOnRedirection (Boolean) Open Custom Tab in a new task to avoid issues redirecting back to app scheme. [true/false]
hasBackButton (Boolean) Sets a back arrow instead of the default X icon to close the custom tab. [true/false]
browserPackage (String) Package name of a browser to be used to handle Custom Tabs.
showInRecents (Boolean) Determining whether browsed website should be shown as separate entry in Android recents/multitasking view. [true/false]
includeReferrer (Boolean) Determining whether to include your package name as referrer for the website to track. [true/false]

Demo

import { Linking, Alert } from 'react-native'
import { InAppBrowser } from 'react-native-inappbrowser-reborn'

...
  async sleep(timeout) {
    return new Promise(resolve => setTimeout(resolve, timeout))
  }
  async openLink() {
    try {
      const url = 'https://github.com/proyecto26'
      if (await InAppBrowser.isAvailable()) {
        const result = await InAppBrowser.open(url, {
          // iOS Properties
          dismissButtonStyle: 'cancel',
          preferredBarTintColor: '#453AA4',
          preferredControlTintColor: 'white',
          readerMode: false,
          animated: true,
          modalPresentationStyle: 'fullScreen',
          modalTransitionStyle: 'coverVertical',
          modalEnabled: true,
          enableBarCollapsing: false,
          // Android Properties
          showTitle: true,
          toolbarColor: '#6200EE',
          secondaryToolbarColor: 'black',
          navigationBarColor: 'black',
          navigationBarDividerColor: 'white',
          enableUrlBarHiding: true,
          enableDefaultShare: true,
          forceCloseOnRedirection: false,
          // Specify full animation resource identifier(package:anim/name)
          // or only resource name(in case of animation bundled with app).
          animations: {
            startEnter: 'slide_in_right',
            startExit: 'slide_out_left',
            endEnter: 'slide_in_left',
            endExit: 'slide_out_right'
          },
          headers: {
            'my-custom-header': 'my custom header value'
          }
        })
        await this.sleep(800);
        Alert.alert(JSON.stringify(result))
      }
      else Linking.openURL(url)
    } catch (error) {
      Alert.alert(error.message)
    }
  }
...

Android Optimizations

On Android, you can warmup the in app browser client to make it launch siginificantly faster. To do so, add the following to your MainActivity

import com.proyecto26.inappbrowser.RNInAppBrowserModule;

public class MainActivity extends ReactActivity {

  @Override
  protected void onStart() {
    super.onStart();
    RNInAppBrowserModule.onStart(this);
  }

}

You can further optimize performance and pre-render pages by providing the urls that the user is likely to open.

// Do not call this every time the component render
useEffect(() => {
  InAppBrowser.mayLaunchUrl("Url user has high chance to open", ["Other urls that user might open ordered by priority"]);
}, []);

Authentication Flow using Deep Linking

In order to redirect back to your application from a web browser, you must specify a unique URI to your app. To do this, define your app scheme and replace my-scheme and my-host with your info.

<activity
  ...
  android:launchMode="singleTask">
  <intent-filter>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="my-scheme" android:host="my-host" android:pathPrefix="" />
  </intent-filter>
</activity>
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleTypeRole</key>
    <string>Editor</string>
    <key>CFBundleURLName</key>
    <string>my-scheme</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>my-scheme</string>
    </array>
  </dict>
</array>
  • utilities.js
import { Platform } from 'react-native'
export const getDeepLink = (path = '') => {
  const scheme = 'my-scheme'
  const prefix = Platform.OS == 'android' ? `${scheme}://my-host/` : `${scheme}://`
  return prefix + path
}
import { Root } from 'native-base'
import { createStackNavigator } from 'react-navigation'
import { getDeepLink } from './utilities'

const Main = createStackNavigator(
  {
    SplashComponent: { screen: SplashComponent },
    LoginComponent: { screen: LoginComponent },
    HomeComponent: { screen: HomeComponent },
    CallbackComponent: { //Redirect users to the Home page if they are authenticated, otherwise to Login page...
      screen: CallbackComponent,
      path: 'callback/' //Enable Deep linking redirection to get the auth_token
    }
  },
  {
    index: 0,
    initialRouteName: 'SplashComponent',
    headerMode: 'none'
  }
)
...
  render() {
    return (
      <Root>
        <Main uriPrefix={getDeepLink()} />
      </Root>
    )
  }
...
  • LoginComponent
import { Linking } from 'react-native'
import { InAppBrowser } from 'react-native-inappbrowser-reborn'
import { getDeepLink } from './utilities'
...
  async onLogin() {
    const deepLink = getDeepLink('callback)
    const url = `https://my-auth-login-page.com?redirect_uri=${deepLink}`
    try {
      if (await InAppBrowser.isAvailable()) {
        InAppBrowser.openAuth(url, deepLink, {
          // iOS Properties
          ephemeralWebSession: false,
          // Android Properties
          showTitle: false,
          enableUrlBarHiding: true,
          enableDefaultShare: false
        }).then((response) => {
          if (
            response.type === 'success' &&
            response.url
          ) {
            Linking.openURL(response.url)
          }
        })
      } else Linking.openURL(url)
    } catch (error) {
      Linking.openURL(url)
    }
  }
...
  • SplashComponent
...
  async componentDidMount() {
    // Play Lottie Animation :)

    // Validate the stored access token (Maybe with a request)
    // Redirect the user to the Home page if the token is still valid
    // Otherwise redirect to the Login page
  }
...
  • CallbackComponent
...
  async componentDidMount() {
    // Play Lottie Animation :)
    try {
      await this.loadUserInfo()
      // Redirect to the Home page
    } catch (error) {
      // Show error and redirect the user to the Login page
    }
  }

  async loadUserInfo() {
    const { navigation } = this.props
    const { state: { params } } = navigation
    const { code, error } = params || {}

    if (code) {
      // Get and Save the access token request, user info...
    }
    else {
      return Promise.reject(new Error(error))
    }
  }
...

StatusBar

The StatusBar will keep the last one provided in your app. So if the StatusBar is dark-content before you open the browser this will keep it.

Starting with React Native 0.59 onwards, there is a simpler way of handling this update, without the need of patching StatusBar.

  async openInBrowser(url) {
    try {
      const oldStyle = StatusBar.pushStackEntry({ barStyle: 'dark-content', animated: false });
      await InAppBrowser.open(url)
      StatusBar.popStackEntry(oldStyle);
    } catch (error) {
      Alert.alert(error.message)
    }
  })

For previous versions, you can still apply the method described below.

If you want to change before opening you can do something like

  async openInBrowser(url) {
    try {
      StatusBar.setBarStyle('dark-content')
      await InAppBrowser.open(url)
    } catch (error) {
      Alert.alert(error.message)
    }
  })

If you need to restore the old bar style, after the browser is dismissed, you can try and patch the StatusBar.setBarStyle function to store the old value like so:

// patch StatusBar.setBarStyle to make style accessible
const _setBarStyle = StatusBar.setBarStyle
StatusBar.setBarStyle = (style) => {
  StatusBar.currentStyle = style
  _setBarStyle(style)
}

You can than restore the old bar style after the browser has been dismissed like this:

  async openInBrowser(url) {
    try {
      const oldStyle = StatusBar.currentStyle
      StatusBar.setBarStyle('dark-content')
      await InAppBrowser.open(url)
      if(oldStyle) StatusBar.setBarStyle(oldStyle)
    } catch (error) {
      Alert.alert(error.message)
    }
  })

Authentication

Using in-app browser tabs (like SFAuthenticationSession/ASWebAuthenticationSession and Android Custom Tabs) where available. Embedded user-agents, known as web-views (like UIWebView and WKWebView), are explicitly not supported due to the usability and security reasons documented in Section 8.12 of RFC 8252.

Credits 👍

Contributing ✨

When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated ❤️. You can learn more about how you can contribute to this project in the contribution guide.

Contributors ✨

Please do contribute! Issues and pull requests are welcome.

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

Supporting 🍻

I believe in Unicorns 🦄 Support me, if you do too.

Donate Ethereum, ADA, BNB, SHIBA, USDT, DOGE:

Wallet address

Wallet address: 0x3F9fA8021B43ACe578C2352861Cf335449F33427

Please let us know your contributions! 🙏

Enterprise 💼

Available as part of the Tidelift Subscription.

The maintainers of InAppBrowser for React Native and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.

Security contact information 🚨

To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.

License ⚖️

This repository is available under the MIT License.

Happy coding 💯

Made with ❤️

More Repositories

1

RestClient

🦄 A Promise based REST and HTTP client for Unity 🎮
C#
1,234
star
2

awesome-unity

A curated list of awesome Unity games! 🎮
714
star
3

awesome-jsgames

A curated list of awesome JavaScript Games 🎮
445
star
4

TheJobInterviewGuide

A job guide to help developers get through interviews and get amazing jobs!
333
star
5

ion-phaser

A web component to use Phaser Framework with Angular, React, Vue, etc 🎮
TypeScript
248
star
6

animatable-component

Animate once, use Everywhere! 💫
TypeScript
245
star
7

MyAPI

A template to create awesome APIs easily ⚡️
TypeScript
135
star
8

Phaser-Kinetic-Scrolling-Plugin

Kinetic Scrolling plugin for Canvas using Phaser Framework
JavaScript
130
star
9

MyApp

A template to create awesome Apps easily ⚡️
TypeScript
75
star
10

nativescript-inappbrowser

📱InAppBrowser for NativeScript (Android & iOS) 🤘
TypeScript
72
star
11

nativescript-ionic-template

📱 🖥 Create Mobile First apps, Web and Native sharing the code with Angular 🎉
TypeScript
69
star
12

cardano-developer

A Cardano Developer Guide
62
star
13

proyecto26.github.io

The Proyecto26 github homepage.
JavaScript
57
star
14

thecryptopurge

A crypto shooter-survival real-time NFT-based game inspired by The Purge 💸
JavaScript
57
star
15

MyBot

🧠 Create chatbots easily with Bot Framework! 🤖
JavaScript
31
star
16

mercadopago-api

API for MercadoPago Checkout
TypeScript
23
star
17

Phaser-Workshop

A workshop to create awesome games with Phaser Framework 🎮
22
star
18

Roxy-Fileman-for-Node.js

Roxy Fileman, upload and manage files with Node.js!
JavaScript
15
star
19

PokeDex-GO

The Best PokéDex for Pokémon Go, created by Pokémon masters! 😺
JavaScript
14
star
20

ion-phaser-ce

A web component to use Phaser Framework CE (Community Edition) with Angular, React, Vue, etc 🎮
TypeScript
11
star
21

react-native-mercado-pago-enterprise

Integrating Mobile Checkout of MercadoPago with React Native to create a payment experience in your applications.
11
star
22

use-dictionary

A React useReducer() hook to use dictionaries (keys and values) 🔑
TypeScript
9
star
23

dotnet-documentation

SOLID, DI, N-Tier, Logs, etc with dotnet
9
star
24

colombia

Departamentos y Municipios de Colombia 🇨🇴
6
star
25

BuyMeNear

Buy Me Near is a revolutionary, meaningful way to fund your creative work.
JavaScript
6
star
26

react-native-animations-demo

Animate with React Native ⏯
JavaScript
6
star
27

web-animations-workshop

Workshop of Web Animations API and Web Components
4
star
28

record-audio-button-enterprise

🔴 A Web Component for Recording Audio with a swipe gesture inspired by WhatsApp (Enterprise) 💼
4
star
29

Xamarin

A summary/template about Xamarin 📱
C#
3
star
30

Phaser-Market

Discover & share phaser plugins for your games
CSS
3
star
31

social-change

Social change through technology, together we are more! 💪
3
star
32

OpenSourceCoin

A cryptocurrency for Open Source Contributors & Developers
2
star
33

stencil-ionic-components

Create StencilJS Components reusing Ionic components
TypeScript
2
star
34

concertx-frontend

Empowering musical artists and fans with immersive concert experiences and trusted transactions. Start bringing your concert ideas to life today!
TypeScript
2
star
35

ionic-background-geolocation

Background Geolocation App using BackgroundLocation and Location ionic plugins
TypeScript
2
star
36

NodeBots

Nodebots (Tessel), IoT and Azure
JavaScript
1
star
37

flutter-inappbrowser

📱InAppBrowser for Flutter (Android & iOS) 🤘
1
star
38

ProjectX

NextJS template with TailwindCSS, etc
1
star
39

sponsors

The place to discuss with our sponsors! 💼
1
star