Updating from Ionic 5 to 6
note
This guide assumes that you have already updated your app to the latest version of Ionic 5. Make sure you have followed the Updating to Ionic 5 Guide before starting this guide.
Breaking Changes
For a complete list of breaking changes from Ionic 5 to Ionic 6, please refer to the breaking changes document in the Ionic Framework repository.
Getting Started
Angular
- Ionic 6 supports Angular 12+. Update to the latest version of Angular by following the Angular Update Guide.
- Update to the latest version of Ionic 6:
npm install @ionic/angular@6
If you are using Ionic Angular Server, be sure to update that as well:
npm install @ionic/angular@6 @ionic/angular-server@6
- Remove any usage of
Config.set(). Instead, set your config inIonicModule.forRoot(). See the Angular Config Documentation for more examples. - Remove any usage of the
setupConfigfunction previously exported from@ionic/angular. Set your config inIonicModule.forRoot()instead.
React
- Ionic 6 supports React 17+. Update to the latest version of React:
npm install react@latest react-dom@latest
- Update to the latest version of Ionic 6:
npm install @ionic/react@6 @ionic/react-router@6
- Update the
testfield in thescriptsobject of yourpackage.jsonto includetransformIgnorePatterns:
"scripts": {
"test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons)/)'",
...
}
- Import and call
setupIonicReactin yourAppcomponent file. If you are also usingsetupConfig, pass your config tosetupIonicReactinstead:
Before
import { setupConfig } from '@ionic/react';
...
setupConfig({
mode: 'md'
});
After
import { setupIonicReact } from '@ionic/react';
...
setupIonicReact({
mode: 'md'
});
note
Developers must import and call setupIonicReact even if they are not setting custom config.
See the React Config Documentation for more examples.
- Update all controller imports from
@ionic/coreto@ionic/core/components. As an example, here is a migration formenuController:
Before
import { menuController } from '@ionic/core';
After
import { menuController } from '@ionic/core/components';
Vue
- Ionic 6 supports Vue 3.0.6+. Update to the latest version of Vue:
npm install vue@3 vue-router@4
- For apps that use the Vue CLI, install Vue CLI 5:
npm install -g @vue/cli@next
Then, upgrade all Vue CLI plugins:
vue upgrade --next
- Update to the latest version of Ionic 6:
npm install @ionic/vue@6 @ionic/vue-router@6
- Add the following
transformIgnorePatternsto eitherjest.config.jsor thejestfield inpackage.json:
module.exports = {
...
transformIgnorePatterns: ['/node_modules/(?!@ionic/vue|@ionic/vue-router|@ionic/core|@stencil/core|ionicons)']
}
{
...
"jest": {
"transformIgnorePatterns": ["/node_modules/(?!@ionic/vue|@ionic/vue-router|@ionic/core|@stencil/core|ionicons)"]
}
}
See the Testing section below for more information.
Remove any usage of the
setupConfigfunction previously exported from@ionic/vue. Set your config when installing theIonicVueplugin instead. See the Vue Config Documentation for more examples.Rename the
IonRoutertype foruseIonRoutertoUseIonRouterResult.Rename the
IonKeyboardReftype foruseKeyboardtoUseKeyboardResult.Rename any overlay event listeners to use the new format:
Before
<ion-modal
:is-open="modalOpenRef"
@onWillPresent="onModalWillPresentHandler"
@onDidPresent="onModalDidPresentHandler"
@onWillDismiss="onModalWillDismissHandler"
@onDidDismiss="onModalDidDismissHandler"
>
...
</ion-modal>
After
<ion-modal
:is-open="modalOpenRef"
@willPresent="onModalWillPresentHandler"
@didPresent="onModalDidPresentHandler"
@willDismiss="onModalWillDismissHandler"
@didDismiss="onModalDidDismissHandler"
>
...
</ion-modal>
note
This applies to ion-action-sheet, ion-alert, ion-loading, ion-modal, ion-picker, ion-popover, and ion-toast.
- Pass in an
ion-router-outletinto anyion-tabsthat are being used:
Before
<ion-tabs>
<ion-tab-bar slot="bottom"> ... </ion-tab-bar>
</ion-tabs>
<script>
import { IonTabs, IonTabBar } from '@ionic/vue';
import { defineComponent } from 'vue';
export default defineComponent({
components: { IonTabs, IonTabBar },
});
</script>
After
<ion-tabs>
<ion-router-outlet></ion-router-outlet>
<ion-tab-bar slot="bottom"> ... </ion-tab-bar>
</ion-tabs>
<script>
import { IonTabs, IonTabBar, IonRouterOutlet } from '@ionic/vue';
import { defineComponent } from 'vue';
export default defineComponent({
components: { IonTabs, IonTabBar, IonRouterOutlet },
});
</script>
- Additional routes inside of tabs should be re-written as sibling routes instead of child routes:
Before
const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: '/tabs/tab1'
},
{
path: '/tabs/',
component: Tabs,
children: [
{
path: '',
redirect: 'tab1'
},
{
path: 'tab1',
component: () => import('@/views/Tab1.vue'),
children: {
{
path: 'view',
component: () => import('@/views/Tab1View.vue')
}
}
},
{
path: 'tab2',
component: () => import('@/views/Tab2.vue')
},
{
path: 'tab3',
component: () => import('@/views/Tab3.vue')
}
]
}
]
After
const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: '/tabs/tab1',
},
{
path: '/tabs/',
component: Tabs,
children: [
{
path: '',
redirect: 'tab1',
},
{
path: 'tab1',
component: () => import('@/views/Tab1.vue'),
},
{
path: 'tab1/view',
component: () => import('@/views/Tab1View.vue'),
},
{
path: 'tab2',
component: () => import('@/views/Tab2.vue'),
},
{
path: 'tab3',
component: () => import('@/views/Tab3.vue'),
},
],
},
];
Core
- Update to the latest version of Ionic 6:
npm install @ionic/core@6
Updating Your Code
Datetime
Remove any usages of the
placeholder,pickerOptions,pickerFormat,monthNames,monthShortNames,dayNames, anddayShortNamesproperties.ion-datetimenow automatically formats the month names, day names, and time displayed inside of the component according to the language and region set on the device. See the ion-datetime Localization Documentation for more information.Remove any usages of the
textandplaceholderCSS Shadow Parts.Remove any usages of the
--padding-bottom,--padding-end,--padding-start,--padding-top, and--placeholder-colorCSS Variables. To customize the padding onion-datetime, you can use any of thepaddingCSS properties.Remove any usage of the
openmethod. To present the datetime in an overlay, place it inside of anion-modalor anion-popovercomponent. See the ion-datetime Usage Examples for more information.Remove any usage of the
displayFormatordisplayTimezoneproperties. To parse the UTC string provided in the payload of theionChangeevent, we recommend using date-fns. See the ion-datetime Parsing Dates Documentation for examples.
note
See the Datetime Migration Sample Application for more migration examples.
Icon
Ionic 6 now ships with Ionicons 6. Review the Ionicons 6 Breaking Changes Guide and make any necessary changes.
Input
Ensure null is not passed in as a value to the placeholder property. We recommend using undefined instead.
Modal
ion-modal now uses the Shadow DOM. Update any styles targeting the internals of ion-modal to use either the ion-modal CSS Variables or the ion-modal CSS Shadow Parts:
Before
ion-modal .modal-wrapper {
/* Any custom styles here */
}
ion-modal ion-backdrop {
/* Any custom styles here */
}
After
ion-modal::part(content) {
/* Any custom styles here */
}
ion-modal::part(backdrop) {
/* Any custom styles here */
}
Popover
ion-popover now uses the Shadow DOM. Update any styles targeting the internals of ion-popover to use either ion-popover CSS Variables or the ion-popover CSS Shadow Parts:
Before
ion-popover .popover-arrow {
/* Any custom styles here */
}
ion-popover ion-backdrop {
/* Any custom styles here */
}
ion-popover .popover-content {
/* Any custom styles here */
}
After
ion-popover::part(arrow) {
/* Any custom styles here */
}
ion-popover::part(backdrop) {
/* Any custom styles here */
}
ion-popover::part(content) {
/* Any custom styles here */
}
Radio
Remove any usage of the RadioChangeEventDetail interface.
Select
Ensure null is not passed in as a value to the placeholder property. We recommend using undefined instead.
Textarea
Ensure null is not passed in as a value to the placeholder property. We recommend using undefined instead.
Browser Support
The list of browsers that Ionic supports has changed. Review the Browser Support Guide to ensure you are deploying apps to supported browsers.
If you have a browserslist or .browserslistrc file, update it with the following content:
Chrome >=60
Firefox >=63
Edge >=79
Safari >=13
iOS >=13
Testing
Ionic 6 now ships as ES Modules. ES Modules are supported in all major browsers and bring developer experience and code maintenance improvements. Developers testing with Jest will need to update their Jest configuration as Jest does not have full support for ES Modules as of Jest 27.
This update involves using Babel to compile Ionic's ES Modules down to the CommonJS (CJS) format, a format that Jest can understand. Once Jest ships support for ES Modules, this change will no longer be necessary. See https://github.com/facebook/jest/issues/9430 for updates on ES Modules support in Jest.
If you are starting fresh with a new Ionic app, this configuration is done for you in our starter applications. For those with existing Ionic apps, follow the steps below to get Jest working with Ionic 6:
- Add a
transformIgnorePatternsfield to your Jest config that includes the relevant Ionic packages. This is typically found injest.config.jsor thejestfield inpackage.json:
module.exports = {
...
transformIgnorePatterns: ['/node_modules/(?!@ionic/core|@stencil/core|ionicons)']
}
{
...
"jest": {
"transformIgnorePatterns": ["/node_modules/(?!@ionic/core|@stencil/core|ionicons)"]
}
}
note
If you are using Ionic React or Ionic Vue, be sure to add the appropriate packages to the transformIgnorePatterns array. For Ionic React this includes @ionic/react and @ionic/react-router. For Ionic Vue this includes @ionic/vue and @ionic/vue-router.
For developers using Create React App (CRA), there is currently no way to update the transformIgnorePatterns in a Jest config file. This is a CRA restriction and not something Ionic has control over. We can, however, pass the transformIgnorePatterns directly into the react-scripts test command:
"scripts": {
"test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons)/)'",
...
}
If you are still running into issues, here are a couple things to try:
Verify that
@babel/preset-envis included in your project-wide configuration instead of your file-relative configuration. This typically means defining the Babel configuration in<project-root>/babel.config.json.If you have a
browserslist/testfield inpackage.jsonfile, make sure it is set tocurrent node.
Need Help Upgrading?
Be sure to look at the Ionic 6 Breaking Changes Guide. There were several changes to default property and CSS Variable values that developers may need to be aware of. Only the breaking changes that required user action are listed on this page.
If you need help upgrading, please post a thread on the Ionic Forum.