ionic
Ionic / Capacitor Conventions
An Ionic app is an Angular app in a native (Capacitor) shell: the framework rules live in angular-conventions and the language baseline in typescript - load both. This skill is the Ionic/Capacitor-specific layer of house policy. In-app navigation and the page lifecycle are owned here in references/navigation-and-lifecycle.md; broader Ionic UI mechanics (component APIs, theming) are fetched live via context7 or the Ionic docs, not vendored. Per-plugin install/config is fetched live (context7 or the plugin's README); the durable plugin-sourcing and typed-service-wrapping guidance is here in this skill. Cutting a release - the build, signing, store submission, OTA, and release CI - is capacitor-release. Security-hardening the native surface - Keychain/Keystore secret storage, permission least-privilege, cleartext and WebView lockdown, deep-link input trust - is mobile-security. Version floors, the per-major deltas that bite, and the Ionic + Capacitor upgrade paths live in references/versions.md.
Components and structure
- Standalone components + signals, OnPush, new control flow - same as
angular-conventions. Ionic components (IonContent,IonList, ...) are standalone imports, not a shared module. - Theme through Ionic CSS variables and
color/mode, not hardcoded colors; keep design tokens in one place. Respect the system light/dark setting. - Handle safe-area / edge-to-edge insets with the CSS
env(safe-area-inset-*)variables (Ionic's--ion-safe-area-*), never fixed padding - Capacitor 8 draws content under the status and navigation bars by default (it droppedadjustMarginsForEdgeToEdgefor a System Bars core plugin plus these CSS variables), so pad it back with the insets; the System Bars plugin API is fetched live. - Dark mode is a palette you opt into, not per-component overrides: import Ionic's dark palette and choose the strategy - follow the OS (system) or an app toggle (the ion-palette-dark class on the root). Theme off the palette's CSS variables; never hand-roll dark colours per component. The v8 import files and the step-token split are in
references/versions.md. - Respect the OS accessibility settings: Ionic scales type to the device Dynamic Type / font-size setting by default (the
--ion-dynamic-fonttoken) - size with relative units and check large-text layouts, never fixedpxthat clips. Keep touch targets >= 44px and give every interactive control an accessible name. - Keep page components thin: data + state in services/stores, presentation in the page.
- Import Ionic UI components from
@ionic/angular/standaloneand bootstrap withprovideIonicAngular(), never the@ionic/angularbarrel - the barrel path pulls in lazy-loaded code that defeats tree-shaking.
Form controls - the modern syntax
- Label and validation live on the control, not slotted into
IonItem:IonInput/IonTextarea/IonSelectcarrylabel,labelPlacement,fill(outline/solid),helperText,errorText, andcounterdirectly. Ionic 8 removed the legacyIonItem-wrapped form pattern and thelegacyproperty - never author it or paste it from an old sample. - The control's
label(or an[aria-label]when it is visually labelled elsewhere) IS its accessible name - a field with neither fails the verifier's a11y gate. Build forms with typed reactiveFormGroups (perangular-conventions) and surface validation through one sharederrorTextpath, not a per-field@iferror wall.