DEV Community

Cover image for Running React with Ionic Capacitor & Live Reload
Aaron K Saunders
Aaron K Saunders

Posted on • Updated on

Running React with Ionic Capacitor & Live Reload

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

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...

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"
  }
}

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

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.

npx cap open ios

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

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
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.

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">

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!!
  }
}

Discussion (6)

Collapse
nikitafuchs profile image
Nikita Fuchs

The latest step saved me ! They're not mentioning it in the tutorials how to get away from depending on live reload serving the site somewhere. Especially when using the camera, you will have errors ( "Cannot read property 'enumerateDevices' of undefined " ) , because communicating with that requires an HTTPS connection, which is total garbage compared to Cordova.

Thank you very much for this !

Collapse
aaronksaunders profile image
Aaron K Saunders Author

Thanks and I am glad i was able to help out

Collapse
heikokanzler profile image
Heiko Kanzler 🇪🇺

Thank you very much.
A short and very usefull help for everybody who struggles with live reloading.

Collapse
aaronksaunders profile image
Aaron K Saunders Author

thanks, i think the combo video and doc can be helpful at times

Collapse
ben profile image
Ben Halpern

First I'm learning of Ionic Capacitor. Very interesting.

Collapse
aaronksaunders profile image
Aaron K Saunders Author

It is a nice alternative to Cordova that can work within, for the most part, some of the existing Cordova ecosystem in regards to plugins... have a few more posts on the topic forthcoming 👍🏾