plugins/auth0/skills/auth0-spa-js/SKILL.md
Use when adding authentication to Vanilla JS, Svelte, or any framework-agnostic single-page applications - integrates @auth0/auth0-spa-js SDK for SPAs without framework-specific wrappers
npx skillsauth add auth0/agent-skills auth0-spa-jsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Add authentication to any browser-based single-page application using @auth0/auth0-spa-js — the low-level Auth0 SDK for Vanilla JS, Svelte, SolidJS, and any SPA not using React, Angular, or Vue.
Agent instruction: Before providing SDK setup instructions, fetch the latest release version by running:
gh api repos/auth0/auth0-spa-js/releases/latest --jq '.tag_name'Use the returned version in all dependency lines instead of any hardcoded version below. If the command fails, fall back to checking https://github.com/auth0/auth0-spa-js/releases.
npm install @auth0/auth0-spa-js
Or via CDN (no bundler). Run this to get the latest version, then use it in your HTML:
VERSION=$(npm view @auth0/auth0-spa-js version)
<script src="https://cdn.auth0.com/js/auth0-spa-js/$VERSION/auth0-spa-js.production.js"></script>
For automated setup with Auth0 CLI, see Setup Guide for complete scripts.
For manual setup, create .env (Vite):
VITE_AUTH0_DOMAIN=your-tenant.auth0.com
VITE_AUTH0_CLIENT_ID=your-client-id
In Auth0 Dashboard, set for your Single Page Application:
http://localhost:5173http://localhost:5173http://localhost:5173import { createAuth0Client } from '@auth0/auth0-spa-js';
const auth0 = await createAuth0Client({
domain: import.meta.env.VITE_AUTH0_DOMAIN,
clientId: import.meta.env.VITE_AUTH0_CLIENT_ID,
authorizationParams: {
redirect_uri: window.location.origin
}
});
// Handle redirect callback after login
const query = new URLSearchParams(window.location.search);
if ((query.has('code') || query.has('error')) && query.has('state')) {
await auth0.handleRedirectCallback();
window.history.replaceState({}, document.title, window.location.pathname);
}
Agent instruction: Before adding new UI elements, search the project for existing click handlers for login, logout, sign-in, or sign-out buttons. If existing handlers are found, hook the Auth0 code into them without modifying the existing UI. Only create new buttons if no existing handlers are found.
// Login
document.getElementById('login-btn').addEventListener('click', async () => {
await auth0.loginWithRedirect();
});
// Logout
document.getElementById('logout-btn').addEventListener('click', () => {
auth0.logout({
logoutParams: { returnTo: window.location.origin }
});
});
// Update UI based on auth state
const isAuthenticated = await auth0.isAuthenticated();
if (isAuthenticated) {
const user = await auth0.getUser();
console.log(user.name, user.email);
}
const accessToken = await auth0.getTokenSilently();
const response = await fetch('https://your-api.example.com/data', {
headers: { Authorization: `Bearer ${accessToken}` }
});
Agent instruction: After completing the integration, build the project to verify it compiles successfully:
npm run buildIf the build fails, analyze the error output and fix the issues. Common integration build failures include:
- Module not found: Missing
npm install @auth0/auth0-spa-js— run the install command- Cannot find name 'import.meta': TypeScript target too low — set
"target": "ES2020"or higher intsconfig.jsoncreateAuth0Clientis not a function: Wrong import path or CDN usage without bundle step- Env vars undefined at runtime: Vite requires
VITE_prefix; webpack/CRA requiresREACT_APP_prefixRe-run the build after each fix. Track the number of build-fix iterations.
Failcheck: If the build still fails after 5–6 fix attempts, stop and ask the user using
AskUserQuestion: "The build is still failing after several fix attempts. How would you like to proceed?"
- Let the skill continue fixing iteratively — continue the build-fix loop for another 5–6 attempts
- Fix it manually — show the remaining errors and let the user resolve them
- Skip build verification — proceed without a successful build
.env configuration, callback URL setup| Mistake | Fix |
|---------|-----|
| Callback URL port mismatch (e.g., localhost:3001 vs localhost:5173) | Match Allowed Callback URLs exactly to your dev server port in Auth0 Dashboard |
| client_secret in SPA code | SPAs must never have a client secret — remove it. Auth0 sets auth method to None for SPA apps |
| Tokens stored in localStorage | Use in-memory storage (default) or sessionStorage. Never localStorage — XSS risk |
| getTokenSilently() throws login_required on page refresh | Add your app origin to Allowed Web Origins in Auth0 Dashboard |
| handleRedirectCallback() not called after redirect | Must call after login redirect to exchange the auth code; without this the URL params persist and re-trigger |
| Domain includes https:// prefix | Auth0 domain should be hostname only: your-tenant.auth0.com, not https://your-tenant.auth0.com |
| loginWithPopup() called from async init code | Popups must be triggered directly from a user gesture (click handler). Never call from init or page load code |
| Using Auth0Provider from @auth0/auth0-react in Vanilla JS | For Vanilla JS, use createAuth0Client() directly — no provider component needed |
| Method | Description |
|--------|-------------|
| createAuth0Client(options) | Create and initialize client (calls checkSession internally) |
| new Auth0Client(options) | Instantiate without auto session check |
| auth0.loginWithRedirect(options?) | Redirect to Auth0 Universal Login |
| auth0.loginWithPopup(options?) | Open Auth0 login in a popup |
| auth0.logout(options?) | Clear session and redirect |
| auth0.handleRedirectCallback(url?) | Process redirect result after login |
| auth0.isAuthenticated() | Promise<boolean> |
| auth0.getUser() | Promise<User \| undefined> |
| auth0.getTokenSilently(options?) | Promise<string> — access token |
| auth0.checkSession() | Attempt silent re-authentication |
development
Use when adding login, logout, and user profile to a Laravel web application using session-based authentication - integrates auth0/login (laravel-auth0) for guard-based auth with auto-registered routes.
tools
Use when securing Laravel API endpoints with JWT Bearer token validation, scope/permission checks, or stateless auth - integrates auth0/login (laravel-auth0) with the AuthorizationGuard for REST APIs receiving access tokens from SPAs, mobile apps, or other clients. Triggers on: Laravel API auth, auth0.authorizer, AuthorizationGuard, Laravel JWT, stateless Bearer.
development
Use when adding Auth0 authentication to a Flutter web application — integrates the auth0_flutter SDK (web platform) for browser-based authentication using redirect login, popup login, and credential caching.
development
Use when adding Auth0 authentication to a Flutter mobile application (iOS/Android) — integrates the auth0_flutter SDK (native platform) for Web Auth login/logout via the system browser, with secure credential storage and biometric protection through the CredentialsManager.