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!!
}
}
Top comments (6)
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 !
Thanks and I am glad i was able to help out
Thank you very much.
A short and very usefull help for everybody who struggles with live reloading.
thanks, i think the combo video and doc can be helpful at times
First I'm learning of Ionic Capacitor. Very interesting.
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 👍🏾