Running React with Ionic Capacitor & Live Reload
Tags: react, javascript, ionic, tutorial
Published: 2020-01-02 16:30:35

*Photo by Fabian Grohs on Unsplash*

[:film_projector: [VIDEO] Running React with Ionic Capacitor & Live Reload] (https://youtu.be/bqNiaa0sZEg)

>[Ionic Capacitor](https://capacitor.ionicframework.com/docs/) is a cross-platform app runtime that makes it easy to build web apps that run natively on iOS, Android, Electron, and the web. We call these apps "Native Progressive Web Apps" and they represent the next evolution beyond Hybrid apps.


The [Ionic Capacitor documentation](https://ionicframework.com/docs/cli/commands/capacitor-run) doesn't really work for building and running your react application with Capacitor and Live Reload so after hours spent realizing that, I have figured out a process that works for me, hopefully it benefits someone out there.

## First Build Your App
The starting point for this code is in this github repo [MyAppReactApp](https://github.com/aaronksaunders/MyAppReactApp). This is the code that is from the YouTube Video [React Hooks In Ionic Framework - Part One](https://www.youtube.com/watch?v=f9pq4Yizrg4&t=6s)

```console
ionic serve
```
When it is done running, notice that it has displayed the url the application in running on. Here is what it looks like on my development device
```console
MacBook-Pro:MyAppReactApp aaronksaunders$ ionic serve            
> react-scripts start
[react-scripts] ℹ ｢wds｣: Project is running at http://10.6.17.241/
[react-scripts] ℹ ｢wds｣: webpack output is served from /
[react-scripts] ℹ ｢wds｣: Content not from webpack is served from /Users/aaronksaunders/dev/projects/react/MyAppReactApp/public
[react-scripts] ℹ ｢wds｣: 404s will fallback to /index.html
[react-scripts] Starting the development server...
```
### Setting up `capacitor.config.json`
The file `capacitor.config.json` can be found in the root of the application directory we need to modify it so capacitor knows where to find the website running. Take the url from the output of the `ionic serve` command and modify your `capacitor.config.json` file as follows
```json
{
  "appId": "io.ionic.starter",
  "appName": "myAppReact1",
  "bundledWebRuntime": false,
  "npmClient": "npm",
  "webDir": "build",
  "cordova": {},
  "server": {
    "url": "http://10.6.17.241:8100"
  }
}
``` 
**Make sure you add the port on the end of the URL**
### Running Capacitor
Since I work in Visual Studio Code, just open another terminal window and run the following commands to sync the project code.
```
npx cap sync
```
This will copy over all of the plugin information and the native bridge code for the project to run on device or emulator; the console output should looks similar to below
```console
MacBook-Pro:MyAppReactApp aaronksaunders$ npx cap sync ios
✔ Copying web assets from build to ios/App/public in 348.07ms
✔ Copying native bridge in 1.60ms
✔ Copying capacitor.config.json in 1.43ms
✔ copy in 368.54ms
✔ Updating iOS plugins in 3.57ms
  Found 0 Capacitor plugins for ios:
✔ Updating iOS native dependencies with "pod install" (may take several minutes) in 4.23s
✔ update ios in 4.24s
Sync finished in 4.626s
```
Next you can open up the platform specific IDE with the following command, I am on ios so the command will open XCode, and when it opens, build/run the application.
```console
npx cap open ios
```
When the application starts up, you should see something similar to this in you xcode log
```console
2019-12-30 14:30:08.440853-0500 App[8013:145759] DiskCookieStorage changing policy from 2 to 0, cookie file: file:///Users/aaronksaunders/Library/Developer/CoreSimulator/Devices/76C4C563-0811-4917-9047-4ACD2B6C8687/data/Containers/Data/Application/D4CCEEC9-3FE1-4360-AF30-574BC8DEA7FA/Library/Cookies/io.ionic.starter.aks.binarycookies
Loading network plugin
2019-12-30 14:30:08.541581-0500 App[8013:145759] CAPKeyboard: resize mode - native
⚡️  Loading app at http://10.6.17.241:8100...
Reachable via WiFi
APP ACTIVE
⚡️  [log] - [HMR] Waiting for update signal from WDS...
⚡️  WebView loaded
⚡️  To Native ->  App addListener 25525202
SplashScreen.hideSplash: SplashScreen was automatically hidden after default timeout. You should call `SplashScreen.hide()` as soon as your web app is loaded (or increase the timeout). Read more at https://capacitor.ionicframework.com/docs/apis/splash-screen/#hiding-the-splash-screen
⚡️  To Native ->  Camera getPhoto 25525203
```
Now any edits you make to the website will force a rebuild... then the application will detect the new website and reload itself.
### Android Quirks
When running capacitor with livereload on android devices and emulators there is an issue you will most likely run into. This issue can be resolve pretty easily if you follow the instructions below.

I will walk you through the process so you can see the error and then fix the error. Lets get started by adding android to the project.
```
npx cap add android
```
```console
MacBook-Pro:MyAppReactApp aaronksaunders$ npx cap add android
✔ Installing android dependencies in 7.13s
⠋ Adding native android project in: /Users/aaronksaunders/de✔ Adding native android project in: /Users/aaronksaunders/dev/projects/react/MyAppReactApp/android in 27.56ms
✔ Syncing Gradle in 15.83s
✔ add in 22.99s
⠋ Copying web assets from build to android/app/src/main/asse⠙ Copying web assets from build to android/app/src/main/asse⠹ Copying web assets from build to android/app/src/main/asse✔ Copying web assets from build to android/app/src/main/assets/public in 235.76ms
✔ Copying native bridge in 1.00ms
✔ Copying capacitor.config.json in 760.08μp
✔ copy in 247.39ms
✔ Updating Android plugins in 3.77ms
  Found 0 Capacitor plugins for android:
✔ update android in 16.64ms
```
Then we need to sync the native code and plugins so we can run it in Android Studio.
```
npx cap sync android
```
And then open Android Studio with the following command.
```
npx cap open android
```
Finally run the code in in the emulator or device and you will see the following error.
<img src="https://thepracticaldev.s3.amazonaws.com/i/9mrdpgb0u3ezf02rwj71.png" width=600/>
This is an android specific issue that can be resolved by updating the `AndroidManifest.xml` to include the following `android:usesCleartextTraffic="true"`. You can make this edit in the file which can be found at this path `android/app/src/main/AndroidManifest.xml`.

```xml
<application
    android:usesCleartextTraffic="true"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
```
After you make this change, you will need to `npx cap sync android` to get the application updates and then restart the emulator or device and you should see the application working fine.
### Removing Live Reload
To remove live reload from you project all you need to do is update the `capacitor.config.json` and remove the `server.url` property
```json
{
  "appId": "io.ionic.starter",
  "appName": "myAppReact1",
  "bundledWebRuntime": false,
  "npmClient": "npm",
  "webDir": "build",
  "cordova": {},
  "server": {
    "url": "http://10.6.17.241:8100" //<== REMOVE THIS!!
  }
}
```