
auth0-ionic-vue
โ 37by auth0 ยท part of auth0/agent-skills
Use when adding Auth0 login, logout, or deep linking to an Ionic Vue app with Capacitor. Integrates @auth0/auth0-vue with Capacitor Browser and App plugins for native iOS/Android.
This is the playbook your agent receives when the skill activates โ you don't need to read it to use the skill, but it's here to audit before installing.
Auth0 Ionic Vue (Capacitor) Integration
Add Auth0 authentication to Ionic Vue applications using Capacitor. This skill covers native mobile authentication using the @auth0/auth0-vue SDK combined with @capacitor/browser and @capacitor/app plugins for deep link handling on iOS and Android.
When NOT to Use
| Use Case | Recommended Skill |
|---|---|
| Vue SPA (no Capacitor/Ionic) | auth0-vue |
| React SPA (no Capacitor/Ionic) | auth0-react |
| React Native (bare CLI) | auth0-react-native |
| Expo (React Native) | auth0-expo |
| Ionic + React + Capacitor | auth0-ionic-react |
| Ionic + Angular + Capacitor | auth0-ionic-angular |
| Next.js (server-side) | auth0-nextjs |
| Nuxt (server-side) | auth0-nuxt |
| iOS native (Swift) | auth0-swift |
| Android native (Kotlin) | auth0-android |
Detailed Documentation
- Setup Guide โ Auth0 CLI automated setup (login, app creation, credential injection), Capacitor URL scheme registration, secret management
- Integration Patterns โ Login/logout with Capacitor Browser, deep link callback handling, user profile, protected routes, token access, error handling
- Testing & Reference โ Full API reference for createAuth0 options, useAuth0 composable, Capacitor plugin configuration, testing checklist, common issues
WebAuth Method
This SDK uses Auth0's Universal Login (WebAuth) via the Capacitor Browser plugin. The loginWithRedirect() method opens the Auth0 authorization endpoint in a system browser (SFSafariViewController on iOS, Chrome Custom Tabs on Android). After authentication, Auth0 redirects back to the app using a native callback URL with a custom scheme: {packageId}://{domain}/capacitor/{packageId}/callback. The @capacitor/app plugin captures this deep link, and handleRedirectCallback(url) processes the authorization code exchange.
Unlike standard native SDKs that use https://{domain}/android/{packageId}/callback or https://{domain}/ios/{bundleId}/callback, Ionic Capacitor apps use the Capacitor-specific callback path with the package ID as the URL scheme.
Related Skills
- auth0-vue โ Vue SPA (browser-only, no Capacitor)
- auth0-ionic-react โ Ionic with React and Capacitor
- auth0-ionic-angular โ Ionic with Angular and Capacitor
- auth0-react-native โ React Native (bare CLI, no Ionic/Capacitor)
- auth0-expo โ Expo (React Native) with Auth0
Quick Reference
| API | Description |
|---|---|
createAuth0(options) | Vue plugin factory โ registers Auth0 with app.use() |
useAuth0() | Composable โ returns { isLoading, isAuthenticated, user, loginWithRedirect, logout, getAccessTokenSilently, handleRedirectCallback, error } |
loginWithRedirect({ openUrl }) | Login via Universal Login โ use Browser.open() in openUrl callback |
logout({ logoutParams, openUrl }) | Logout โ use Browser.open() in openUrl callback |
handleRedirectCallback(url) | Process Auth0 callback URL from deep link |
getAccessTokenSilently() | Get access token (uses refresh tokens on mobile) |
createAuthGuard(app) | Vue Router navigation guard factory for protected routes |
Browser.open({ url }) | Capacitor โ opens URL in system browser (SFSafariViewController / Chrome Custom Tabs) |
CapApp.addListener('appUrlOpen', cb) | Capacitor โ listens for deep link events |
Browser.close() | Capacitor โ closes the in-app browser after callback |
References
npx skills add https://github.com/auth0/agent-skills --skill auth0-ionic-vueRun this in your project โ your agent picks the skill up automatically.
Prerequisites
- Node.js 18+
- Ionic CLI (
npm install -g @ionic/cli) - An existing Ionic Vue application with Capacitor configured
- Auth0 account and tenant
- For iOS: Xcode 14+ and CocoaPods
- For Android: Android Studio with API level 21+
- Auth0 CLI โ
brew install auth0/auth0-cli/auth0
Quick Start Workflow
Step 1: Configure Auth0
For automated setup with Auth0 CLI, see Setup Guide for complete scripts.
For manual setup, configure a Native application in the Auth0 Dashboard and note your Domain and Client ID.
Step 2: Install Dependencies
npm install @auth0/auth0-vue @capacitor/browser @capacitor/app
npx cap syncStep 3: Set Up Auth0 Plugin
Agent instruction: If Step 1 already wrote
.envand updatedsrc/main.ts, verify the configuration looks correct and skip to Step 4. Only use the template below if configuring manually.
Register the Auth0 Vue plugin in your app entry point (src/main.ts), configuring it for Capacitor. Credentials are read from .env via import.meta.env:
import { createApp } from 'vue';
import { createAuth0 } from '@auth0/auth0-vue';
import { IonicVue } from '@ionic/vue';
import App from './App.vue';
import router from './router';
// Agent: read appId from capacitor.config.ts and replace this value
const packageId = "YOUR_PACKAGE_ID";
const app = createApp(App);
app.use(IonicVue);
app.use(router);
app.use(
createAuth0({
domain: import.meta.env.VITE_AUTH0_DOMAIN,
clientId: import.meta.env.VITE_AUTH0_CLIENT_ID,
useRefreshTokens: true,
useRefreshTokensFallback: false,
authorizationParams: {
redirect_uri: `${packageId}://${import.meta.env.VITE_AUTH0_DOMAIN}/capacitor/${packageId}/callback`
}
})
);
router.isReady().then(() => {
app.mount('#app');
});Step 4: Implement Login with Capacitor Browser
<script setup lang="ts">
import { useAuth0 } from '@auth0/auth0-vue';
import { Browser } from '@capacitor/browser';
import { IonButton } from '@ionic/vue';
const { loginWithRedirect } = useAuth0();
const login = async () => {
await loginWithRedirect({
async openUrl(url: string) {
await Browser.open({ url, windowName: "_self" });
}
});
};
</script>
<template>
<ion-button @click="login">Log in</ion-button>
</template>Step 5: Handle Callback via Deep Link
Handle the deep link callback in your App.vue component. This must run on app initialization:
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue';
import { useAuth0 } from '@auth0/auth0-vue';
import { App as CapApp } from '@capacitor/app';
import { Browser } from '@capacitor/browser';
import { IonApp, IonRouterOutlet } from '@ionic/vue';
const { handleRedirectCallback } = useAuth0();
let urlOpenListener: any;
onMounted(async () => {
urlOpenListener = await CapApp.addListener('appUrlOpen', async ({ url }) => {
if (url.includes('state') && (url.includes('code') || url.includes('error'))) {
await handleRedirectCallback(url);
}
await Browser.close();
});
});
onUnmounted(() => {
urlOpenListener?.remove();
});
</script>
<template>
<ion-app>
<ion-router-outlet />
</ion-app>
</template>Step 6: Implement Logout
<script setup lang="ts">
import { useAuth0 } from '@auth0/auth0-vue';
import { Browser } from '@capacitor/browser';
import { IonButton } from '@ionic/vue';
const domain = import.meta.env.VITE_AUTH0_DOMAIN;
// Agent: read appId from capacitor.config.ts and replace this value
const packageId = "YOUR_PACKAGE_ID";
const logoutUri = `${packageId}://${domain}/capacitor/${packageId}/callback`;
const { logout } = useAuth0();
const doLogout = async () => {
await logout({
logoutParams: {
returnTo: logoutUri
},
async openUrl(url: string) {
await Browser.open({ url, windowName: "_self" });
}
});
};
</script>
<template>
<ion-button @click="doLogout">Log out</ion-button>
</template>Step 7: Build and Test
Agent instruction: After integration, verify the build:
ionic build npx cap syncFor iOS:
npx cap open iosthen build in Xcode. For Android:npx cap open androidthen build in Android Studio. If the build fails, iterate up to 5-6 times to fix issues. If still failing, useAskUserQuestionto request help.
Common Mistakes
| Mistake | Fix |
|---|---|
| App type not set to Native in Auth0 Dashboard | Change application type to "Native" in Dashboard settings |
| Missing or incorrect callback URL format | Use YOUR_PACKAGE_ID://YOUR_DOMAIN/capacitor/YOUR_PACKAGE_ID/callback โ must match exactly |
| Not enabling refresh tokens | Set useRefreshTokens: true and useRefreshTokensFallback: false in createAuth0() |
Missing @capacitor/browser or @capacitor/app | Install both: npm install @capacitor/browser @capacitor/app && npx cap sync |
| Not handling deep link callback | Add CapApp.addListener('appUrlOpen', ...) to process Auth0 redirect |
Forgetting npx cap sync after install | Always run npx cap sync after installing Capacitor plugins |
Using window.location.origin as redirect URI | Use the custom URL scheme (packageId://domain/...), not http://localhost |
| Missing Allowed Origins in Dashboard | Add capacitor://localhost, http://localhost to Allowed Origins |
Not calling app.use(createAuth0(...)) before mount | Register Auth0 plugin before calling app.mount('#app') |
Accessing .value incorrectly on auth refs | useAuth0() returns Vue refs โ use .value in <script>, template unwraps automatically |
| localStorage treated as persistent on mobile | Use refresh tokens (useRefreshTokens: true) for reliable token persistence |
Licensed under Apache-2.0โ you can use, modify, and redistribute it under that license's terms.
View the full license file on GitHub โ