DEV Community

loading...
Ionic

Adding Ionic React to an existing React project

elylucas profile image Ely Lucas ・4 min read

Earlier this week, we launched Ionic React (read the announcement here). To get started with a new Ionic React project is quite easy, but what if you have an existing React project and want to integrate Ionic into it?

Fortunately the process it pretty easy. In this short guide, I'll go through how to start using Ionic React in an existing project. I'll start with how to use individual components, and then touch on how to get the full Ionic app experience.

Using Individual Ionic Components

Ionic React has around 100 components that you can begin using in your app immediately to help make it more mobile-friendly.

To get started with just using components, add the @ionic/react package to your project:

npm i @ionic/react

Next, import the core CSS for Ionic somewhere in your main app file:

import '@ionic/react/css/core.css';

Now, you can import any of the components and begin to use them right away. Here we are importing the IonButton and IonDatetme components and using them anywhere in our app:

import { IonButton, IonDatetime } from '@ionic/react';
<IonDatetime displayFormat="MM/DD/YYYY" placeholder="Select Date"></IonDatetime>
<IonButton fill="clear">Start</IonButton>

Using Ionic Pages

If you want to convert part of your app and give it the whole Ionic experience, there are a few additional steps to take to get this setup.

First, import some additional CSS files that help set up the overall structure of the page and some utility helpers:

/* Basic CSS for apps built with Ionic */
import '@ionic/react/css/normalize.css';
import '@ionic/react/css/structure.css';
import '@ionic/react/css/typography.css';

/* Optional CSS utils that can be commented out */
import '@ionic/react/css/padding.css';
import '@ionic/react/css/float-elements.css';
import '@ionic/react/css/text-alignment.css';
import '@ionic/react/css/text-transformation.css';
import '@ionic/react/css/flex-utils.css';
import '@ionic/react/css/display.css';

If you are using another CSS framework (like Bootstrap), you might want to isolate the Ionic pages away from them. This will help to ensure there aren't any CSS conflicts between the libraries.

Next, install the @ionic/react-router library:

npm i @ionic/react-router

The Ionic React Router library is a small wrapper around the popular React Router library and helps provide the functionality we need for native-like page transitions.

The main Ionic page will need a couple of base components. First, use a IonApp component (from @ionic/react) as the root component, and then use IonReactRouter (from @ionic/react-router).

IonApp sets up our main container, with the necessary styling needed for our structural components. IonReactRouter is a small wrapper for React Routers BrowserRouter and should be used in its place.

Then, wrap all your routes in an IonRouterOutlet, which is what manages our Ionic pages.

<IonApp>
  <IonReactRouter>
    <IonRouterOutlet>
      <Route path="/" exact component={Home} />
      <Route path="/about" exact component={About} />
    </IonRouterOutlet>
  </IonReactRouter>
</IonApp>

Now you can setup Ionic pages like so:

<IonPage>
  <IonHeader>
    <IonToolbar>
      <IonTitle>My Page</IonTitle>
    </IonToolbar>
  </IonHeader>
  <IonContent>
    <IonDatetime displayFormat="MM/DD/YYYY" placeholder="Select Date"></IonDatetime>
    <IonButton fill="clear">Start</IonButton>
  </IonContent>
</IonPage>

Note that having IonPage is important to have as the base component for your "Ionic" pages. IonPage is the element we look for to do the page transition on.

For more information on routing and navigation in Ionic React, see here.

Customize the Theme

To customize the look and feel of the components, we have some CSS variables you can override to provide a theme for your components. Set these somewhere in your main CSS file:

:root {
  --ion-color-angular: #ac282b;
  --ion-color-communication: #8e8d93;
  --ion-color-tooling: #fe4c52;
  --ion-color-services: #fd8b2d;
  --ion-color-design: #fed035;
  --ion-color-workshop: #69bb7b;
  --ion-color-food: #3bc7c4;
  --ion-color-documentation: #b16be3;
  --ion-color-navigation: #6600cc;

  --ion-color-primary: #3880ff;
  --ion-color-primary-rgb: 56, 128, 255;
  --ion-color-primary-contrast: #ffffff;
  --ion-color-primary-contrast-rgb: 255, 255, 255;
  --ion-color-primary-shade: #3171e0;
  --ion-color-primary-tint: #4c8dff;

  --ion-color-secondary: #0cd1e8;
  --ion-color-secondary-rgb: 12, 209, 232;
  --ion-color-secondary-contrast: #ffffff;
  --ion-color-secondary-contrast-rgb: 255, 255, 255;
  --ion-color-secondary-shade: #0bb8cc;
  --ion-color-secondary-tint: #24d6ea;

  --ion-color-tertiary: #7044ff;
  --ion-color-tertiary-rgb: 112, 68, 255;
  --ion-color-tertiary-contrast: #ffffff;
  --ion-color-tertiary-contrast-rgb: 255, 255, 255;
  --ion-color-tertiary-shade: #633ce0;
  --ion-color-tertiary-tint: #7e57ff;

  --ion-color-success: #10dc60;
  --ion-color-success-rgb: 16, 220, 96;
  --ion-color-success-contrast: #ffffff;
  --ion-color-success-contrast-rgb: 255, 255, 255;
  --ion-color-success-shade: #0ec254;
  --ion-color-success-tint: #28e070;

  --ion-color-warning: #ffce00;
  --ion-color-warning-rgb: 255, 206, 0;
  --ion-color-warning-contrast: #ffffff;
  --ion-color-warning-contrast-rgb: 255, 255, 255;
  --ion-color-warning-shade: #e0b500;
  --ion-color-warning-tint: #ffd31a;

  --ion-color-danger: #f04141;
  --ion-color-danger-rgb: 245, 61, 61;
  --ion-color-danger-contrast: #ffffff;
  --ion-color-danger-contrast-rgb: 255, 255, 255;
  --ion-color-danger-shade: #d33939;
  --ion-color-danger-tint: #f25454;

  --ion-color-dark: #222428;
  --ion-color-dark-rgb: 34, 34, 34;
  --ion-color-dark-contrast: #ffffff;
  --ion-color-dark-contrast-rgb: 255, 255, 255;
  --ion-color-dark-shade: #1e2023;
  --ion-color-dark-tint: #383a3e;

  --ion-color-medium: #989aa2;
  --ion-color-medium-rgb: 152, 154, 162;
  --ion-color-medium-contrast: #ffffff;
  --ion-color-medium-contrast-rgb: 255, 255, 255;
  --ion-color-medium-shade: #86888f;
  --ion-color-medium-tint: #a2a4ab;

  --ion-color-light: #f4f5f8;
  --ion-color-light-rgb: 244, 244, 244;
  --ion-color-light-contrast: #000000;
  --ion-color-light-contrast-rgb: 0, 0, 0;
  --ion-color-light-shade: #d7d8da;
  --ion-color-light-tint: #f5f6f9;
}

For more info on theming your Ionic app, see the guide here.

Wrapping up

Adding Ionic React to an existing React project is fairly simple and can be done in just a few minutes.

The great thing about using individual components from Ionic React is that you only import the component you need. Each component is lazy loaded at runtime so that it won't bloat your bundle size. This makes Ionic React ideal for adding it to existing projects that need to look and work great on mobile devices.

Discussion (7)

pic
Editor guide
Collapse
rockinrone profile image
Ronny Ewanek

While attempting to do this, I keep getting the following TS error from imported ionic components such as IonApp, IonContent, and IonButton, but not from IonModal:

Property 'translate' is missing in type '{ children: Element[]; }' but required in type 'Pick

¯_(ツ)_/¯

I've imported the all the CSS .

Collapse
elylucas profile image
Ely Lucas Author

try updating the @types/react and @types/react-dom to the latest and see if that helps.

Collapse
rockinrone profile image
Ronny Ewanek

No luck.

This is an existing React app built with TS. Please let me know if I can provide more info to be helpful!

Thread Thread
elylucas profile image
Ely Lucas Author

hmm, could you get me the versions of the follow:

@ionic/react
react
react-dom
@types/react
@types/react-dom?

Thanks for helping troubleshoot!

Thread Thread
rockinrone profile image
Ronny Ewanek • Edited

"@ionic/react": "^5.0.5",
"@ionic/react-router": "^5.0.5",
"react": "^16.9.0",
"react-dom": "^16.10.2",
"@types/react": "^16.9.2",
"@types/react-dom": "^16.9.0",

github.com/ionic-team/ionic/issues...

Collapse
jdnichollsc profile image
Juan David Nicholls Cardona

Any example using ionic icons? I'm getting errors like this: "Mirage: Your app tried to GET 'data:image/svg+xml;utf8,<svg xmlns='http:..."

Thanks in advance!

Collapse
jdnichollsc profile image
Juan David Nicholls Cardona

Nevermind, it was an issue with miragejs, fixed with this config:
this.pretender.get('data:image/*', this.pretender.passthrough);

Cheers!