How to Add React Native Web in a Crowdbotics Mobile App

React Native is a fantastic framework that continues to improve over time. It’s open-source and allows us to build cross-platform mobile applications using JavaScript as its core.

Using React Native Web, an open-source project, React Native core API components can be used to build universal applications using the same source code. It uses React DOM at the core to render a majority of React Native components.

In this post, let's take a step-by-step look at how you can integrate and configure React Native Web in a RADStack app generated using Crowdbotics' build tool.

Create a Crowdbotics mobile app


To create a new mobile app using Crowdbotics, go the app dashboard screen and click the button Create App.

You will be redirected to the Create App screen, where you will see options for naming your app and choosing what type of scaffold to build. Select the option Build from Scratch in the side menu, then select the type of the app to be Mobile App. Then enter the name of the app in the input field as shown below:

Click the button Create App in the above screen. The app's scaffolding process has been started. It might take a few minutes to generate the app. You will be re-directed to the Storyboard Editor.

There are plenty of app modules and templates available to add to the mobile app that you can choose from.

For this guide, we are going to use the default app generated.

Next, go to the Status page to see if the scaffolding of the app is complete. Once it's complete, a success message is shown under Build Status.

You can generate the first versions of your iOS or Android app as well as deploy the backend API by deploying the app. Click the button Deploy App to build the initial version.

When the initial deployment of the API is done, the status gets an update. Also, when the deployment of the Android app is done, a Preview tab is opened where you can the initial version of the app as shown below.

The app scaffolding process is now complete. To access the associated GitHub repo, go to the Settings tab in the sidebar. On the right hand side you will see the option to View Code.

Click on View Code and you will be redirected to the GitHub repo. If you are accessing the repo for the first time, you will be prompted to accept the invitation as shown below.

You are now ready to access the source code from GitHub.

To install dependencies and build the app for the iOS or Android platform, please follow the instructions provided in the README.md file with the source code. In order to proceed, make sure the app is up and running.

Rearrange the project structure

Before installing any dependencies to integrate React Native Web in our current app, let's rearrange the project structure a bit. First, take a look at what the current project structure looks like.

The initial thing to do in this section is to move the App.js and app.json files to the src/ directory. The reason for moving these files is that when the React Native Web dependency is installed, it uses a package called react-dom to render and launch the web app. It always looks for the main file inside the src/ directory. A similar behavior can be seen in React apps generated with the Create React App utility.

There are going to be two entry points in the current app structure. The first is going to be a file called index.native.js that is going to trigger the React Native app. This file is going to be at the root of the project directory since the React Native build tool always looks for the entry point file at the root. After moving the App.js and app.json files to the src/ directory, the contents of this file are going to be:

import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './src/app.json';

AppRegistry.registerComponent(appName, () => App);

Next, create another file called index.js inside the src/ directory. This file is going to be the entry point for the web app. Make sure to add the runApplication method from the AppRegistry to load the web app. It accepts the name of the app from app.json as the first argument and an object with rootTag as its property.

Add the following code snippet in this file:

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);
AppRegistry.runApplication(appName, {
  rootTag: document.getElementById('root'),
});

The rootTag passed as the property of an object is going to look for an id with the value of root on a div element in an HTML file. This behavior is also similar to that of Create React App or any web app that uses the React library. At the root of the project directory, create a new folder called public/ and inside it, create a file called index.html with the following markup code.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta name="theme-color" content="#000000" />
    <title>Crowdbotics Web App</title>
  </head>

  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
  </body>
</html>

Add dependencies to launch the web app

There are three dependencies required in order to integrate and make React Native Web app work:

  • react-native-web
  • react-dom
  • react-scripts

To install them, go back to the terminal window and run the command:

yarn add [email protected] react-dom

# then install react-scripts as dev dependency
yarn add --dev react-scripts

Then add the script to launch the web app development server in the package.json file.

"scripts": {
    "web": "react-scripts start",
    // ...
  },

That's all the necessary steps to configure React Native Web.

Building the mobile and the web app

React Native Web supports a majority of React Native API core components such as View, Text, TextInput, and so on. There are a lot of similarities between the APIs of the mobile UI and the Web, but there are important differences to understand and keep in mind.

For Web and mobile, let's see how some of these components render on each platform. In the App.js file, let's try to display an image that has a width and a height as half of the width of the current window.

import React from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  FlatList,
  Image,
  Dimensions,
} from 'react-native';

const {width} = Dimensions.get('window');

export default class App extends React.Component {
  render() {
    return (
      <View style=>
        <View style=>
          <Image
            style=
            source={require('./assets/images/backgroundLoginV1.png')}
          />
        </View>
        <Text style=>
          React Native Web + Crowdbotics = 💜
        </Text>
      </View>
    );
  }
}


React Native relies on JavaScript when it comes to styling components or UI elements. React Native for Web implements the React Native style API. To define a style, it’s the same in a React Native app. Either define style objects using the StyleSheet API or use inline style objects as shown in the code snippet above.

To run the app on mobile, use the command yarn start from a terminal window. To run the app in a web browser, run the command yarn run web in a separate terminal window.

You are going to get the following result:

Let's add a button from the React Native API using TouchableOpacity. Modify the App component as the following code snippet:

export default class App extends React.Component {
  render() {
    return (
      <View style=>
        <View style=>
          <Image
            style=
            source={require('./assets/images/backgroundLoginV1.png')}
          />
        </View>
        <Text style=>
          React Native Web + Crowdbotics = 💜
        </Text>
        <Text style=>
          See alert box in action
        </Text>
        <TouchableOpacity
          onPress={() => alert('Pressed')}
          style={{
            backgroundColor: 'tomato',
            justifyContent: 'center',
            alignItems: 'center',
            height: 40,
            width: 100,
          }}>
          <Text style=>Button</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

Here is the output:

On pressing the button, an alert box is displayed.

Rendering a list in React Native Web is similar to React Native for mobile. Let’s add some mockup data and use FlatList to display the content. Modify App.js as shown below:

export default class App extends React.Component {
  state = {
    StarWarsAPI: [
      {
        id: 1,
        name: 'Luke Skywalker',
      },
      {
        id: 2,
        name: 'C-3PO',
      },
      {
        id: 3,
        name: 'R2-D2',
      },
    ],
  };

  _keyExtractor = item => item.id;

  _renderItem = ({item}) => (
    <View>
      <Text style=>{item.name}</Text>
    </View>
  );

  render() {
    return (
      <View
        style={{
          flex: 1,
          alignItems: 'center',
          marginTop: 40,
        }}>
        <View style=>
          <Image
            style={{
              width: width / 2,
              height: width / 4,
              borderRadius: 10,
            }}
            source={require('./assets/images/backgroundLoginV1.png')}
          />
        </View>
        <Text
          style={{
            fontSize: 20,
            fontWeight: '600',
            marginBottom: 20,
          }}>
          React Native Web + Crowdbotics = 💜
        </Text>
        <Text
          style={{
            fontSize: 20,
            fontWeight: '600',
            marginBottom: 20,
          }}>
          See alert box in action
        </Text>
        <TouchableOpacity
          onPress={() => alert('Pressed')}
          style={{
            backgroundColor: 'tomato',
            justifyContent: 'center',
            alignItems: 'center',
            height: 40,
            width: 100,
            marginBottom: 20,
          }}>
          <Text style=>Button</Text>
        </TouchableOpacity>
        <Text
          style={{
            fontSize: 20,
            fontWeight: '600',
            marginBottom: 20,
          }}>
          Below is a list:
        </Text>
        <FlatList
          data={this.state.StarWarsAPI}
          keyExtractor={this._keyExtractor}
          renderItem={this._renderItem}
        />
      </View>
    );
  }
}

Here is the output:

Conclusion

This post allows you to set up and configure React Native Web in a Crowdbotics generated mobile app built with React Native. Currently, organizations like Twitter, Expo, Major League Soccer, Flipkart, and a few more are using React Native Web in production.

In-app support for React Native Web is slated to be released on the Crowdbotics platform in Q4 2020.

Please note that a mobile app generated using the Crowdbotics build tool uses React Native version 0.62.0 and above at the time of writing and publishing this post. React Native Web currently supports all React Native versions above 0.60.0.

Originally published:

August 27, 2020

Related Articles