ionic-vue
Guides the agent through Ionic Vue development patterns — project structure, Vue-specific Ionic components (IonPage, IonRouterOutlet, IonTabs), navigation with Vue Router and useIonRouter, Ionic lifecycle hooks (onIonViewWillEnter, onIonViewDidEnter, onIonViewWillLeave, onIonViewDidLeave), composable utilities (useIonRouter, useBackButton, useKeyboard), tab-based routing, lazy loading, platform detection with isPlatform, and troubleshooting common Vue-specific issues. Do not use for general Ionic component theming or CLI usage (use ionic-app-development), creating a new Ionic app (use ionic-app-creation), Capacitor-specific Vue patterns without Ionic (use capacitor-vue), upgrading Ionic versions (use ionic-app-upgrades), or non-Vue frameworks like Angular or React.
Works with
Agent Skills format with YAML frontmatter. Claude Code reads it as-is.
---
name: "ionic-vue"
description: "Guides the agent through Ionic Vue development patterns — project structure, Vue-specific Ionic components (IonPage, IonRouterOutlet, IonTabs), navigation with Vue Router and useIonRouter, Ionic lifecycle hooks (onIonViewWillEnter, onIonViewDidEnter, onIonViewWillLeave, onIonViewDidLeave), composable utilities (useIonRouter, useBackButton, useKeyboard), tab-based routing, lazy loading, platform detection with isPlatform, and troubleshooting common Vue-specific issues. Do not use for general Ionic component theming or CLI usage (use ionic-app-development), creating a new Ionic app (use ionic-app-creation), Capacitor-specific Vue patterns without Ionic (use capacitor-vue), upgrading Ionic versions (use ionic-app-upgrades), or non-Vue frameworks like Angular or React."
license: "MIT"
---
# Ionic Vue
Develop Ionic apps with Vue — project structure, components, navigation, lifecycle hooks, composables, and Vue-specific patterns.
## Prerequisites
1. **Ionic Framework 7 or 8** with `@ionic/vue`.
2. **Vue 3**.
3. Node.js and npm installed.
4. For **iOS**: Xcode installed.
5. For **Android**: Android Studio installed.
## Agent Behavior
- **Auto-detect before asking.** Check the project for `package.json` dependencies (`@ionic/vue`, `vue`, `@capacitor/core`), platforms (`android/`, `ios/`), build tools (`vite.config.ts`), and TypeScript usage. Only ask the user when something cannot be detected.
- **Guide step-by-step.** Walk the user through the process one step at a time. Never present multiple unrelated questions at once.
- **Adapt to the project.** Detect whether the project uses `<script setup>` (Composition API) or Options API and generate code that matches the existing style. Default to `<script setup lang="ts">` for new files unless the project uses a different pattern.
## Procedures
### Step 1: Analyze the Project
Auto-detect the following by reading project files:
1. **Ionic version**: Read `@ionic/vue` version from `package.json`.
2. **Vue version**: Read `vue` version from `package.json`.
3. **Capacitor version**: Read `@capacitor/core` version from `package.json` (if present).
4. **TypeScript**: Check if `tsconfig.json` exists and if `.vue` files use `<script setup lang="ts">`.
5. **Platforms**: Check which directories exist (`android/`, `ios/`).
6. **Router config**: Locate the router file (typically `src/router/index.ts`).
7. **Project template**: Determine if the project uses tabs, side-menu, or blank template by examining the router configuration and `App.vue`.
### Step 2: Project Structure
A standard Ionic Vue project follows this structure:
```
project-root/
├── android/ # Android native project (generated by Capacitor)
├── ios/ # iOS native project (generated by Capacitor)
├── public/
├── src/
│ ├── components/ # Reusable Vue components
│ ├── composables/ # Custom composables
│ ├── router/
│ │ └── index.ts # Vue Router configuration (uses @ionic/vue-router)
│ ├── theme/
│ │ └── variables.css # Ionic CSS custom properties
│ ├── views/ # Page components (routed views)
│ ├── App.vue # Root component (contains IonApp + IonRouterOutlet)
│ └── main.ts # Entry point (installs IonicVue plugin)
├── capacitor.config.ts # Capacitor configuration
├── package.json
├── tsconfig.json
└── vite.config.ts
```
If the project does not follow this structure, adapt all guidance to the project's actual directory layout. Do **not** restructure the project unless the user explicitly asks.
### Step 3: App Entry Point and Root Component
The entry point `src/main.ts` installs the IonicVue plugin and mounts the app:
```typescript
import { createApp } from 'vue';
import { IonicVue } from '@ionic/vue';
import App from './App.vue';
import router from './router';
/* Ionic CSS */
import '@ionic/vue/css/core.css';
import '@ionic/vue/css/normalize.css';
import '@ionic/vue/css/structure.css';
import '@ionic/vue/css/typography.css';
import '@ionic/vue/css/padding.css';
import '@ionic/vue/css/float-elements.css';
import '@ionic/vue/css/text-alignment.css';
import '@ionic/vue/css/text-transformation.css';
import '@ionic/vue/css/flex-utils.css';
import '@ionic/vue/css/display.css';
/* Theme */
import './theme/variables.css';
const app = createApp(App).use(IonicVue).use(router);
router.isReady().then(() => {
app.mount('#app');
});
```
The root `App.vue` contains `IonApp` and `IonRouterOutlet`:
```vue
<template>
<ion-app>
<ion-router-outlet />
</ion-app>
</template>
<script setup lang="ts">
import { IonApp, IonRouterOutlet } from '@ionic/vue';
</script>
```
### Step 4: Components and IonPage
Read `references/components.md` for detailed component patterns.
Key rules:
1. **Import all Ionic components** from `@ionic/vue` — e.g., `import { IonButton, IonContent, IonPage } from '@ionic/vue'`.
2. **Every routed page must use `IonPage`** as its root template element. Without it, page transitions break and Ionic lifecycle hooks do not fire.
3. **Access Web Component methods via `$el`** — e.g., `contentRef.value.$el.scrollToBottom(300)`.
4. **Import icons as SVG references** from `ionicons/icons` — never pass icon names as strings.
5. **Use `v-model`** on Ionic form components (`IonInput`, `IonToggle`, `IonSelect`, `IonCheckbox`, `IonRange`).
6. **Use kebab-case** for Ionic event names in templates — e.g., `@ion-change`, `@ion-infinite`.
### Step 5: Navigation and Routing
Read `references/navigation.md` for detailed routing patterns.
Key principles:
1. **Import `createRouter` from `@ionic/vue-router`**, not from `vue-router`. The Ionic version wraps Vue Router to enable page transitions.
2. **Declarative navigation**: Use `router-link` attribute on Ionic components with optional `router-direction` and `router-animation`.
3. **Programmatic navigation**: Use the `useIonRouter` composable for Ionic-specific transitions, or `useRouter` from `vue-router` for standard navigation.
4. **Lazy load routes** with `component: () => import('@/views/DetailPage.vue')`.
5. **Tab routing**: Use nested routes with `IonTabs` and `IonRouterOutlet`. Each tab maintains its own navigation stack.
6. **Never cross-route between tabs** — only tab bar buttons should switch tabs. Use `IonModal` for views shared across tabs.
### Step 6: Lifecycle Hooks
Read `references/lifecycle.md` for detailed lifecycle patterns.
Key principles:
1. `IonRouterOutlet` keeps pages in the DOM. Vue's `onMounted` fires only once per page, not on every visit.
2. Use Ionic lifecycle hooks to run logic on every page visit:
- `onIonViewWillEnter` — Refresh data every time the page appears.
- `onIonViewDidEnter` — Start animations or focus inputs after the page transition finishes.
- `onIonViewWillLeave` — Save state or unsubscribe.
- `onIonViewDidLeave` — Clean up off-screen resources.
3. Ionic lifecycle hooks require `IonPage` as the root element.
4. Only router-mapped components receive lifecycle hooks — child components do not.
### Step 7: Composables and Utilities
Read `references/composables.md` for detailed composable documentation.
Available composables and utilities from `@ionic/vue`:
| Function | Purpose |
|----------|---------|
| `useIonRouter()` | Programmatic navigation with transition control |
| `useBackButton(priority, handler)` | Handle Android hardware back button |
| `useKeyboard()` | Reactive keyboard visibility and height |
| `onIonViewWillEnter(cb)` | Lifecycle: page about to show |
| `onIonViewDidEnter(cb)` | Lifecycle: page fully visible |
| `onIonViewWillLeave(cb)` | Lifecycle: page about to hide |
| `onIonViewDidLeave(cb)` | Lifecycle: page fully hidden |
| `isPlatform(name)` | Check current platform (`ios`, `android`, `hybrid`, etc.) |
| `getPlatforms()` | Get array of all matching platform identifiers |
### Step 8: Platform Detection
Use `isPlatform` from `@ionic/vue` to conditionally execute platform-specific logic:
```vue
<script setup lang="ts">
import { isPlatform } from '@ionic/vue';
const isIOS = isPlatform('ios');
const isAndroid = isPlatform('android');
const isNative = isPlatform('hybrid');
const isMobileWeb = isPlatform('mobileweb');
</script>
<template>
<div>
<p v-if="isNative">Running as a native app</p>
<p v-else>Running in a browser</p>
</div>
</template>
```
Supported identifiers: `android`, `capacitor`, `cordova`, `desktop`, `electron`, `hybrid`, `ios`, `ipad`, `iphone`, `mobile`, `mobileweb`, `phablet`, `pwa`, `tablet`.
### Step 9: Build and Run
After implementing changes:
```bash
npm run build
npx cap sync
npx cap run android
npx cap run ios
```
For development with live reload:
```bash
ionic serve
```
For native live reload:
```bash
ionic cap run android --livereload --external
ionic cap run ios --livereload --external
```
## Error Handling
- **`Failed to resolve component: ion-*`**: The Ionic component is not imported. Add the missing import from `@ionic/vue` in the `<script>` section (e.g., `import { IonButton } from '@ionic/vue'`).
- **Page transitions not working**: Verify that the page component uses `IonPage` as its root template element. Without `IonPage`, transitions and lifecycle hooks silently fail.
- **Ionic lifecycle hooks not firing**: Ensure `IonPage` is the root element and the component is directly mapped to a route in the router configuration. Lifecycle hooks do not fire on child components.
- **`Method on component is not a function`**: Access the underlying Web Component via `$el` — e.g., `ref.value.$el.scrollToBottom()`, not `ref.value.scrollToBottom()`.
- **Slot attribute deprecation warning**: Ionic uses Web Component slots, which linters misidentify as deprecated Vue 2 slots. Disable the ESLint rule: `'vue/no-deprecated-slot-attribute': 'off'`.
- **Event listeners not firing**: Use kebab-case event names in templates (`ion-modal-did-present`) and in `addEventListener` calls. Do not use camelCase.
- **`useIonRouter` or `useBackButton` fails**: These composables use Vue's `inject()` internally and must be called inside `setup()` or `<script setup>`, not in standalone functions or callbacks.
- **Tab navigation loses state**: Each tab maintains its own stack. Do not use `router.go()` with non-linear (tab-based) routing. Use `useIonRouter().push()` or `router-link` instead.
- **Vue `onMounted` fires only once**: `IonRouterOutlet` caches pages in the DOM. Use `onIonViewWillEnter` instead of `onMounted` for logic that must run every time the page is shown.
- **Content overlaps tab bar or header**: The page component is missing `IonPage` as the root element. `IonPage` sets up the proper flexbox layout.
## Related Skills
- **`ionic-app-development`** — General Ionic development guidance: components, theming, CLI usage.
- **`ionic-app-creation`** — Create a new Ionic app from scratch.
- **`capacitor-vue`** — Capacitor-specific Vue patterns (plugins, hooks, services) without Ionic Framework.
- **`ionic-app-upgrades`** — Upgrade Ionic Framework to a newer version.More Frontend Frameworks skills
frontend-design
anthropics/skills
Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
design-taste-frontend
leonxlnx/taste-skill
Anti-slop frontend skill for landing pages, portfolios, and redesigns. The agent reads the brief, infers the right design direction, and ships interfaces that do not look templated. Real design systems when applicable, audit-first on redesigns, strict pre-flight check.
hyperframes-creative
heygen-com/hyperframes
Non-animation creative direction for HyperFrames videos. Use for design spec (frame.md / design.md) handling, palettes, typography, narration, beat planning, audio-reactive visuals, composition patterns, and brand / style decisions. For atomic motion patterns and scene blueprints, use hyperframes-animation.

