Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/auth0/agent-skills --skill auth0-flutter-web- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads auth0-flutter-web automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Auth0 Flutter Web Integration
auth0_flutter is the official Auth0 SDK for Flutter applications. On the web platform, it wraps the Auth0 SPA JS SDK to provide browser-based authentication via redirect or popup flows with built-in credential caching and automatic token renewal.
Agent instruction: The current SDK version is
2.1.0. Use this version in all dependency lines below. If you need to verify, runflutter pub add auth0_flutterwhich will resolve the latest compatible version automatically.
When NOT to Use
- Flutter mobile (iOS/Android): Use auth0-flutter-native — mobile uses a different platform interface with Web Auth via system browser
- Native iOS (Swift): Use auth0-swift
- Native Android (Kotlin/Java): Use auth0-android
- React SPA: Use auth0-react
- Angular SPA: Use auth0-angular
- Vue SPA: Use auth0-vue
- Node.js/Express servers: Use auth0-express
Prerequisites
- Flutter 3.24.0+
- Dart 3.5.0+
- Auth0 account — Sign up free
- Auth0 CLI — install instructions (used to create and configure the Auth0 application)
Quick Start Workflow
Agent instruction: Follow these steps in order. If you encounter an error at any step, attempt to fix it up to 5 times before calling
AskUserQuestionto ask the user for guidance. Always search existing code first — if there are existing login/logout handlers, hook into them rather than creating new ones.
Step 1 — Install SDK
Agent instruction: Check the project directory for
pubspec.yaml. If present, add the dependency. If not found, this is not a Flutter project — ask the user.Run in the project root:
flutter pub add auth0_flutterVerify the dependency was added to
pubspec.yaml:dependencies: auth0_flutter: ^2.1.0
Step 2 — Configure Auth0
Note: For Single Page Applications, the Auth0 Domain and Client ID are public configuration (not secrets). A SPA uses PKCE with no client secret, and these values ship in the browser bundle. Pass them directly to
Auth0Web(domain, clientId)— there is no need to store them in environment variables or hide them.Agent instruction:
- If Auth0 credentials (domain AND client ID) are already in the user's prompt: Proceed to Step 3 and use those values directly in the
Auth0Web(...)constructor.- If no credentials are provided: Create the application with the Auth0 CLI — do NOT ask the user to create or configure an Auth0 application manually in the Dashboard. Always use the CLI path.
Follow Setup Guide — Auth0 Configuration for the pre-flight checks and the
auth0 apps createcommand.
Step 3 — Add Auth0 SPA JS to index.html
Agent instruction:
- Locate the web entry point:
web/index.html- Add the Auth0 SPA JS script tag inside
<head>:<script src="https://cdn.auth0.com/js/auth0-spa-js/2.1/auth0-spa-js.production.js" defer></script>If
web/index.htmldoes not exist, the user may need to runflutter create . --platforms=webto add web support.
Step 4 — Configure Callback URLs
Agent instruction:
- Determine the app's web URL. For local development, default is
http://localhost:3000(when running with--web-port 3000).- Ask the user via
AskUserQuestion: "What port will you run your Flutter web app on locally? (default: 3000)"- Register the callback URLs using the Auth0 CLI (substitute real values for
CLIENT_ID,APP_URL):auth0 apps update CLIENT_ID \ --callbacks "APP_URL" \ --logout-urls "APP_URL" \ --web-origins "APP_URL" \ --no-inputFor production, also add the production URL to each list.
Step 5 — Implement Authentication
Agent instruction: Search the project for the main app entry point (
main.dart). Determine the state management approach:
- Look for
provider,riverpod,bloc,GetX, ormobximports- If none found, use basic
StatefulWidgetwithsetStateThen follow only the matching path below. If ambiguous, ask via
AskUserQuestion: "Which state management approach does your Flutter app use — Provider, Riverpod, Bloc, or basic setState?"
Basic StatefulWidget (Default)
Agent instruction: Create an
AuthServiceclass, then wire it into the app's root widget. Search for theMaterialApporCupertinoAppwidget and update accordingly.
// lib/auth_service.dart
import 'package:auth0_flutter/auth0_flutter.dart';
import 'package:auth0_flutter/auth0_flutter_web.dart';
class AuthService {
late final Auth0Web _auth0;
Credentials? _credentials;
AuthService({required String domain, required String clientId}) {
_auth0 = Auth0Web(domain, clientId);
}
bool get isAuthenticated => _credentials != null;
Credentials? get credentials => _credentials;
UserProfile? get user => _credentials?.user;
/// Call on app startup to restore session from cache
Future<void> onLoad() async {
_credentials = await _auth0.onLoad();
}
/// Redirect to Auth0 Universal Login
Future<void> loginWithRedirect({String? redirectUrl}) async {
await _auth0.loginWithRedirect(
redirectUrl: redirectUrl,
scopes: {'openid', 'profile', 'email', 'offline_access'},
);
}
/// Open Auth0 login in a popup window
Future<void> loginWithPopup() async {
_credentials = await _auth0.loginWithPopup(
scopes: {'openid', 'profile', 'email', 'offline_access'},
);
}
/// Get cached credentials (auto-refreshes if expired)
Future<Credentials> getCredentials() async {
final creds = await _auth0.credentials();
_credentials = creds;
return creds;
}
/// Check if valid credentials exist
Future<bool> hasValidCredentials() async {
return await _auth0.hasValidCredentials();
}
/// Logout and redirect back to the app
Future<void> logout({String? returnToUrl}) async {
await _auth0.logout(returnToUrl: returnToUrl);
_credentials = null;
}
}
// lib/main.dart
import 'package:flutter/material.dart';
import 'auth_service.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _authService = AuthService(
domain: 'YOUR_AUTH0_DOMAIN',
clientId: 'YOUR_AUTH0_CLIENT_ID',
);
bool _isLoading = true;
@override
void initState() {
super.initState();
_initAuth();
}
Future<void> _initAuth() async {
await _authService.onLoad();
setState(() => _isLoading = false);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: _isLoading
? const Scaffold(body: Center(child: CircularProgressIndicator()))
: _authService.isAuthenticated
? HomeScreen(authService: _authService)
: LoginScreen(authService: _authService),
);
}
}
class LoginScreen extends StatelessWidget {
final AuthService authService;
const LoginScreen({super.key, required this.authService});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => authService.loginWithRedirect(),
child: const Text('Log In'),
),
),
);
}
}
class HomeScreen extends StatelessWidget {
final AuthService authService;
const HomeScreen({super.key, required this.authService});
@override
Widget build(BuildContext context) {
final user = authService.user;
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
actions: [
IconButton(
onPressed: () => authService.logout(
returnToUrl: Uri.base.origin,
),
icon: const Icon(Icons.logout),
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (user?.pictureUrl != null)
CircleAvatar(
backgroundImage: NetworkImage(user!.pictureUrl.toString()),
radius: 40,
),
const SizedBox(height: 16),
Text('Welcome, ${user?.name ?? 'User'}!'),
Text(user?.email ?? ''),
],
),
),
);
}
}
Provider (State Management)
Agent instruction: If the project uses
provider, createAuthServiceas aChangeNotifierand inject it viaChangeNotifierProviderat the app root.
// lib/auth_service.dart
import 'package:flutter/foundation.dart';
import 'package:auth0_flutter/auth0_flutter.dart';
import 'package:auth0_flutter/auth0_flutter_web.dart';
class AuthService extends ChangeNotifier {
late final Auth0Web _auth0;
Credentials? _credentials;
bool _isLoading = true;
AuthService({required String domain, required String clientId}) {
_auth0 = Auth0Web(domain, clientId);
}
bool get isAuthenticated => _credentials != null;
bool get isLoading => _isLoading;
UserProfile? get user => _credentials?.user;
Future<void> init() async {
_credentials = await _auth0.onLoad();
_isLoading = false;
notifyListeners();
}
Future<void> loginWithRedirect() async {
await _auth0.loginWithRedirect(
scopes: {'openid', 'profile', 'email', 'offline_access'},
);
}
Future<void> loginWithPopup() async {
_credentials = await _auth0.loginWithPopup(
scopes: {'openid', 'profile', 'email', 'offline_access'},
);
notifyListeners();
}
Future<void> logout() async {
await _auth0.logout(returnToUrl: Uri.base.origin);
_credentials = null;
notifyListeners();
}
}
// lib/main.dart — wrap with ChangeNotifierProvider
import 'package:provider/provider.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => AuthService(
domain: 'YOUR_AUTH0_DOMAIN',
clientId: 'YOUR_AUTH0_CLIENT_ID',
)..init(),
child: const MyApp(),
),
);
}
For complete patterns with Riverpod, Bloc, and advanced scenarios, see Integration Patterns.
Step 6 — Verify Build
Agent instruction: Run a build to verify the integration compiles without errors:
flutter build webThen run the app locally to test:
flutter run -d chrome --web-port 3000If the build fails, review error messages and fix up to 5 times before asking the user.
Detailed Documentation
- Setup Guide — Auth0 application creation via the Auth0 CLI, web/index.html setup, callback URL registration
- Integration Patterns — Redirect login, popup login, credential management, state management patterns, organization support, error handling
- API Reference & Testing — Full API reference, configuration options, claims reference, testing checklist, troubleshooting
Common Mistakes
| Mistake | Fix |
|---|---|
| Auth0 app type not set to Single Page Application | In Auth0 Dashboard, select "Single Page Application" when creating the application |
Missing Auth0 SPA JS script in web/index.html | Add <script src="https://cdn.auth0.com/js/auth0-spa-js/2.1/auth0-spa-js.production.js" defer></script> to <head> |
Not calling onLoad() on app startup | Always call onLoad() in initState() or equivalent to restore sessions after redirect |
Missing Allowed Web Origins in Auth0 Dashboard | Add your app URL (e.g., http://localhost:3000) to Allowed Web Origins — required for silent token renewal |
Using auth0_flutter mobile API on web | Import both package:auth0_flutter/auth0_flutter.dart (for types like Credentials, UserProfile) AND package:auth0_flutter/auth0_flutter_web.dart (for Auth0Web class) |
| Missing base import causes type errors | Credentials and UserProfile are exported from auth0_flutter.dart, not auth0_flutter_web.dart — you need both imports |
| Callback URL mismatch | Ensure Allowed Callback URLs matches the exact URL where your app runs (including port) |
Not adding --web-port when running locally | Use flutter run -d chrome --web-port 3000 to ensure consistent port matching callback URLs |
| Popup blocked by browser | loginWithPopup() must be called from a direct user interaction (button click); cannot be called from initState() |
Missing offline_access scope | Add 'offline_access' to scopes set to enable refresh token rotation for silent renewal |
| CORS errors on token endpoint | Ensure Allowed Web Origins is configured in Auth0 Dashboard (not just Callback URLs) |
References
FAQ
What does the auth0-flutter-web skill do?
Use when adding Auth0 login or logout to a Flutter web application. Integrates auth0flutter on the web platform — use even if the user says "add login to my Flutter web app".
How do I install auth0-flutter-web?
Run npx skills add https://github.com/auth0/agent-skills --skill auth0-flutter-web in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/auth0-flutter-web/ (personal) or .claude/skills/auth0-flutter-web/ (project).
Which AI agents can use auth0-flutter-web?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is auth0-flutter-web safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains auth0-flutter-web?
It is published by auth0 in auth0/agent-skills. It has 203 recorded installs.
More from auth0/agent-skills
auth0
auth0/agent-skills
Use when adding, fixing, or improving how an app authenticates users or protects an API, or when using or configuring any Auth0 feature — signing users in and out, sessions and tokens, guarding routes and endpoints, MFA, passwordless passkey login (WebAuthn), SSO, Organizations, RBAC, custom domains, Universal Portals for hosted account and organization self-service, or Universal Login branding. Also use to audit a tenant's health, security, and plan fit (CheckMate), to debug why an auth flow fails, to migrate from another auth provider, or to set up the Vercel native integration. Covers any web, mobile, or backend framework and every Auth0 SDK, tool, and API. Use even if the user never mentions Auth0.
auth0-quickstart
auth0/agent-skills
Use when adding Auth0 authentication to any app and unsure which SDK or skill to use. Detects the project's framework and routes to the right setup workflow — use this as the entry point even if the user just says "add login to my app" or "set up Auth0" without naming a framework.
auth0-nextjs
auth0/agent-skills
Use when adding Auth0 login, logout, protected pages, or middleware to a Next.js application. Supports App Router and Pages Router with @auth0/nextjs-auth0 — use even if the user says "add login to my Next.js app" or "protect my Next.js routes".
auth0-react
auth0/agent-skills
Use when adding Auth0 login, logout, protected routes, or user sessions to a React SPA. Integrates @auth0/auth0-react — use even if the user says "add login to my React app" or "protect my React routes" without naming the SDK.
auth0-react-native
auth0/agent-skills
Use when adding Auth0 login, logout, or biometric auth to a bare React Native app (not Expo). Integrates react-native-auth0 with native deep linking.
auth0-express
auth0/agent-skills
Use when adding session-based login, logout, or protected routes to an Express.js web application. Integrates express-openid-connect — use even if the user says "add login to my Express app" or "protect my Express routes".
Popular mobile skills
design-mobile-apps
designed-by-ai/skills
Design mobile app screens with Sleek, edit Sleek projects, and implement their designs in React Native or HTML.
ios-design
uizze.sh
Design and review iOS UI/UX for iPhone apps in SwiftUI, UIKit, or React Native. Use for mobile app design, screen redesigns, navigation flows, typography, forms, keyboard and safe-area layout, and accessibility checks. Apply Apple Human Interface Guidelines and consult real product references through the optional Uizze connection.
vercel-react-native-skills
vercel-labs/agent-skills
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
animate-expo
emilkowalski/skills
Build animations in React Native and Expo, making the decisions in the order that determines whether they feel right — should it animate, which thread it runs on, which properties, spring or timing, how the gesture hands off, how it degrades. Writes the implementation with Reanimated, Gesture Handler, Expo Router and expo-haptics. Use when animating anything in an Expo app, adding gestures, sheets, screen transitions, press feedback or haptics, or fixing motion that stutters on device. For web animation use animate.
xcode-project-setup
firebase/agent-skills
Safely modifies Xcode projects (.pbxproj) to add Swift Packages and link files. Use this skill whenever an iOS project needs dependencies installed (e.g. Firebase, Alamofire).
firebase-remote-config-basics
firebase/agent-skills
Manages Firebase Remote Config templates, feature flags, loading strategies, and SDKs (Android, iOS). Use when downloading/deploying remoteconfig JSON templates, managing version history/feature flags, setting in-app defaults, fetchAndActivate(), real-time listeners, or SDK setup. Don't use for Firebase Hosting, Auth, Firestore, Data Connect, Crashlytics, or App Hosting.
