Short tutorial/project that leads you to transform your React@17 Web-Application into an Ionic Mobile-Application
I know, React-Native exists and does that, BUUUUT sometimes your application is too big to transform all HTML elements into React-Native components and you might need to release a Mobile-App ASAP, if this is your case, this tutorial is for you.
Before you follow this tutorial, make sure that you can upgrade or downgrade to use react@17, if you can't this might not work for you.
To follow this tutorial you are going to need:
- NodeJS
- (optional) Android Studio (only if you want to run the app in an Android Device)
- (optional) Xcode (only if you want to run the app in an iOS Device, don't forget that for this you need to use a Mac computer)
- Any Code Editor
- Your terminal
Let's start
- Create a React app (using create-react-app)
npm create-react-app my-test-app --template cra-template-typescript
- Install Ionic CLI
npm install -g @ionic/cli
- Install Ionic/Capacitor packages:
npm install @capacitor/app @capacitor/core @capacitor/haptics @capacitor/keyboard @capacitor/status-bar @ionic/react
npm install --D @capacitor/cli
- Update the react package to the compatible version
npm install react@17.0.1 react-dom@17.0.1 react-scripts@5.0.0 typescript@4.1.3
- If you are using react version 18 (or higher), make sure update the
src/index.tsx
file to make it compatatible with version 17, like thisimport React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
- If you are using react version 18 (or higher), make sure update the
- Create
capacitor.config.ts
&ionic.config.json
filesimport { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: 'io.ionic.starter', appName: 'my-test-app', webDir: 'build', bundledWebRuntime: false }; export default config;
{ "name": "my-test-app", "integrations": { "capacitor": {} }, "type": "react" }
- Don't forget update your app name in those files
- If you need an extra config to run you mobile-app you are going to need update the
capacitor.config.ts
file, you can find the information here
- Add these lines to your
public/index.html
file<base href="/" /> <meta name="color-scheme" content="light dark" /> <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta name="format-detection" content="telephone=no" /> <meta name="msapplication-tap-highlight" content="no" /> <!-- add to homescreen for ios --> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-title" content="Ionic App" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" />
- Add new commands to
package.json
file... "build:ionic": "ionic capacitor build android && ionic capacitor build ios && npm run resources", "build:android": "ionic capacitor build android && npm run resources", "build:ios": "ionic capacitor build ios && npm run resources", "build:sync": "npx cap sync", "jetify": "npx jetify && npx cap sync", "resources": "capacitor-resources -p android,ios", "emulate:ios": "ionic capacitor run ios --port=3000 --livereload", "emulate:android": "ionic capacitor run android --port=3000 --livereload --external", "emulate:android:ssl": "ionic capacitor run android --ssl", "release:android": "ionic capacitor build android --prod --release", "release:ios": "ionic capacitor build ios --prod --release" ...
- (Optional) Create Icon & Splash-Screen images (if you skip this step you need to remove the command from
package.json
)- Install Capacitor Resources
npm install capacitor-resources -g
- Create in the root of the project a folder with the name
resources
- Follow these instructions for create the right images
- Install Capacitor Resources
- Build Project
npm run build:ionic
(this is going to build the project for both platforms)- If you have a peer dependency issue that doesn't allow you to finish the build you can try build with the command
npx cap add android
for Android andnpx cap add ios
for iOS - Sometimes you might need to update
gradle
for Android app, check it in your Android Studio IDE to do this, more info in the the troubleshooting section
- If you have a peer dependency issue that doesn't allow you to finish the build you can try build with the command
- Emulate project
npm run emulate:ios
for iOS ornpm run emulate:android
for Android, and choose the device that you want
Command | What it does |
---|---|
npm run build:ionic |
Build the Ionic project for Android & iOS and copy the resources files (icon and splash-screen images) into the new built |
npm run build:android |
Build the Ionic project for Android and copy the resources files (icon and splash-screen images) into the new built |
npm run build:ios |
Build the Ionic project for iOS and copy the resources files (icon and splash-screen images) into the new built |
npm run build:sync |
Update the Ionic project for Android & iOS |
npm run jetify |
If you have updated your gradle from Android Studio and you are using Cordova, run this command to update the Capacitor config |
npm run resources |
Copy the resources files (icon and splash-screen images) into the new built |
npm run emulate:ios |
Emulate your application on livereload mode in the port 3000 |
npm run emulate:android |
Emulate your application on livereload mode in the port 3000 , this mode use an ip for the address instead of localhost |
npm run emulate:android:ssl |
Emulate yourt application on production mode using SSL |
npm run release:android |
Create a release package for production |
npm run release:ios |
Create a release package for production |
npx cap open android |
Open project on Android Studio |
npx cap open ios |
Open project on Xcode |
npx cap add android |
Alternative way to build Android project |
npx cap add ios |
Alternative way to build iOS project |
-
Android Build
APK
(Android application Package is the packaging format which eventually will be installed on devices):- Assuming that you have tested the app, so have built it once at least, run
npm run build:sync
,npm run resources
andnpm run release:android
- Open the the folder
[root]/android
as a project using Android Studio (if the previous step didn't open it automatically), alternatively, you can open it by runningnpx cap open android
- From the top NavBar select
Build -> Build Bundle(s) / APK(s) -> Build APK(s)
- Doing that will iniciate the compile process and you will see a message in the right-bottom corner telling you when it's ready and where is it the
APK
- Assuming that you have tested the app, so have built it once at least, run
-
Android Build
Bundle
(Publishing format used to upload to Google Play Store):- Assuming that you have tested the app, so have built it once at least, run
npm run build:sync
,npm run resources
andnpm run release:android
- Open the the folder
[root]/android
as a project using Android Studio (if the previous step didn't open it automatically), alternatively, you can open it by runningnpx cap open android
- Make sure that for each release you increase the bundle version (Version Code) and App version (Version Name)
- You can do this in Android Studio
File -> Project Structure -> Modules -> Default Config
- From the top NavBar select
Build -> Generate Signed Bundle or APK
- Select
Android App Bundle
and clicknext
- Select the
key
stored to update the app, once thekey
file has been selected this should complete the remaining fields, and now click onnext
- If is the first time uploading the app you must create a new key clicking on the
Create new...
button
- If is the first time uploading the app you must create a new key clicking on the
- Select
release
option and clickfinish
- Now, Android Studio will start to build the APK Bundle, if you keep an eye in the right-bottom corner you will be able to see the a notification when is ready and where is located, which usually would be in
[root]/android/app/release/app-release.aab
- Now go to Google Play Console to upload the app
- Go to the
Production
section and in theApp bundles
and upload the created file in the previous step
- Assuming that you have tested the app, so have built it once at least, run
-
iOs Build
IPA
(Used to directly install into a device):- Assuming that you have tested the app, so have built it once at least, run
npm run build:sync
andnpm run resources
- Open the the folder
[root]/ios
as a project using Xcode (if the previous step didn't open it automatically), alternatively, you can open it by runningnpx cap open ios
- (Optional) Once is open, check the "Build Warning" tab and click in the automatic fix (if is possible) when that fix is finished, select a device for testing in the top nav bar, and click on "play" to make sure that is still working
- In the top bar, click on
Product -> Build
and wait till finish the process, then go to Xcode under Project NavigatorApp -> Products -> App
and there you have the installer file
- Assuming that you have tested the app, so have built it once at least, run
-
iOs Build Distributable bundle (
Bundle
used to publish in the App Store):- Assuming that you have tested the app, so have built it once at least, run
npm run build:sync
andnpm run resources
- Open the the folder
[root]/ios
as a project using Xcode, you can open it by runningnpx cap open ios
- (Optional) Once is open, check the "Build Warning" tab and click in the automatic fix (if is possible) when that fix is finished, select a device for testing in the top nav bar, and click on "play" to make sure that is still working
- Now, in the TopNavBar, where says
App
(in the center), select the optionAny iOS Device
(this is for built the app for any device) - Under Project Navigator, select your porject and then in the middle section select
Signing & Capabilities
and make sure you have chosen your organization's team - Under Project Navigator, select your project and then in the middle section select
General
check the version and build info, those must be greater than the previous built and version (ideally should match with the used on the Android Build) - In the TopNavBar, click on
Product -> Archive
and wait till finish the process (can be checked on the TopNavBar, there should be a green wheel), then in the new opened windows, select your version app (it will show you a list with previous version of the same app) and click onValidate App
and follow the instruction until finish the process- Once the Validate windws is opened, write the name of your app in the field "name" the other way will stay just as "App"
- If you have the error "error finding app store connect credentials" open your account on App Store Connect using the website and try again
- Now click on
Distribute App
, selectApp Store Connect
, and thenUpload
- All the rest must be updated on the App Store Connect website
- Assuming that you have tested the app, so have built it once at least, run
To use some native mobile features, like the Camera, Bluetooth, among others, you must install a plugin, to do that we have two options:
-
- This must be our priority, either the Official Plugins or the Community Plugins, to do that you just have to find the plugin that you want and follow the documentation.
-
-
We should avoid use Cordova plugins as much as we can, because most of these are deprecated, but due to Capacitor is still considered "new", most of the plugins that we might need are not available for Capacitor, so here is where we would be needing use a Cordova plugin.
-
Use a Cordova plugin it's more complex than use Capacitor plugin, so here are the necessary steps to do that:
-
Find the Cordova plugin on this list, or just google it (you can use npm to find it too), most of the time (if not all the time) the name of the plugin will start with the words
cordova-plugin-
, for example, the name of the plugin to read/write files on the device iscordova-plugin-file
-
To continue with the above example, to install that plugin you must use the command
npm i cordova-plugin-file
(unlike was done with previous versionscordova plugin add cordova-plugin-file
) -
Then you should go and find the "bridge plugin", this it's an npm package used to call/import the plugin from your react project, so you will be calling the "bridge plugin" from your code, and that "bridge plugin" is going to call (internally) the real plugin.
-
As a "bridge plugin" we have two options, the @awesome-cordova-plugins and @ionic-native, lets try to use only the @awesome-cordova-plugins for consistency
-
Example of Cordova functions use (without Ionic)
// No need import // to call a Cordova function you use `window` // and then inside of it you might be able to get the functions that you want window.resolveLocalFileSystemURL(file, fileEntry => { ... }
- Example of Cordova function using the "bridge plugin" from @awesome-cordova-plugins
import { File } from '@awesome-cordova-plugins/file'; File.resolveLocalFilesystemUrl(path).then(fileSystem => { ... }
For the above example, due to the lack of documentation, it was necessary to find the function (and structure) to import directly on the
node_module
folder -
-
You can find the official "bridge plugin" list here, I suggest find it on npm here to get the exact name and installation command.
-
So to install the Awesome Cordova Plugin File we must run the command
npm i @awesome-cordova-plugins/file
-
At this point we have installed 2 different packages to get the plugin, now we have to pass that information to the iOS/build & android/build (mostly for the gradle) that we have installed a package that it's not part of Capacitor, to do that we have installed
jetifier
this it's a tool that will care of pass the external plugins to the built files. -
To use
jetifier
, we need to runnpm run jetify
(our minified command), this will update our build and synchronize it with Capacitor, after this you are ready to run and test the new installed plugin in the emulator/device, see more in the troubleshooting section
-
-
- If you face the error
An error occurred while running subprocess
(which might appear for corrupts build) you will have to delete the[root]/android
or[root]/ios
(depending of which built gaves you the problem) and[root]/build
after that try again.
-
The
SSL
does not work on livereload mode and doesn't allow to choose a port. -
Livereload mode only can work with the external flag, so the Ionic App can only run under an
ip
url instead of underlocalhost
(unlike iOs). -
If you have a
Gradle
trouble building the app you have to open the[root]/android
with Android Studio as a project, and in the right-bottom corner you will have a message asking to update the grade, so do it (see the next images) and then after that only if you have installed a Cordova ( see the troubleshooting : Use Native mobile features ) package runnpm run jetify
the other way it should be ready and fixed. -
If you have a JDK version trouble while you are building the project, go to
Android Studio -> Preferences -> Build, Execution, Deploymeny -> Build Tools -> Gradle
and in the sectionGradle JDK
choose the one that Android Studio is asking for. -
Some times when you want to run the app you could have an error saying that your
Manifest
file wasn't found, so you have to delete the folder[root]/android
and then runionic capacitor build android
, after that you should be able to run againionic capacitor run android --livereload --external
.
- The
SSL
does not work on iOS.
This tutorial doesn't mean to replace a React-Native or any other optimized mobile-app, this might not have the best performance, but is still good enough to release a mobile-app ASAP and give you extra time to create an app with the best performance possible =)