Build Options
Developers have two options for using Ionic components: Standalone or Modules. This guide covers both options as well as the benefits and downsides of each approach.
While the Standalone approach is newer and makes use of more modern Angular APIs, the Modules approach will continue to be supported in Ionic. Most of the Angular examples on this documentation website use the Modules approach.
Standalone
Ionic UI components as Angular standalone components is supported starting in Ionic v7.5.
Overview
Developers can use Ionic components as standalone components to take advantage of treeshaking and newer Angular features. This option involves importing specific Ionic components in the Angular components you want to use them in. Developers can use Ionic standalone components even if their Angular application is NgModule-based.
See the Standalone Migration Guide for instructions on how to update your Ionic app to make use of Ionic standalone components.
Benefits
- Enables treeshaking so the final build output only includes the code necessary to run your app which reduces overall build size.
- Avoids the use of NgModules to streamline the development experience and make your code easier to understand.
- Allows developers to also use newer Angular features such as ESBuild.
Drawbacks
- Ionic components need to be imported into every Angular component they are used in which can be time consuming to set up.
Usage with Standalone-based Applications
All Ionic imports should be imported from the @ionic/angular/standalone
submodule. This includes imports such as components, directives, providers, and types. Importing from @ionic/angular
may pull in lazy loaded Ionic code which can interfere with treeshaking.
Bootstrapping and Configuration
Ionic Angular needs to be configured when the Angular application calls bootstrapApplication
using the provideIonicAngular
function. Developers can pass any IonicConfig values as an object in this function. Note that provideIonicAngular
needs to be called even if no custom config is passed.
import { enableProdMode, importProvidersFrom } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { RouteReuseStrategy, provideRouter } from '@angular/router';
import { provideIonicAngular, IonicRouteStrategy } from '@ionic/angular/standalone';
import { routes } from './app/app.routes';
import { AppComponent } from './app/app.component';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
bootstrapApplication(AppComponent, {
providers: [
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
provideIonicAngular({ mode: 'ios' }),
provideRouter(routes),
],
});
Components
In the example below, we are importing IonContent
and IonButton
from @ionic/angular/standalone
and passing them to imports
for use in the component template. We would get a compiler error if these components were not imported and provided to the imports
array.
import { Component } from '@angular/core';
import { IonButton, IonContent } from '@ionic/angular/standalone';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
standalone: true,
imports: [IonButton, IonContent],
})
export class HomePage {
constructor() {}
}
Icons
The icon SVG data needs to be defined in the Angular component so it can be loaded correctly. Developers can use the addIcons
function from ionicons
to map the SVG data to a string name. Developers can then reference the icon by its string name using the name
property on IonIcon
.
We recommend calling addIcons
in the Angular component constructor
so the data is only added if the Angular component is being used.
For developers using Ionicons 7.2 or newer, passing only the SVG data will cause the string name to be automatically generated.
import { Component } from '@angular/core';
import { IonIcon } from '@ionic/angular/standalone';
import { addIcons } from 'ionicons';
import { logoIonic } from 'ionicons/icons';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
standalone: true,
imports: [IonIcon],
})
export class HomePage {
constructor() {
/**
* On Ionicons 7.2+ this icon
* gets mapped to a "logo-ionic" key.
* Alternatively, developers can do:
* addIcons({ 'logo-ionic': logoIonic });
*/
addIcons({ logoIonic });
}
}
Icons can also be registered in entry points such as app.component.ts
to avoid the need to call addIcons
multiple times. Developers should be aware that the initial application chunk may increase because the registered icons will need to be loaded at application start. However, if your application uses a small number of icons the impact of this may be minimal.
import { Component } from '@angular/core';
import { addIcons } from 'ionicons';
import { logoIonic } from 'ionicons/icons';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
standalone: true,
})
export class AppComponent {
constructor() {
/**
* Any icons you want to use in your application
* can be registered in app.component.ts and then
* referenced by name anywhere in your application.
*/
addIcons({ logoIonic });
}
}
Icons registered in an application entry point can then be referenced by name anywhere in the application.
<!--
logoIonic was registered in app.component.ts instead of home.page.ts,
but it can still be used in home.page.html.
-->
<ion-icon name="logo-ionic"></ion-icon>
Routing
Developers who wish to use routerLink
, routerAction
, or routerDirection
on Ionic components should import the IonRouterLink
directive. Developers who wish to use these routing features on anchor (<a>
) elements should import IonRouterLinkWithHref
instead.
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { IonButton, IonRouterLink } from '@ionic/angular/standalone';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
standalone: true,
imports: [
IonButton,
RouterLink, // required to get base routerLink behavior for @angular/router
IonRouterLink, // use IonRouterLinkWithHref if you are using an <a> element instead
],
})
export class HomePage {}
<ion-button routerLink="/foo" routerDirection="root">Go to Foo Page</ion-button>
Testing
Ionic Angular's standalone components use ES Modules. As a result, developers using Jest should ensure that ES Modules are transpiled to a format that Jest can use. Developers using Jest should add the following to their Jest config:
- npm
- pnpm
"transformIgnorePatterns": ["<rootDir>/node_modules/(?!(@ionic/angular|@ionic/core|ionicons|@stencil/core|@angular/*)/)"]