Ionic Framework Integration with Analog
This tutorial guides you through the process of integrating Ionic Framework within your Analog application so you can leverage the power of Ionic's iOS and Android components in your applications.
Step 1: Install Ionic Framework
To begin, you need to install the @ionic/angular@latest
package. Depending on your preferred package manager, run one of the following commands:
- npm
- yarn
- pnpm
npm install @ionic/angular@latest
yarn add @ionic/angular@latest
pnpm install @ionic/angular@latest
Optional: Install Ionic Angular Toolkit for schematics
Ionic also offers a set of schematics that can help you create components following the Ionic structure. You can add them by installing the @ionic/angular-toolkit
package to your devDependencies
- npm
- yarn
- pnpm
npm install -D @ionic/angular-toolkit
yarn add -D @ionic/angular-toolkit
pnpm install -D @ionic/angular-toolkit
Optional: Install Ionicons: Ionic custom icons library
Ionic offers too, an icon library that brings more than 500 icons for most of your mobile application needs. You can install them by adding the ionicons
package to your project:
- npm
- yarn
- pnpm
npm install ionicons
yarn add ionicons
pnpm install ionicons
Step 2: Configuring Ionic Framework in your application
- Update your
vite.config.ts
file to include Ionic packages in the SSR process, adding them to thenoExternal
array. ionicons is required only if you installed the ionicons package. If you use Vitest, inline the @ionic/angular package to allow Vitest to build that package properly for Vitest.
export default defineConfig(({ mode }) => {
return {
// ...
// add these lines
ssr: {
noExternal: ['@ionic/**', '@stencil/**', 'ionicons'],
},
// ...
// add these lines if you use Vitest
test: {
server: {
deps: {
inline: ['@ionic/angular'],
},
},
},
};
});
- Add in your
app.config.ts
theprovideIonicAngular
method andIonicRouteStrategy
provider.
import { RouteReuseStrategy, provideRouter } from '@angular/router';
import {
IonicRouteStrategy,
provideIonicAngular,
} from '@ionic/angular/standalone';
export const appConfig: ApplicationConfig = {
providers: [
provideFileRouter(),
provideClientHydration(),
provideHttpClient(withFetch()),
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
provideIonicAngular(),
],
};
- Update your
app.component.ts
file to set in the template the required Ionic tags. You will need to look at Server Side Rendering caveat as Ionic doesn't yet support client hydration
import { Component } from '@angular/core';
import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone';
@Component({
selector: 'demo-root',
standalone: true,
imports: [IonApp, IonRouterOutlet],
template: `<ion-app><ion-router-outlet></ion-router-outlet></ion-app>`,
})
export class AppComponent {}
- Rename the file
styles.css
tostyles.scss
. - Set the
inlineStylesExtension
property to'scss'
in thevite.config.ts
file:
export default defineConfig(({ mode }) => {
return {
plugins: [
analog({
vite: {
inlineStylesExtension: 'scss',
},
}),
],
};
});
- Update the
index.html
file to reference the SCSS file, and to include the required meta tags for Ionic apps:
<head>
<!-- other headers -->
<link rel="stylesheet" href="/src/styles.scss" />
<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="color-scheme" content="light dark" />
<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-status-bar-style" content="black" />
</head>
<body>
<!-- content -->
</body>
- Update the
styles.scss
file to import the Ionic styles and define your custom theme:
/* Core CSS required for Ionic components to work properly */
@import '@ionic/angular/css/core.css';
/* Basic CSS for apps built with Ionic */
@import '@ionic/angular/css/normalize.css';
@import '@ionic/angular/css/structure.css';
@import '@ionic/angular/css/typography.css';
@import '@ionic/angular/css/display.css';
/* Optional CSS utils that can be commented out */
@import '@ionic/angular/css/padding.css';
@import '@ionic/angular/css/float-elements.css';
@import '@ionic/angular/css/text-alignment.css';
@import '@ionic/angular/css/text-transformation.css';
@import '@ionic/angular/css/flex-utils.css';
/**
* Ionic Dark Mode
* -----------------------------------------------------
* For more info, please see:
* https://ionicframework.com/docs/theming/dark-mode
*/
/* @import "@ionic/angular/css/palettes/dark.always.css"; */
/* @import "@ionic/angular/css/palettes/dark.class.css"; */
@import '@ionic/angular/css/palettes/dark.system.css';
Server Side Rendering Caveat
Ionic Framework doesn't support Angular's new Client Hydration, as Angular doesn't support SSR with web components, and when they are supported, work has to be done on the Stencil components to enable it. So right now there are three options to handle this:
-
Remove
provideClientHydration()
fromapp.config.ts
providers.- This removes the new client hydration mechanism from Angular and reverts to the previous one, which will cause a flicker when re-rendering the DOM from the client.
import { RouteReuseStrategy, provideRouter } from '@angular/router';
import {
IonicRouteStrategy,
provideIonicAngular,
} from '@ionic/angular/standalone';
export const appConfig: ApplicationConfig = {
providers: [
provideFileRouter(),
//provideClientHydration(), // remove this.
provideHttpClient(withFetch()),
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
provideIonicAngular(),
],
}; -
Add
ngSkipHydration
attribute to theion-app
tag.-
This will disable the client hydration mechanism for the
ion-app
element and children, but will continue to use client hydration on other elements. This will also cause a flicker in the page for the Ionic components. This is not that helpful for other elements/components as, with Ionic apps, all your Ionic components exist inside theion-app
tag.import { Component } from '@angular/core';
import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone';
@Component({
selector: 'demo-root',
standalone: true,
imports: [IonApp, IonRouterOutlet],
template: `
<ion-app ngSkipHydration>
<ion-router-outlet></ion-router-outlet>
</ion-app>
`,
})
export class AppComponent {}
-
-
Disable SSR completely
-
Disable SSR in the
vite.config.ts
file. This will eliminate the flickering but you will lose all the benefits of having SSR in your app.plugins: [
analog({
ssr: false,
}),
],
-
You must pick one of the previous options, as not configuring this will make your app throw errors on runtime, like the following:
ERROR Error: NG0500: During hydration Angular expected <ion-toolbar> but found a comment node.
Angular expected this DOM:
<ion-toolbar color="secondary">…</ion-toolbar> <-- AT THIS LOCATION
…
Actual DOM is:
<ion-header _ngcontent-ng-c1775393043="">
<!-- --> <-- AT THIS LOCATION
…
</ion-header>
Note: attributes are only displayed to better represent the DOM but have no effect on hydration mismatches.
To fix this problem:
* check the "AppComponent" component for hydration-related issues
* check to see if your template has valid HTML structure
* or skip hydration by adding the `ngSkipHydration` attribute to its host node in a template
Step 3: Adding Capacitor (Optional)
Capacitor allows you to create web native applications that can be run on iOS and Android devices with ease.
Step 3.1 Install and configure your Capacitor app
- First, you need to install the
@capacitor/core
and@capacitor/cli
packages. Depending on your preferred package manager, run one of the following commands:
- npm
- yarn
- pnpm
npm install @capacitor/core
npm install -D @capacitor/cli
yarn add @capacitor/core
yarn add -D @capacitor/cli
pnpm install @capacitor/core
pnpm install -D @capacitor/cli
- Then you have to initialize the Capacitor project with the following command. The CLI will ask you a few questions, starting with your app name, and the package ID you would like to use for your app.
npx cap init
- Update
capacitor.config.ts
webDir
property to point to the dist folder of analog build
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.ionic.capacitor',
appName: 'ionic-capacitor',
webDir: 'dist/analog/public',
};
export default config;
Step 3.2 Create your Android and iOS projects
- Install the
@capacitor/android
and/or@capacitor/ios
packages based on the platforms you want to support.
- npm
- yarn
- pnpm
npm install @capacitor/android
npm install @capacitor/ios
yarn add @capacitor/android
yarn add @capacitor/ios
pnpm install @capacitor/android
pnpm install @capacitor/ios
- Add the Android and/or iOS project to your app
npx cap add android
npx cap add ios
- Sync the project files to the installed platforms
npx cap sync
- You can run the app with the following commands
npx cap run android
npx cap run ios
That's it! You have successfully installed and configured Ionic Framework with (or without) Capacitor for your Analog application!