Running React with Ionic Capacitor & Live Reload

Aaron K Saunders - Jan 2 '20 - - Dev Community

Photo by Fabian Grohs on Unsplash

📽️ [VIDEO] Running React with Ionic Capacitor & Live Reload

Ionic Capacitor 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 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. This is the code that is from the YouTube Video React Hooks In Ionic Framework - Part One

ionic serve
Enter fullscreen mode Exit fullscreen mode

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

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...
Enter fullscreen mode Exit fullscreen mode

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

{
  "appId": "io.ionic.starter",
  "appName": "myAppReact1",
  "bundledWebRuntime": false,
  "npmClient": "npm",
  "webDir": "build",
  "cordova": {},
  "server": {
    "url": "http://10.6.17.241:8100"
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

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
Enter fullscreen mode Exit fullscreen mode

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.

npx cap open ios
Enter fullscreen mode Exit fullscreen mode

When the application starts up, you should see something similar to this in you xcode log

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

Then we need to sync the native code and plugins so we can run it in Android Studio.

npx cap sync android
Enter fullscreen mode Exit fullscreen mode

And then open Android Studio with the following command.

npx cap open android
Enter fullscreen mode Exit fullscreen mode

Finally run the code in in the emulator or device and you will see the following error.

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.

<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">
Enter fullscreen mode Exit fullscreen mode

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

{
  "appId": "io.ionic.starter",
  "appName": "myAppReact1",
  "bundledWebRuntime": false,
  "npmClient": "npm",
  "webDir": "build",
  "cordova": {},
  "server": {
    "url": "http://10.6.17.241:8100" //<== REMOVE THIS!!
  }
}
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .