{"id":"c196293c-9487-46d2-a39c-f481cda7dc61","entityType":"agent","slug":"clawhub-auth0-auth0-react","name":"Auth0 React","canonicalUrl":"https://www.xpersona.co/agent/clawhub-auth0-auth0-react","canonicalPath":"/agent/clawhub-auth0-auth0-react","generatedAt":"2026-10-11T04:33:01.529Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T02:41:26.850Z","emptyReason":null},"description":"Deprecated — use the `auth0` skill instead (run `npx clawhub install auth0`). 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 Skill: Auth0 React Owner: auth0 Summary: Deprecated — use the auth0 skill instead (run npx clawhub install auth0). 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 Tags: latest:1.1.0 Version history: v1.1.0 | 2026-07-20T14:50:48.794Z | user - ⚠️ D","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.2K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s1705618g3dhya8px0x9gnyy4d84geyh:auth0-react","sourceUrl":"https://clawhub.ai/auth0/auth0-react","homepage":"https://clawhub.ai/auth0/skills/auth0-react","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/auth0/auth0-react","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/auth0/skills/auth0-react","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":61,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Deprecated — use the `auth0` skill instead (run `npx clawhub install auth0`). Use when adding Auth0 login, logout, protected routes, or user sessions to a React"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T02:41:26.850Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T02:41:26.850Z","emptyReason":null},"stars":null,"forks":null,"downloads":1185,"packageName":null,"latestVersion":"1.1.0","tractionLabel":"1.2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T02:41:26.781Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T02:41:26.850Z","lastCrawledAt":"2026-10-11T02:41:26.781Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T02:41:26.782Z","lastVerifiedAt":null,"highlights":[{"version":"1.1.0","createdAt":"2026-07-20T14:50:48.794Z","changelog":"- ⚠️ Deprecated: This skill is now retired in favor of the consolidated auth0 skill. - All reference and integration documentation files have been removed. - Instructions direct users to install the new auth0 skill (`npx clawhub install auth0`) for all Auth0 React SPA use cases. - No further updates or maintenance will be provided for this version.","fileCount":3,"zipByteSize":2069},{"version":"1.0.1","createdAt":"2026-05-06T12:58:05.789Z","changelog":"Bump to 1.0.1","fileCount":6,"zipByteSize":18310},{"version":"1.0.0","createdAt":"2026-04-15T16:48:32.728Z","changelog":"- Initial release of the auth0-react skill. - Provides step-by-step integration instructions for adding Auth0 authentication to React SPAs (Vite or Create React App). - Includes setup prerequisites, quick start workflow, common pitfalls, detailed documentation references, and core usage examples. - Covers protected routes, API access, and advanced features like MFA handling using @auth0/auth0-react SDK. - Lists related skills and troubleshooting guidance for common mistakes.","fileCount":5,"zipByteSize":16819}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s1705618g3dhya8px0x9gnyy4d84geyh:auth0-react","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T04:33:01.525Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-auth0-auth0-react/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T02:41:26.850Z","emptyReason":null},"readme":"Skill: Auth0 React\n\nOwner: auth0\n\nSummary: Deprecated — use the `auth0` skill instead (run `npx clawhub install auth0`). 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\n\nTags: latest:1.1.0\n\nVersion history:\n\nv1.1.0 | 2026-07-20T14:50:48.794Z | user\n\n- ⚠️ Deprecated: This skill is now retired in favor of the consolidated auth0 skill.\n- All reference and integration documentation files have been removed.\n- Instructions direct users to install the new auth0 skill (`npx clawhub install auth0`) for all Auth0 React SPA use cases.\n- No further updates or maintenance will be provided for this version.\n\nv1.0.1 | 2026-05-06T12:58:05.789Z | user\n\nBump to 1.0.1\n\nv1.0.0 | 2026-04-15T16:48:32.728Z | user\n\n- Initial release of the auth0-react skill.\n- Provides step-by-step integration instructions for adding Auth0 authentication to React SPAs (Vite or Create React App).\n- Includes setup prerequisites, quick start workflow, common pitfalls, detailed documentation references, and core usage examples.\n- Covers protected routes, API access, and advanced features like MFA handling using @auth0/auth0-react SDK.\n- Lists related skills and troubleshooting guidance for common mistakes.\n\nArchive index:\n\nArchive v1.1.0: 3 files, 2069 bytes\n\nFiles: skill-card.md (2022b), SKILL.md (1301b), _meta.json (130b)\n\nFile v1.1.0:SKILL.md\n\n---\nname: auth0-react\ndescription: >-\n  Deprecated — use the `auth0` skill instead (run `npx clawhub install auth0`).\n  Use when adding Auth0 login, logout, protected routes, or user sessions to a\n  React SPA. Integrates @auth0/auth0-react — use even if the user says \"add\n  login to my React app\" or \"protect my React routes\" without naming the SDK.\nlicense: Apache-2.0\nmetadata:\n  author: Auth0 <support@auth0.com>\n  version: 1.1.0\n  openclaw:\n    emoji: 🔐\n    homepage: https://github.com/auth0/agent-skills\n    requires:\n      bins:\n      - auth0\n    os:\n    - darwin\n    - linux\n    install:\n    - id: brew\n      kind: brew\n      formula: auth0/auth0-cli/auth0\n      bins:\n      - auth0\n      label: Install Auth0 CLI (brew)\n---\n\n# ⚠️ Deprecated — install the replacement skill\n\n**Do not use this skill.** It has been consolidated into the single `auth0`\nskill, which auto-detects your framework and routes to the same guidance for all\nAuth0 authentication work (login, logout, route protection, token validation,\nMFA, and more).\n\nClawHub does **not** install the replacement automatically. When you download\nthis outdated skill, install the consolidated one by running:\n\n```bash\nnpx clawhub install auth0\n```\n\nThen use the `auth0` skill instead — this one will not be maintained.\n\nFile v1.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn7cjgtjqyx9kzrhcrr56tyzd183x56s\",\n  \"slug\": \"auth0-react\",\n  \"version\": \"1.1.0\",\n  \"publishedAt\": 1784559048794\n}\n\nFile v1.1.0:skill-card.md\n\n## Description:\n\nDeprecated skill that directs users to install the consolidated `auth0` skill for Auth0 React SPA login, logout, protected routes, and user sessions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[auth0](https://clawhub.ai/user/auth0)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers maintaining React SPAs use this deprecated skill as a redirect notice and should install the consolidated `auth0` skill for Auth0 authentication work, including login, logout, protected routes, and user sessions.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: This deprecated skill redirects users to install a replacement skill through an unpinned ClawHub install command.\n\nMitigation: Review the replacement auth0 skill, prefer a pinned or otherwise trusted ClawHub installer invocation when available, and run installation from a least-privilege shell without production secrets.\n\nRisk: Users may expect maintained Auth0 React implementation guidance from a retired skill.\n\nMitigation: Use this skill only as a deprecation notice and install the consolidated auth0 skill for current Auth0 authentication guidance.\n\n## Reference(s):\n\n- [Auth0 React skill page](https://clawhub.ai/auth0/skills/auth0-react)\n- [Auth0 agent skills repository](https://github.com/auth0/agent-skills)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands]\n\n**Output Format:** [Markdown with inline shell command]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Redirects users to install the consolidated auth0 skill; no maintained Auth0 React implementation guidance is provided.]\n\n## Skill Version(s):\n\n1.1.0 (source: server release metadata and skill frontmatter)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.0.1: 6 files, 18310 bytes\n\nFiles: references/api.md (16302b), references/integration.md (14166b), references/setup.md (10662b), skill-card.md (2780b), SKILL.md (6615b), _meta.json (130b)\n\nFile v1.0.1:SKILL.md\n\n---\nname: auth0-react\ndescription: Use when adding authentication to React applications (login, logout, user sessions, protected routes) - integrates @auth0/auth0-react SDK for SPAs with Vite or Create React App\nlicense: Apache-2.0\nmetadata:\n  author: Auth0 <support@auth0.com>\n  version: '1.0.1'\n  openclaw:\n    emoji: \"\\U0001F510\"\n    homepage: https://github.com/auth0/agent-skills\n---\n\n# Auth0 React Integration\n\nAdd authentication to React single-page applications using @auth0/auth0-react.\n\n---\n\n## Prerequisites\n\n- React 16.11+ application (Vite or Create React App) - supports React 16, 17, 18, and 19\n- Auth0 account and application configured\n- If you don't have Auth0 set up yet, use the `auth0-quickstart` skill first\n\n## When NOT to Use\n\n- **Next.js applications** - Use `auth0-nextjs` skill for both App Router and Pages Router\n- **React Native mobile apps** - Use `auth0-react-native` skill for iOS/Android\n- **Server-side rendered React** - Use framework-specific SDK (Next.js, Remix, etc.)\n- **Embedded login** - This SDK uses Auth0 Universal Login (redirect-based)\n- **Backend API authentication** - Use express-openid-connect or JWT validation instead\n\n---\n\n## Quick Start Workflow\n\n### 1. Install SDK\n\n```bash\nnpm install @auth0/auth0-react\n```\n\n### 2. Configure Environment\n\n**For automated setup with Auth0 CLI**, see [Setup Guide](references/setup.md) for complete scripts.\n\n**For manual setup:**\n\nCreate `.env` file:\n\n**Vite:**\n```bash\nVITE_AUTH0_DOMAIN=your-tenant.auth0.com\nVITE_AUTH0_CLIENT_ID=your-client-id\n```\n\n**Create React App:**\n```bash\nREACT_APP_AUTH0_DOMAIN=your-tenant.auth0.com\nREACT_APP_AUTH0_CLIENT_ID=your-client-id\n```\n\n### 3. Wrap App with Auth0Provider\n\nUpdate `src/main.tsx` (Vite) or `src/index.tsx` (CRA):\n\n```tsx\nimport React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport { Auth0Provider } from '@auth0/auth0-react';\nimport App from './App';\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n  <React.StrictMode>\n    <Auth0Provider\n      domain={import.meta.env.VITE_AUTH0_DOMAIN} // or process.env.REACT_APP_AUTH0_DOMAIN\n      clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}\n      authorizationParams={{\n        redirect_uri: window.location.origin\n      }}\n    >\n      <App />\n    </Auth0Provider>\n  </React.StrictMode>\n);\n```\n\n### 4. Add Authentication UI\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\n\nexport function LoginButton() {\n  const { loginWithRedirect, logout, isAuthenticated, user, isLoading } = useAuth0();\n\n  if (isLoading) return <div>Loading...</div>;\n\n  if (isAuthenticated) {\n    return (\n      <div>\n        <span>Welcome, {user?.name}</span>\n        <button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>\n          Logout\n        </button>\n      </div>\n    );\n  }\n\n  return <button onClick={() => loginWithRedirect()}>Login</button>;\n}\n```\n\n### 5. Test Authentication\n\nStart your dev server and test the login flow:\n\n```bash\nnpm run dev  # Vite\n# or\nnpm start    # CRA\n```\n\n---\n\n## Detailed Documentation\n\n- **[Setup Guide](references/setup.md)** - Automated setup scripts (Bash/PowerShell), CLI commands, manual configuration\n- **[Integration Guide](references/integration.md)** - Protected routes, API calls, error handling, advanced patterns\n- **[API Reference](references/api.md)** - Complete SDK API, configuration options, hooks reference, testing strategies\n\n---\n\n## Common Mistakes\n\n| Mistake | Fix |\n|---------|-----|\n| Forgot to add redirect URI in Auth0 Dashboard | Add your application URL (e.g., `http://localhost:3000`, `https://app.example.com`) to Allowed Callback URLs in Auth0 Dashboard |\n| Using wrong env var prefix | Vite uses `VITE_` prefix, Create React App uses `REACT_APP_` |\n| Not handling loading state | Always check `isLoading` before rendering auth-dependent UI |\n| Storing tokens in localStorage | Never manually store tokens - SDK handles secure storage automatically |\n| Missing Auth0Provider wrapper | Entire app must be wrapped in `<Auth0Provider>` |\n| Provider not at root level | Auth0Provider must wrap all components that use auth hooks |\n| Wrong import path for env vars | Vite uses `import.meta.env.VITE_*`, CRA uses `process.env.REACT_APP_*` |\n| Using `acr_values` redirect for in-app MFA | Use `useAuth0().mfa` API for in-app enrollment/challenge/verify flows |\n| Not catching `MfaRequiredError` | Wrap `getAccessTokenSilently` in try/catch and check `instanceof MfaRequiredError` |\n| Making direct HTTP calls to MFA endpoints | Use the `mfa` property from `useAuth0()` — it handles token management automatically |\n| Forgetting refresh tokens for step-up MFA | Set `useRefreshTokens={true}` on Auth0Provider when using `interactiveErrorHandler=\"popup\"` |\n\n---\n\n## Related Skills\n\n- `auth0-quickstart` - Basic Auth0 setup\n- `auth0-migration` - Migrate from another auth provider\n- `auth0-mfa` - Add Multi-Factor Authentication\n- `auth0-cli` - Manage Auth0 resources from the terminal\n\n---\n\n## Quick Reference\n\n**Core Hooks:**\n- `useAuth0()` - Main authentication hook\n- `isAuthenticated` - Check if user is logged in\n- `user` - User profile information\n- `loginWithRedirect()` - Initiate login\n- `logout()` - Log out user\n- `getAccessTokenSilently()` - Get access token for API calls\n- `mfa` - MFA API client for enrollment, challenge, and verification\n  - `mfa.getAuthenticators(mfaToken)` - List enrolled authenticators\n  - `mfa.getEnrollmentFactors(mfaToken)` - Get available enrollment factors\n  - `mfa.enroll(params)` - Enroll new authenticator (OTP, SMS, Email, Voice, Push)\n  - `mfa.challenge(params)` - Initiate MFA challenge\n  - `mfa.verify(params)` - Verify MFA challenge and complete authentication\n\n**MFA Error Types (import from `@auth0/auth0-react`):**\n- `MfaRequiredError` - Thrown by `getAccessTokenSilently` when MFA is needed (has `mfa_token` and `mfa_requirements`)\n- `MfaEnrollmentError`, `MfaChallengeError`, `MfaVerifyError` - Thrown by respective `mfa.*` methods\n\n**Common Use Cases:**\n- Login/Logout buttons → See Step 4 above\n- Protected routes → [Integration Guide](references/integration.md#protected-routes)\n- API calls with tokens → [Integration Guide](references/integration.md#calling-apis)\n- Error handling → [Integration Guide](references/integration.md#error-handling)\n- MFA handling → [Integration Guide](references/integration.md#mfa-handling)\n\n---\n\n## References\n\n- [Auth0 React SDK Documentation](https://auth0.com/docs/libraries/auth0-react)\n- [Auth0 React Quickstart](https://auth0.com/docs/quickstart/spa/react)\n- [SDK GitHub Repository](https://github.com/auth0/auth0-react)\n\nFile v1.0.1:_meta.json\n\n{\n  \"ownerId\": \"kn7cjgtjqyx9kzrhcrr56tyzd183x56s\",\n  \"slug\": \"auth0-react\",\n  \"version\": \"1.0.1\",\n  \"publishedAt\": 1778072285789\n}\n\nFile v1.0.1:references/api.md\n\n# Auth0 React SDK API Reference\n\nComplete API documentation for @auth0/auth0-react SDK.\n\n---\n\n## Auth0Provider Configuration\n\n### Complete Configuration Options\n\n```tsx\nimport { Auth0Provider } from '@auth0/auth0-react';\n\n<Auth0Provider\n  // Required\n  domain=\"your-tenant.auth0.com\"\n  clientId=\"your-client-id\"\n\n  // Authorization parameters\n  authorizationParams={{\n    redirect_uri: window.location.origin,\n    audience: 'https://your-api-identifier', // For API calls\n    scope: 'openid profile email', // Default scopes\n    connection: 'google-oauth2', // Force specific connection\n    prompt: 'login', // Force login prompt\n    ui_locales: 'en', // Localization\n    screen_hint: 'signup', // Show signup page by default\n  }}\n\n  // Token management\n  cacheLocation=\"localstorage\" // or \"memory\" for stricter security (default: \"memory\")\n  useRefreshTokens={true} // Enable refresh tokens (default: false)\n  useRefreshTokensFallback={false} // Fall back to iframe if refresh token exchange fails (default: false)\n  useMrrt={false} // Enable Multi-Refresh-Token for multi-tenant apps (default: false)\n\n  // MFA / Step-up\n  interactiveErrorHandler=\"popup\" // Automatically handle MFA via popup (requires useRefreshTokens)\n\n  // Advanced options\n  skipRedirectCallback={false} // Skip automatic callback handling\n  context={Auth0Context} // Custom React context\n\n  // Callbacks\n  onRedirectCallback={(appState) => {\n    // Handle redirect after login\n    // appState receives the custom state passed to loginWithRedirect()\n    // Example: if login was called with appState: { targetUrl: '/dashboard' }\n    // then appState.targetUrl will be '/dashboard' here\n    window.location.replace(appState?.returnTo || '/');\n  }}\n>\n  <App />\n</Auth0Provider>\n```\n\n### Configuration Properties\n\n| Property | Type | Default | Description |\n|----------|------|---------|-------------|\n| `domain` | string | **Required** | Your Auth0 tenant domain |\n| `clientId` | string | **Required** | Your Auth0 application client ID |\n| `authorizationParams` | object | `{}` | Authorization parameters (see below) |\n| `cacheLocation` | `'memory' \\| 'localstorage'` | `'memory'` | Where to store tokens |\n| `useRefreshTokens` | boolean | `false` | Enable refresh token rotation |\n| `useRefreshTokensFallback` | boolean | `false` | Fall back to iframe if refresh token exchange fails |\n| `useMrrt` | boolean | `false` | Enable Multi-Refresh-Token support for multi-tenant apps. Requires `useRefreshTokens` and `useRefreshTokensFallback` to be `true` |\n| `workerUrl` | string | - | Custom worker script URL for token calls. Useful for CSP compliance when using `useRefreshTokens: true` with `cacheLocation: 'memory'` |\n| `context` | React.Context | - | Custom React context for nested Auth0Providers. Allows multiple Auth0Providers in same app |\n| `interactiveErrorHandler` | `'popup'` | - | Automatically handle MFA via popup when `getAccessTokenSilently` encounters `mfa_required`. Requires `useRefreshTokens={true}` |\n| `skipRedirectCallback` | boolean | `false` | Skip automatic callback handling |\n| `onRedirectCallback` | function | - | Callback after successful login |\n\n### Authorization Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `redirect_uri` | string | URL to redirect after authentication |\n| `audience` | string | API audience identifier |\n| `scope` | string | Requested scopes (space-separated) |\n| `connection` | string | Force specific connection |\n| `prompt` | string | `'none'`, `'login'`, `'consent'`, or `'select_account'` |\n| `ui_locales` | string | Language code (e.g., `'en'`, `'es'`) |\n| `screen_hint` | string | `'signup'` to show signup by default |\n| `max_age` | number | Maximum authentication age in seconds |\n| `organization` | string | Organization ID for B2B |\n| `invitation` | string | Invitation ID for organization invites |\n\n---\n\n## useAuth0 Hook\n\n### Hook Interface\n\n```typescript\nconst {\n  // Authentication state\n  isLoading,\n  isAuthenticated,\n  error,\n  user,\n\n  // Methods\n  loginWithRedirect,\n  loginWithPopup,\n  logout,\n  getAccessTokenSilently,\n  getAccessTokenWithPopup,\n  getIdTokenClaims,\n  handleRedirectCallback,\n\n  // MFA API\n  mfa,\n} = useAuth0();\n```\n\n### Authentication State\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `isLoading` | boolean | True while Auth0 is initializing |\n| `isAuthenticated` | boolean | True if user is logged in |\n| `error` | Error \\| undefined | Authentication error if any |\n| `user` | User \\| undefined | User profile information |\n\n### User Object\n\n```typescript\ninterface User {\n  sub: string;          // User ID\n  name: string;         // Display name\n  email: string;        // Email address\n  email_verified: boolean;\n  picture: string;      // Avatar URL\n  updated_at: string;   // Last update timestamp\n  // Custom claims...\n}\n```\n\n### Methods\n\n#### loginWithRedirect\n\n```typescript\nawait loginWithRedirect(options?: RedirectLoginOptions);\n```\n\nRedirects to Auth0 Universal Login page.\n\n**Options:**\n```typescript\ninterface RedirectLoginOptions {\n  authorizationParams?: {\n    redirect_uri?: string;\n    audience?: string;\n    scope?: string;\n    connection?: string;\n    prompt?: 'none' | 'login' | 'consent' | 'select_account';\n    max_age?: number;\n    ui_locales?: string;\n    screen_hint?: 'signup' | 'login';\n  };\n  appState?: any; // Custom state to preserve\n  fragment?: string; // URL fragment\n}\n```\n\n**Example:**\n```tsx\n// Basic login\nawait loginWithRedirect();\n\n// Login with specific connection\nawait loginWithRedirect({\n  authorizationParams: {\n    connection: 'google-oauth2'\n  }\n});\n\n// Login with custom state (preserved through redirect)\nawait loginWithRedirect({\n  appState: { targetUrl: '/dashboard' }\n});\n// After login, onRedirectCallback receives appState.targetUrl = '/dashboard'\n```\n\n#### loginWithPopup\n\n```typescript\nawait loginWithPopup(options?: PopupLoginOptions);\n```\n\nOpens Auth0 login in popup window (better UX, but may be blocked).\n\n**Options:**\n```typescript\ninterface PopupLoginOptions {\n  authorizationParams?: AuthorizationParams;\n  config?: PopupConfigOptions; // Popup window configuration\n}\n```\n\n**Example:**\n```tsx\ntry {\n  await loginWithPopup();\n} catch (error) {\n  // Handle popup blocked or closed\n  console.error('Popup login failed:', error);\n}\n```\n\n#### logout\n\n```typescript\nlogout(options?: LogoutOptions);\n```\n\nLogs out the user and optionally redirects.\n\n**Options:**\n```typescript\ninterface LogoutOptions {\n  logoutParams?: {\n    returnTo?: string; // URL to redirect after logout\n    federated?: boolean; // Logout from identity provider too\n    client_id?: string; // Client ID (if different from current)\n  };\n  openUrl?: (url: string) => void; // Custom URL opener\n}\n```\n\n**Example:**\n```tsx\n// Basic logout\nlogout();\n\n// Logout with redirect\nlogout({\n  logoutParams: {\n    returnTo: window.location.origin\n  }\n});\n\n// Federated logout (logout from Google/Facebook too)\nlogout({\n  logoutParams: {\n    returnTo: window.location.origin,\n    federated: true\n  }\n});\n```\n\n#### getAccessTokenSilently\n\n```typescript\nconst token = await getAccessTokenSilently(options?: GetTokenSilentlyOptions);\n```\n\nGets access token without user interaction (uses refresh token or iframe).\n\n**Options:**\n```typescript\ninterface GetTokenSilentlyOptions {\n  authorizationParams?: {\n    audience?: string;\n    scope?: string;\n    ignoreCache?: boolean; // Force new token\n    timeoutInSeconds?: number; // Request timeout\n    detailedResponse?: boolean; // Return full response with expiry\n  };\n}\n```\n\n**Example:**\n```tsx\n// Basic usage\nconst token = await getAccessTokenSilently();\n\n// With specific audience\nconst token = await getAccessTokenSilently({\n  authorizationParams: {\n    audience: 'https://api.example.com'\n  }\n});\n\n// Force fresh token\nconst token = await getAccessTokenSilently({\n  authorizationParams: {\n    ignoreCache: true\n  }\n});\n\n// Get detailed response with expiry\nconst { access_token, expires_in } = await getAccessTokenSilently({\n  authorizationParams: {\n    detailedResponse: true\n  }\n});\n```\n\n#### getAccessTokenWithPopup\n\n```typescript\nconst token = await getAccessTokenWithPopup(options?: GetTokenWithPopupOptions);\n```\n\nGets access token via popup window. Useful as fallback when `getAccessTokenSilently` fails (e.g., third-party cookies blocked).\n\n**Options:**\n```typescript\ninterface GetTokenWithPopupOptions {\n  authorizationParams?: {\n    audience?: string;\n    scope?: string;\n  };\n  config?: PopupConfigOptions; // Popup window configuration\n}\n```\n\n**Example:**\n```tsx\n// Try silent auth, fall back to popup\ntry {\n  const token = await getAccessTokenSilently();\n} catch (error) {\n  // Fallback to popup if silent auth fails\n  const token = await getAccessTokenWithPopup();\n}\n\n// Direct popup usage with specific audience\nconst token = await getAccessTokenWithPopup({\n  authorizationParams: {\n    audience: 'https://api.example.com'\n  }\n});\n```\n\n#### getIdTokenClaims\n\n```typescript\nconst claims = await getIdTokenClaims();\n```\n\nReturns ID token claims.\n\n**Example:**\n```tsx\nconst claims = await getIdTokenClaims();\nconsole.log(claims.sub); // User ID\nconsole.log(claims.email);\nconsole.log(claims.custom_claim);\n```\n\n#### handleRedirectCallback\n\n```typescript\nconst result = await handleRedirectCallback(url?: string);\n```\n\nManually handle redirect callback (when `skipRedirectCallback` is true).\n\n**Returns:**\n```typescript\ninterface RedirectLoginResult {\n  appState: any; // Custom state from login\n}\n```\n\n#### mfa\n\nThe `mfa` property provides access to the MFA API client for in-app Multi-Factor Authentication flows.\n\n**Methods:**\n\n| Method | Description |\n|--------|-------------|\n| `mfa.getAuthenticators(mfaToken)` | List enrolled authenticators for the user |\n| `mfa.getEnrollmentFactors(mfaToken)` | Get available enrollment factors (when user needs to enroll) |\n| `mfa.enroll(params)` | Enroll a new authenticator (OTP, SMS, Email, Voice, Push) |\n| `mfa.challenge(params)` | Initiate an MFA challenge for an enrolled authenticator |\n| `mfa.verify(params)` | Verify an MFA challenge and complete authentication |\n\n**Enroll params:**\n\n```typescript\n// OTP enrollment\nawait mfa.enroll({ mfaToken, factorType: 'otp' });\n// Returns: { barcodeUri, recoveryCodes, ... }\n\n// SMS enrollment\nawait mfa.enroll({ mfaToken, factorType: 'sms', phoneNumber: '+12025551234' });\n\n// Email enrollment\nawait mfa.enroll({ mfaToken, factorType: 'email', email: 'user@example.com' });\n\n// Voice enrollment\nawait mfa.enroll({ mfaToken, factorType: 'voice', phoneNumber: '+12025551234' });\n\n// Push enrollment\nawait mfa.enroll({ mfaToken, factorType: 'push' });\n```\n\n**Challenge params:**\n\n```typescript\n// OTP challenge (optional — code is already in authenticator app)\nawait mfa.challenge({ mfaToken, challengeType: 'otp', authenticatorId });\n\n// SMS/Voice/Email/Push challenge (required — sends code to user)\nawait mfa.challenge({ mfaToken, challengeType: 'oob', authenticatorId });\n// Returns: { oobCode }\n```\n\n**Verify params:**\n\n```typescript\n// Verify with OTP code\nconst tokens = await mfa.verify({ mfaToken, otp: '123456' });\n\n// Verify with OOB code (SMS/Voice/Email)\nconst tokens = await mfa.verify({ mfaToken, oobCode, bindingCode: '123456' });\n\n// Verify with recovery code\nconst tokens = await mfa.verify({ mfaToken, recoveryCode: 'recovery-code-here' });\n```\n\n---\n\n### MFA Error Types\n\nAll MFA error types are importable from `@auth0/auth0-react`.\n\n| Error | When thrown | Key properties |\n|-------|-----------|----------------|\n| `MfaRequiredError` | `getAccessTokenSilently()` encounters an MFA requirement | `mfa_token`, `mfa_requirements` |\n| `MfaEnrollmentError` | `mfa.enroll()` fails | `error_description` |\n| `MfaChallengeError` | `mfa.challenge()` fails | `error_description` |\n| `MfaVerifyError` | `mfa.verify()` fails (e.g., invalid OTP code) | `error_description` |\n| `MfaListAuthenticatorsError` | `mfa.getAuthenticators()` fails | `error_description` |\n| `MfaEnrollmentFactorsError` | `mfa.getEnrollmentFactors()` fails | `error_description` |\n\n**MfaRequiredError properties:**\n- `mfa_token` — Token used for all subsequent MFA operations\n- `mfa_requirements.enroll` — Array of factor types the user can enroll in (present when user needs to set up MFA)\n- `mfa_requirements.challenge` — Array of factor types the user can challenge (present when user has enrolled authenticators)\n\n**Import:**\n\n```typescript\nimport {\n  MfaRequiredError,\n  MfaEnrollmentError,\n  MfaChallengeError,\n  MfaVerifyError,\n} from '@auth0/auth0-react';\n```\n\n---\n\n## Custom Hooks\n\n### withAuth0\n\nHigher-order component for class components:\n\n```tsx\nimport { withAuth0 } from '@auth0/auth0-react';\n\nclass Profile extends React.Component {\n  render() {\n    const { auth0, isLoading, isAuthenticated, user } = this.props;\n    // Use auth0 methods and state\n  }\n}\n\nexport default withAuth0(Profile);\n```\n\n### withAuthenticationRequired\n\nHOC to protect components requiring authentication:\n\n```tsx\nimport { withAuthenticationRequired } from '@auth0/auth0-react';\n\nconst ProtectedComponent = () => {\n  return <div>Protected content</div>;\n};\n\nexport default withAuthenticationRequired(ProtectedComponent, {\n  onRedirecting: () => <div>Loading...</div>,\n  returnTo: '/profile', // Where to return after login\n  loginOptions: {\n    authorizationParams: {\n      connection: 'google-oauth2'\n    }\n  }\n});\n```\n\n---\n\n## Testing\n\n### Testing with React Testing Library\n\n```tsx\nimport { render, screen } from '@testing-library/react';\nimport { Auth0Provider } from '@auth0/auth0-react';\nimport App from './App';\n\n// Mock Auth0\njest.mock('@auth0/auth0-react', () => ({\n  ...jest.requireActual('@auth0/auth0-react'),\n  Auth0Provider: ({ children }) => children,\n  useAuth0: () => ({\n    isLoading: false,\n    isAuthenticated: true,\n    user: {\n      name: 'Test User',\n      email: 'test@example.com'\n    },\n    loginWithRedirect: jest.fn(),\n    logout: jest.fn(),\n  }),\n}));\n\ntest('renders authenticated app', () => {\n  render(<App />);\n  expect(screen.getByText('Test User')).toBeInTheDocument();\n});\n```\n\n### Testing with Custom Mock\n\n```tsx\n// testUtils.tsx\nimport { Auth0Provider } from '@auth0/auth0-react';\n\nexport const mockAuth0User = {\n  name: 'Test User',\n  email: 'test@example.com',\n  picture: 'https://example.com/avatar.jpg',\n};\n\nexport function renderWithAuth0(ui: React.ReactElement, isAuthenticated = true) {\n  return render(\n    <Auth0Provider\n      domain=\"test.auth0.com\"\n      clientId=\"test-client-id\"\n      authorizationParams={{\n        redirect_uri: window.location.origin\n      }}\n    >\n      {ui}\n    </Auth0Provider>\n  );\n}\n```\n\n---\n\n## TypeScript Types\n\n### Import Types\n\n```typescript\nimport type {\n  Auth0ContextInterface,\n  User,\n  RedirectLoginOptions,\n  PopupLoginOptions,\n  LogoutOptions,\n  GetTokenSilentlyOptions,\n  MfaApiClient,\n  Authenticator,\n  EnrollParams,\n  ChallengeResponse,\n  VerifyParams,\n  EnrollmentFactor,\n} from '@auth0/auth0-react';\n\n// MFA error types (value imports, not type-only)\nimport {\n  MfaRequiredError,\n  MfaEnrollmentError,\n  MfaChallengeError,\n  MfaVerifyError,\n} from '@auth0/auth0-react';\n```\n\n### Type User Profile\n\n```typescript\ninterface CustomUser extends User {\n  app_metadata?: {\n    roles?: string[];\n  };\n  user_metadata?: {\n    preferences?: any;\n  };\n}\n\nconst { user } = useAuth0<CustomUser>();\nconsole.log(user?.app_metadata?.roles);\n```\n\n---\n\n## Related Skills\n\n- `auth0-quickstart` - Initial Auth0 account setup\n- `auth0-migration` - Migrate from another auth provider\n- `auth0-mfa` - Add Multi-Factor Authentication\n- `auth0-organizations` - B2B multi-tenancy support\n- `auth0-passkeys` - Add passkey authentication\n\n---\n\n## References\n\n- [Auth0 React SDK Documentation](https://auth0.com/docs/libraries/auth0-react)\n- [Auth0 React SDK GitHub](https://github.com/auth0/auth0-react)\n- [Auth0 React Quickstart](https://auth0.com/docs/quickstart/spa/react)\n- [useAuth0 Hook API](https://auth0.github.io/auth0-react/interfaces/Auth0ContextInterface.html)\n- [Auth0 React API Reference](https://auth0.github.io/auth0-react/)\n- [Auth0 Universal Login](https://auth0.com/docs/universal-login)\n- [PKCE Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-proof-key-for-code-exchange-pkce)\n\nFile v1.0.1:references/integration.md\n\n# Auth0 React Integration Patterns\n\nPractical implementation patterns and examples for common use cases.\n\n---\n\n## Protected Routes\n\n### Basic Protected Route Component\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\nimport { Navigate } from 'react-router-dom';\n\nexport function ProtectedRoute({ children }: { children: React.ReactNode }) {\n  const { isAuthenticated, isLoading, loginWithRedirect } = useAuth0();\n\n  if (isLoading) {\n    return <div>Loading...</div>;\n  }\n\n  if (!isAuthenticated) {\n    loginWithRedirect();\n    return null;\n  }\n\n  return <>{children}</>;\n}\n```\n\n### Usage with React Router\n\n```tsx\nimport { BrowserRouter, Routes, Route } from 'react-router-dom';\nimport { ProtectedRoute } from './components/ProtectedRoute';\n\nfunction App() {\n  return (\n    <BrowserRouter>\n      <Routes>\n        <Route path=\"/\" element={<Home />} />\n        <Route\n          path=\"/profile\"\n          element={\n            <ProtectedRoute>\n              <Profile />\n            </ProtectedRoute>\n          }\n        />\n      </Routes>\n    </BrowserRouter>\n  );\n}\n```\n\n---\n\n## User Profile\n\n### Display User Information\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\n\nexport function Profile() {\n  const { user, isAuthenticated } = useAuth0();\n\n  if (!isAuthenticated) {\n    return <div>Please log in</div>;\n  }\n\n  return (\n    <div>\n      <img src={user?.picture} alt={user?.name} />\n      <h2>{user?.name}</h2>\n      <p>{user?.email}</p>\n    </div>\n  );\n}\n```\n\n---\n\n## Calling APIs\n\n### Call Protected API with Access Token\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\nimport { useState } from 'react';\n\nexport function ApiTest() {\n  const { getAccessTokenSilently } = useAuth0();\n  const [data, setData] = useState(null);\n  const [error, setError] = useState(null);\n\n  const callApi = async () => {\n    try {\n      const token = await getAccessTokenSilently({\n        authorizationParams: {\n          audience: 'https://your-api-identifier', // Your API identifier\n        }\n      });\n\n      const response = await fetch('https://your-api.com/data', {\n        headers: {\n          Authorization: `Bearer ${token}`\n        }\n      });\n\n      const json = await response.json();\n      setData(json);\n    } catch (err) {\n      setError(err.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={callApi}>Call API</button>\n      {error && <div>Error: {error}</div>}\n      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}\n    </div>\n  );\n}\n```\n\n### Configure Provider for API Calls\n\nWhen calling APIs, add `audience` to your Auth0Provider:\n\n```tsx\n<Auth0Provider\n  domain={import.meta.env.VITE_AUTH0_DOMAIN}\n  clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}\n  authorizationParams={{\n    redirect_uri: window.location.origin,\n    audience: 'https://your-api-identifier' // Add this\n  }}\n>\n  <App />\n</Auth0Provider>\n```\n\n---\n\n## Error Handling\n\n### Handle Loading and Error States\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\n\nexport function App() {\n  const { isLoading, error, isAuthenticated, user } = useAuth0();\n\n  if (isLoading) {\n    return <div>Loading authentication...</div>;\n  }\n\n  if (error) {\n    return <div>Authentication error: {error.message}</div>;\n  }\n\n  return isAuthenticated ? (\n    <div>\n      <h1>Welcome back, {user?.name}!</h1>\n      <AuthenticatedApp />\n    </div>\n  ) : (\n    <div>\n      <h1>Please log in</h1>\n      <LoginButton />\n    </div>\n  );\n}\n```\n\n---\n\n## Silent Authentication\n\n### Auto-login on Page Load\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\nimport { useEffect } from 'react';\n\nexport function App() {\n  const { isAuthenticated, isLoading, getAccessTokenSilently } = useAuth0();\n\n  useEffect(() => {\n    if (!isLoading && !isAuthenticated) {\n      // Attempt silent authentication\n      getAccessTokenSilently().catch(() => {\n        // User not logged in, do nothing\n      });\n    }\n  }, [isLoading, isAuthenticated, getAccessTokenSilently]);\n\n  // Rest of your app...\n}\n```\n\n---\n\n## Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| \"Invalid state\" error | Clear browser storage and try again. Ensure `redirect_uri` matches configured callback URL |\n| User stuck on loading | Check Auth0 application settings have correct callback URLs configured |\n| API calls fail with 401 | Ensure `audience` is configured in Auth0Provider and matches your API identifier |\n| Logout doesn't work | Include `returnTo` URL in logout options and configure in Auth0 \"Allowed Logout URLs\" |\n| CORS errors when calling API | Add your application URL to \"Allowed Web Origins\" in Auth0 application settings |\n| Tokens not refreshing | Enable `useRefreshTokens={true}` in Auth0Provider and ensure refresh token rotation is enabled in Auth0 |\n\n---\n\n## MFA Handling\n\nThe `@auth0/auth0-react` SDK provides a built-in MFA API for handling Multi-Factor Authentication entirely within your app — no redirects to Universal Login required. Access it via the `mfa` property from `useAuth0()`.\n\n> **Note:** MFA support via SDKs is currently in Early Access. For a simpler approach that uses Universal Login to handle MFA automatically (no custom UI), see the [Step-Up via Popup](#step-up-via-popup-simpler-approach) section below.\n\n### Catching MfaRequiredError\n\nWhen `getAccessTokenSilently()` encounters an MFA requirement, it throws `MfaRequiredError`. Catch it and inspect `mfa_requirements` to determine the flow:\n\n```tsx\nimport { useAuth0, MfaRequiredError } from '@auth0/auth0-react';\nimport { useState } from 'react';\n\nexport function ProtectedApiCall() {\n  const { getAccessTokenSilently, mfa } = useAuth0();\n  const [mfaToken, setMfaToken] = useState<string | null>(null);\n  const [error, setError] = useState<string | null>(null);\n\n  const callApi = async () => {\n    try {\n      const token = await getAccessTokenSilently();\n      // Use token to call API...\n    } catch (err) {\n      if (err instanceof MfaRequiredError) {\n        setMfaToken(err.mfa_token);\n\n        // Check if enrollment or challenge is needed\n        const factors = await mfa.getEnrollmentFactors(err.mfa_token);\n        if (factors.length > 0) {\n          // User needs to enroll — show enrollment UI\n        } else {\n          // User has authenticators — show challenge UI\n          const authenticators = await mfa.getAuthenticators(err.mfa_token);\n          // Let user pick authenticator and proceed with challenge\n        }\n      } else {\n        setError(err.message);\n      }\n    }\n  };\n\n  return <button onClick={callApi}>Call Protected API</button>;\n}\n```\n\n### OTP Enrollment\n\nWhen the user needs to set up MFA for the first time:\n\n```tsx\nimport { useAuth0, MfaEnrollmentError } from '@auth0/auth0-react';\nimport { useState } from 'react';\n\nexport function OtpEnrollment({ mfaToken }: { mfaToken: string }) {\n  const { mfa } = useAuth0();\n  const [barcodeUri, setBarcodeUri] = useState<string | null>(null);\n  const [recoveryCodes, setRecoveryCodes] = useState<string[] | null>(null);\n  const [error, setError] = useState<string | null>(null);\n\n  const startEnrollment = async () => {\n    try {\n      const enrollment = await mfa.enroll({ mfaToken, factorType: 'otp' });\n      setBarcodeUri(enrollment.barcodeUri);\n      setRecoveryCodes(enrollment.recoveryCodes);\n    } catch (err) {\n      if (err instanceof MfaEnrollmentError) {\n        setError(err.error_description);\n      }\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={startEnrollment}>Set up authenticator app</button>\n      {barcodeUri && (\n        <div>\n          <p>Scan this QR code with your authenticator app:</p>\n          {/* Render barcodeUri as QR code using a library like qrcode.react */}\n          <code>{barcodeUri}</code>\n        </div>\n      )}\n      {recoveryCodes && (\n        <div>\n          <p>Save these recovery codes:</p>\n          <ul>\n            {recoveryCodes.map((code, i) => <li key={i}>{code}</li>)}\n          </ul>\n        </div>\n      )}\n    </div>\n  );\n}\n```\n\n### Challenge and Verify\n\nWhen the user already has enrolled authenticators:\n\n```tsx\nimport {\n  useAuth0,\n  MfaChallengeError,\n  MfaVerifyError,\n} from '@auth0/auth0-react';\nimport { useState } from 'react';\n\nexport function MfaChallenge({ mfaToken }: { mfaToken: string }) {\n  const { mfa } = useAuth0();\n  const [otp, setOtp] = useState('');\n  const [error, setError] = useState<string | null>(null);\n\n  const handleVerify = async () => {\n    try {\n      // For OTP authenticators, you can skip challenge() and go straight to verify()\n      const tokens = await mfa.verify({ mfaToken, otp });\n      // User is now authenticated — tokens are cached by the SDK\n      console.log('MFA complete, access token:', tokens.access_token);\n    } catch (err) {\n      if (err instanceof MfaVerifyError) {\n        setError('Invalid code. Please try again.');\n      } else if (err instanceof MfaChallengeError) {\n        setError('Challenge failed: ' + err.error_description);\n      }\n    }\n  };\n\n  return (\n    <div>\n      <h3>Enter your verification code</h3>\n      <input\n        type=\"text\"\n        value={otp}\n        onChange={(e) => setOtp(e.target.value)}\n        placeholder=\"6-digit code\"\n        maxLength={6}\n      />\n      <button onClick={handleVerify}>Verify</button>\n      {error && <p style={{ color: 'red' }}>{error}</p>}\n    </div>\n  );\n}\n```\n\n### SMS/Email Challenge (Out-of-Band)\n\nFor SMS, Email, Voice, or Push authenticators, you must call `challenge()` first to send the code:\n\n```tsx\n// Initiate challenge to send code via SMS/Email\nconst response = await mfa.challenge({\n  mfaToken,\n  challengeType: 'oob',\n  authenticatorId: authenticator.id,\n});\n\n// Verify with the OOB code and the binding code the user received\nconst tokens = await mfa.verify({\n  mfaToken,\n  oobCode: response.oobCode,\n  bindingCode: userEnteredCode,\n});\n```\n\n### Step-Up via Popup (Simpler Approach)\n\nIf you don't need a custom MFA UI, configure `interactiveErrorHandler` to let the SDK handle MFA automatically via a Universal Login popup:\n\n```tsx\n<Auth0Provider\n  domain={import.meta.env.VITE_AUTH0_DOMAIN}\n  clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}\n  authorizationParams={{\n    redirect_uri: window.location.origin,\n    audience: 'https://your-api-identifier',\n  }}\n  useRefreshTokens={true}\n  interactiveErrorHandler=\"popup\"\n>\n  <App />\n</Auth0Provider>\n```\n\nWith this setup, `getAccessTokenSilently()` automatically opens a popup when MFA is required. No error handling needed — the token is returned after the user completes MFA in the popup.\n\n---\n\n## Security Considerations\n\n### Client-Side Security\n\n- **Never expose client secret** - React is client-side, use only public client credentials\n- **Use PKCE** - Enabled by default with @auth0/auth0-react\n- **Validate tokens on backend** - Never trust client-side token validation\n- **Use HTTPS in production** - Auth0 requires HTTPS for production redirect URLs\n- **Implement proper CORS** - Configure allowed origins in Auth0 application settings\n\n### Token Storage\n\n```tsx\n// Default: memory storage for highest security (tokens cleared on page refresh)\n<Auth0Provider\n  cacheLocation=\"memory\"\n  {...other props}\n>\n\n// Or localstorage for better UX (tokens persist across refreshes)\n<Auth0Provider\n  cacheLocation=\"localstorage\"\n  {...other props}\n>\n```\n\n### Secure API Calls\n\nAlways validate tokens on your backend:\n\n**Installation:**\n```bash\nnpm install express-oauth2-jwt-bearer\n```\n\n**Backend validation example (Node.js):**\n```javascript\nconst { auth, requiredScopes } = require('express-oauth2-jwt-bearer');\n\nconst checkJwt = auth({\n  audience: process.env.AUTH0_AUDIENCE,\n  issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`,\n});\n\napp.get('/api/private', checkJwt, (req, res) => {\n  res.json({ message: 'Secured data' });\n});\n\n// With scope validation\napp.get('/api/users', checkJwt, requiredScopes('read:users'), (req, res) => {\n  res.json({ users: [] });\n});\n```\n\n---\n\n## Advanced Patterns\n\n### Custom Login with Redirect Options\n\n```tsx\nconst { loginWithRedirect } = useAuth0();\n\n// Login with specific connection\nawait loginWithRedirect({\n  authorizationParams: {\n    connection: 'google-oauth2'\n  }\n});\n\n// Login with prompt\nawait loginWithRedirect({\n  authorizationParams: {\n    prompt: 'login' // Force login even if user has session\n  }\n});\n\n// Login with custom state\nawait loginWithRedirect({\n  appState: { targetUrl: '/protected-page' }\n});\n```\n\n### Handle Redirect Callback\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\nimport { useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\nexport function Callback() {\n  const { handleRedirectCallback } = useAuth0();\n  const navigate = useNavigate();\n\n  useEffect(() => {\n    (async () => {\n      const result = await handleRedirectCallback();\n      const targetUrl = result.appState?.targetUrl || '/';\n      navigate(targetUrl);\n    })();\n  }, [handleRedirectCallback, navigate]);\n\n  return <div>Processing login...</div>;\n}\n```\n\n### Custom Logout\n\n```tsx\nconst { logout } = useAuth0();\n\n// Logout with custom return URL\nlogout({\n  logoutParams: {\n    returnTo: `${window.location.origin}/goodbye`\n  }\n});\n\n// Logout without redirect (federated logout)\nlogout({\n  logoutParams: {\n    federated: true\n  }\n});\n```\n\n---\n\n## Testing\n\n### Manual Testing Checklist\n\n1. **Login Flow**\n   - Start dev server: `npm run dev` (Vite) or `npm start` (CRA)\n   - Click \"Login\" button\n   - Complete Auth0 Universal Login\n   - Verify redirect back to your app with user authenticated\n   - Check user profile displays correctly\n\n2. **Logout Flow**\n   - Click \"Logout\" button\n   - Verify user is logged out\n   - Verify redirect to correct page\n\n3. **Protected Routes**\n   - Navigate to protected route while logged out\n   - Verify redirect to Auth0 login\n   - After login, verify redirect back to protected route\n\n4. **API Calls**\n   - Call protected API endpoint\n   - Verify access token is included in request\n   - Verify API responds correctly\n\n---\n\n## Next Steps\n\n- [API Reference](api.md) - Complete SDK documentation, configuration options, hooks reference\n- [Setup Guide](setup.md) - Detailed setup instructions and scripts\n- [Main Skill](../SKILL.md) - Return to main skill guide\n\nFile v1.0.1:references/setup.md\n\n# Auth0 React Setup Guide\n\nComplete setup instructions with automated scripts and manual configuration options.\n\n---\n\n## Quick Setup (Automated)\n\n**Never read the contents of `.env` at any point during setup.** The file may contain sensitive secrets that should not be exposed in the LLM context. If you determine you need to read the file for any reason, ask the user for explicit permission before doing so — do not proceed until the user confirms.\n\n**Before running any part of this setup that writes to `.env`, you MUST ask the user for explicit confirmation.** Follow the steps below precisely.\n\n### Step 1: Check for existing .env and confirm with user\n\nBefore writing to `.env`, check whether the file already exists:\n\n```bash\ntest -f .env && echo \"EXISTS\" || echo \"NOT_FOUND\"\n```\n\nThen ask the user for explicit confirmation before proceeding — do not continue until the user confirms:\n\n- If `.env` does **not** exist, ask:\n  - Question: \"This setup will create a `.env` file containing Auth0 credentials (domain and client ID). Do you want to proceed?\"\n  - Options: \"Yes, create .env\" / \"No, I'll configure it manually\"\n\n- If `.env` **already exists**, ask:\n  - Question: \"A `.env` file already exists and may contain secrets unrelated to Auth0. This setup will append Auth0 credentials to it without modifying existing content. Do you want to proceed?\"\n  - Options: \"Yes, append to existing .env\" / \"No, I'll update it manually\"\n\n**Do not proceed with writing to `.env` unless the user selects the confirmation option.**\n\n### Step 2: Run automated setup (only after confirmation)\n\n#### Bash Script (macOS/Linux)\n\nRun this script to automatically set up everything:\n\n```bash\n#!/bin/bash\n\n# Detect OS and install Auth0 CLI if needed\nif ! command -v auth0 &> /dev/null; then\n  echo \"Installing Auth0 CLI...\"\n  if [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n    brew install auth0/auth0-cli/auth0\n  elif [[ \"$OSTYPE\" == \"linux-gnu\"* ]]; then\n    # Download and review the install script before executing\n    curl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh -o /tmp/auth0-install.sh\n    echo \"⚠️  Review the install script at /tmp/auth0-install.sh before running\"\n    sh /tmp/auth0-install.sh -b /usr/local/bin\n    rm /tmp/auth0-install.sh\n  elif [[ \"$OSTYPE\" == \"msys\" || \"$OSTYPE\" == \"cygwin\" ]]; then\n    echo \"Please install Auth0 CLI: https://github.com/auth0/auth0-cli#installation\"\n    exit 1\n  fi\nfi\n\n# Check if logged in to Auth0\nif ! auth0 tenants list &> /dev/null; then\n  echo \"\"\n  echo \"======================================\"\n  echo \"Auth0 Login Required\"\n  echo \"======================================\"\n  echo \"\"\n  read -p \"Do you have an Auth0 account? (y/n): \" HAS_ACCOUNT\n\n  if [[ \"$HAS_ACCOUNT\" != \"y\" ]]; then\n    echo \"\"\n    echo \"Let's create your free Auth0 account!\"\n    echo \"\"\n    echo \"1. Visit: https://auth0.com/signup\"\n    echo \"2. Sign up with your email or GitHub\"\n    echo \"3. Choose a tenant domain (e.g., 'mycompany')\"\n    echo \"4. Complete the onboarding\"\n    echo \"\"\n    read -p \"Press Enter when you've created your account...\"\n  fi\n\n  echo \"\"\n  echo \"Logging in to Auth0...\"\n  echo \"A browser will open for authentication.\"\n  echo \"\"\n  auth0 login\n\n  if ! auth0 tenants list &> /dev/null; then\n    echo \"❌ Login failed. Please try again or visit https://auth0.com/docs\"\n    exit 1\n  fi\n\n  echo \"✅ Successfully logged in to Auth0!\"\nfi\n\n# Detect if Vite or CRA\nif grep -q '\"vite\"' package.json 2>/dev/null; then\n  PREFIX=\"VITE_AUTH0\"\nelif grep -q '\"react-scripts\"' package.json 2>/dev/null; then\n  PREFIX=\"REACT_APP_AUTH0\"\nelse\n  echo \"Detecting React project type...\"\n  PREFIX=\"VITE_AUTH0\"  # Default to Vite\nfi\n\n# List apps and prompt for selection\necho \"Your Auth0 applications:\"\nauth0 apps list\n\nread -p \"Enter your Auth0 app ID (or press Enter to create a new one): \" APP_ID\n\nif [ -z \"$APP_ID\" ]; then\n  echo \"Creating new Auth0 SPA application...\"\n  APP_NAME=\"${PWD##*/}-react-app\"\n  APP_ID=$(auth0 apps create \\\n    --name \"$APP_NAME\" \\\n    --type spa \\\n    --callbacks \"http://localhost:3000,http://localhost:5173\" \\\n    --logout-urls \"http://localhost:3000,http://localhost:5173\" \\\n    --origins \"http://localhost:3000,http://localhost:5173\" \\\n    --web-origins \"http://localhost:3000,http://localhost:5173\" \\\n    --metadata \"created_by=agent_skills\" \\\n    --json | grep -o '\"client_id\":\"[^\"]*' | cut -d'\"' -f4)\n  echo \"Created app with ID: $APP_ID\"\nfi\n\n# Get app details and create .env file\necho \"Fetching Auth0 credentials...\"\nAUTH0_DOMAIN=$(auth0 apps show \"$APP_ID\" --json | grep -o '\"domain\":\"[^\"]*' | cut -d'\"' -f4)\nAUTH0_CLIENT_ID=$(auth0 apps show \"$APP_ID\" --json | grep -o '\"client_id\":\"[^\"]*' | cut -d'\"' -f4)\n\n# Append Auth0 credentials to .env\ncat >> .env << EOF\n${PREFIX}_DOMAIN=$AUTH0_DOMAIN\n${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID\nEOF\n\necho \"✅ Auth0 configuration complete!\"\necho \"Appended to .env:\"\necho \"  ${PREFIX}_DOMAIN=$AUTH0_DOMAIN\"\necho \"  ${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID\"\n```\n\n#### PowerShell Script (Windows)\n\n```powershell\n# Install Auth0 CLI if not present\nif (!(Get-Command auth0 -ErrorAction SilentlyContinue)) {\n  Write-Host \"Installing Auth0 CLI...\"\n  scoop install auth0\n}\n\n# Check if logged in\ntry {\n  auth0 tenants list | Out-Null\n} catch {\n  Write-Host \"\"\n  Write-Host \"======================================\"\n  Write-Host \"Auth0 Login Required\"\n  Write-Host \"======================================\"\n  Write-Host \"\"\n\n  $hasAccount = Read-Host \"Do you have an Auth0 account? (y/n)\"\n\n  if ($hasAccount -ne \"y\") {\n    Write-Host \"\"\n    Write-Host \"Let's create your free Auth0 account!\"\n    Write-Host \"\"\n    Write-Host \"1. Visit: https://auth0.com/signup\"\n    Write-Host \"2. Sign up with your email or GitHub\"\n    Write-Host \"3. Choose a tenant domain (e.g., 'mycompany')\"\n    Write-Host \"4. Complete the onboarding\"\n    Write-Host \"\"\n    Read-Host \"Press Enter when you've created your account\"\n  }\n\n  Write-Host \"\"\n  Write-Host \"Logging in to Auth0...\"\n  Write-Host \"A browser will open for authentication.\"\n  Write-Host \"\"\n  auth0 login\n\n  try {\n    auth0 tenants list | Out-Null\n    Write-Host \"✅ Successfully logged in to Auth0!\"\n  } catch {\n    Write-Host \"❌ Login failed. Please try again or visit https://auth0.com/docs\"\n    exit 1\n  }\n}\n\n# Detect project type\n$prefix = if (Select-String -Path \"package.json\" -Pattern '\"vite\"' -Quiet) { \"VITE_AUTH0\" }\n          elseif (Select-String -Path \"package.json\" -Pattern '\"react-scripts\"' -Quiet) { \"REACT_APP_AUTH0\" }\n          else { \"VITE_AUTH0\" }\n\n# List and select app\nWrite-Host \"Your Auth0 applications:\"\nauth0 apps list\n\n$appId = Read-Host \"Enter your Auth0 app ID (or press Enter to create new)\"\n\nif ([string]::IsNullOrEmpty($appId)) {\n  $appName = Split-Path -Leaf (Get-Location)\n  Write-Host \"Creating new Auth0 SPA application...\"\n  $appJson = auth0 apps create --name \"$appName-react-app\" --type spa `\n    --callbacks \"http://localhost:3000,http://localhost:5173\" `\n    --logout-urls \"http://localhost:3000,http://localhost:5173\" `\n    --origins \"http://localhost:3000,http://localhost:5173\" `\n    --web-origins \"http://localhost:3000,http://localhost:5173\" `\n    --metadata \"created_by=agent_skills\" --json\n\n  $appId = ($appJson | ConvertFrom-Json).client_id\n  Write-Host \"Created app with ID: $appId\"\n}\n\n# Get credentials and create .env\nWrite-Host \"Fetching Auth0 credentials...\"\n$appDetails = auth0 apps show $appId --json | ConvertFrom-Json\n\n@\"\n${prefix}_DOMAIN=$($appDetails.domain)\n${prefix}_CLIENT_ID=$($appDetails.client_id)\n\"@ | Out-File -FilePath .env -Encoding UTF8 -Append\n\nWrite-Host \"✅ Auth0 configuration complete!\"\nWrite-Host \"Appended to .env:\"\nWrite-Host \"  ${prefix}_DOMAIN=$($appDetails.domain)\"\nWrite-Host \"  ${prefix}_CLIENT_ID=$($appDetails.client_id)\"\n```\n\n---\n\n## Manual Setup\n\nIf you prefer manual setup or the scripts don't work:\n\n### Step 1: Install SDK\n\n```bash\nnpm install @auth0/auth0-react\n```\n\n### Step 2: Install Auth0 CLI\n\n**macOS:**\n```bash\nbrew install auth0/auth0-cli/auth0\n```\n\n**Linux (review script before executing):**\n```bash\ncurl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh -o /tmp/auth0-install.sh\n# Review the script before running: cat /tmp/auth0-install.sh\nsh /tmp/auth0-install.sh\nrm /tmp/auth0-install.sh\n```\n\n**Windows:**\n```powershell\nscoop install auth0\n# Or: choco install auth0-cli\n```\n\n### Step 3: Get Credentials\n\n```bash\n# Login to Auth0\nauth0 login\n\n# List your apps\nauth0 apps list\n\n# Get app details (replace <app-id>)\nauth0 apps show <app-id>\n```\n\n### Step 4: Create .env File\n\n**For Vite:**\n```bash\nVITE_AUTH0_DOMAIN=<your-tenant>.auth0.com\nVITE_AUTH0_CLIENT_ID=<your-client-id>\n```\n\n**For Create React App:**\n```bash\nREACT_APP_AUTH0_DOMAIN=<your-tenant>.auth0.com\nREACT_APP_AUTH0_CLIENT_ID=<your-client-id>\n```\n\n---\n\n## Creating an Auth0 Application via Dashboard\n\nIf you prefer using the Auth0 Dashboard instead of the CLI:\n\n1. Go to [Auth0 Dashboard](https://manage.auth0.com)\n2. Navigate to **Applications** → **Applications**\n3. Click **Create Application**\n4. Choose:\n   - Name: Your app name\n   - Type: **Single Page Web Applications**\n5. Configure:\n   - **Allowed Callback URLs**: `http://localhost:3000, http://localhost:5173`\n   - **Allowed Logout URLs**: `http://localhost:3000, http://localhost:5173`\n   - **Allowed Web Origins**: `http://localhost:3000, http://localhost:5173`\n   - **Allowed Origins (CORS)**: `http://localhost:3000, http://localhost:5173`\n6. Copy your **Domain** and **Client ID**\n7. Create `.env` file as shown in Step 4 above\n\n---\n\n## Troubleshooting Setup\n\n### CLI Installation Issues\n\n**macOS - Homebrew not found:**\n```bash\n# Install Homebrew first\n/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n```\n\n**Windows - Scoop not found:**\n```powershell\n# Install Scoop first\niwr -useb get.scoop.sh | iex\n```\n\n### Login Issues\n\n**Browser doesn't open:**\n```bash\n# Use device code flow\nauth0 login --no-browser\n```\n\n**\"Not logged in\" error:**\n```bash\n# Force new login\nauth0 login --force\n```\n\n### Environment Variable Issues\n\n**Variables not loading (Vite):**\n- Ensure variables start with `VITE_`\n- Restart dev server after creating `.env`\n- Check file is named exactly `.env` (not `.env.local`)\n\n**Variables not loading (CRA):**\n- Ensure variables start with `REACT_APP_`\n- Restart dev server after creating `.env`\n- CRA doesn't support `.env` hot reload\n\n---\n\n## Next Steps\n\nAfter setup is complete:\n1. Return to [main skill guide](../SKILL.md) for integration steps\n2. See [Integration Guide](integration.md) for advanced patterns\n3. Check [API Reference](api.md) for complete SDK documentation\n\nFile v1.0.1:skill-card.md\n\n## Description: <br>\nUse when adding authentication to React applications (login, logout, user sessions, protected routes) - integrates @auth0/auth0-react SDK for SPAs with Vite or Create React App. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[auth0](https://clawhub.ai/user/auth0) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and engineers use this skill to add Auth0 authentication to React single-page applications, including login, logout, session handling, protected routes, API token usage, and MFA patterns. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Setup guidance may install the Auth0 CLI, create or modify Auth0 applications, and append Auth0 values to a .env file. <br>\nMitigation: Review setup commands before running them, confirm tenant and application changes explicitly, and inspect .env changes without exposing existing secrets. <br>\nRisk: Token-handling examples can expose bearer tokens too casually, including an access-token console log. <br>\nMitigation: Remove token logging before use and avoid copying examples that display or persist bearer tokens unnecessarily. <br>\nRisk: Using localStorage for token storage can increase exposure if the application has cross-site scripting weaknesses. <br>\nMitigation: Prefer in-memory token storage unless persistent storage is required and the application has strong XSS protections. <br>\n\n\n## Reference(s): <br>\n- [Setup Guide](references/setup.md) <br>\n- [Integration Guide](references/integration.md) <br>\n- [API Reference](references/api.md) <br>\n- [Auth0 React SDK Documentation](https://auth0.com/docs/libraries/auth0-react) <br>\n- [Auth0 React Quickstart](https://auth0.com/docs/quickstart/spa/react) <br>\n- [Auth0 React SDK Repository](https://github.com/auth0/auth0-react) <br>\n- [Auth0 Agent Skills Homepage](https://github.com/auth0/agent-skills) <br>\n- [Auth0 React on ClawHub](https://clawhub.ai/auth0/auth0-react) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown with TypeScript, shell, and configuration snippets] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May include Auth0 CLI commands and React SDK configuration examples that require user review before execution.] <br>\n\n## Skill Version(s): <br>\n1.0.1 (source: release evidence and frontmatter) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.0.0: 5 files, 16819 bytes\n\nFiles: references/api.md (16302b), references/integration.md (14166b), references/setup.md (10278b), SKILL.md (6558b), _meta.json (130b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: auth0-react\ndescription: Use when adding authentication to React applications (login, logout, user sessions, protected routes) - integrates @auth0/auth0-react SDK for SPAs with Vite or Create React App\nlicense: Apache-2.0\nmetadata:\n  author: Auth0 <support@auth0.com>\n  version: '1.0.0'\n  openclaw:\n    emoji: \"\\U0001F510\"\n    homepage: https://github.com/auth0/agent-skills\n---\n\n# Auth0 React Integration\n\nAdd authentication to React single-page applications using @auth0/auth0-react.\n\n---\n\n## Prerequisites\n\n- React 16.11+ application (Vite or Create React App) - supports React 16, 17, 18, and 19\n- Auth0 account and application configured\n- If you don't have Auth0 set up yet, use the `auth0-quickstart` skill first\n\n## When NOT to Use\n\n- **Next.js applications** - Use `auth0-nextjs` skill for both App Router and Pages Router\n- **React Native mobile apps** - Use `auth0-react-native` skill for iOS/Android\n- **Server-side rendered React** - Use framework-specific SDK (Next.js, Remix, etc.)\n- **Embedded login** - This SDK uses Auth0 Universal Login (redirect-based)\n- **Backend API authentication** - Use express-openid-connect or JWT validation instead\n\n---\n\n## Quick Start Workflow\n\n### 1. Install SDK\n\n```bash\nnpm install @auth0/auth0-react\n```\n\n### 2. Configure Environment\n\n**For automated setup with Auth0 CLI**, see [Setup Guide](references/setup.md) for complete scripts.\n\n**For manual setup:**\n\nCreate `.env` file:\n\n**Vite:**\n```bash\nVITE_AUTH0_DOMAIN=your-tenant.auth0.com\nVITE_AUTH0_CLIENT_ID=your-client-id\n```\n\n**Create React App:**\n```bash\nREACT_APP_AUTH0_DOMAIN=your-tenant.auth0.com\nREACT_APP_AUTH0_CLIENT_ID=your-client-id\n```\n\n### 3. Wrap App with Auth0Provider\n\nUpdate `src/main.tsx` (Vite) or `src/index.tsx` (CRA):\n\n```tsx\nimport React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport { Auth0Provider } from '@auth0/auth0-react';\nimport App from './App';\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n  <React.StrictMode>\n    <Auth0Provider\n      domain={import.meta.env.VITE_AUTH0_DOMAIN} // or process.env.REACT_APP_AUTH0_DOMAIN\n      clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}\n      authorizationParams={{\n        redirect_uri: window.location.origin\n      }}\n    >\n      <App />\n    </Auth0Provider>\n  </React.StrictMode>\n);\n```\n\n### 4. Add Authentication UI\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\n\nexport function LoginButton() {\n  const { loginWithRedirect, logout, isAuthenticated, user, isLoading } = useAuth0();\n\n  if (isLoading) return <div>Loading...</div>;\n\n  if (isAuthenticated) {\n    return (\n      <div>\n        <span>Welcome, {user?.name}</span>\n        <button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>\n          Logout\n        </button>\n      </div>\n    );\n  }\n\n  return <button onClick={() => loginWithRedirect()}>Login</button>;\n}\n```\n\n### 5. Test Authentication\n\nStart your dev server and test the login flow:\n\n```bash\nnpm run dev  # Vite\n# or\nnpm start    # CRA\n```\n\n---\n\n## Detailed Documentation\n\n- **[Setup Guide](references/setup.md)** - Automated setup scripts (Bash/PowerShell), CLI commands, manual configuration\n- **[Integration Guide](references/integration.md)** - Protected routes, API calls, error handling, advanced patterns\n- **[API Reference](references/api.md)** - Complete SDK API, configuration options, hooks reference, testing strategies\n\n---\n\n## Common Mistakes\n\n| Mistake | Fix |\n|---------|-----|\n| Forgot to add redirect URI in Auth0 Dashboard | Add your application URL (e.g., `http://localhost:3000`, `https://app.example.com`) to Allowed Callback URLs in Auth0 Dashboard |\n| Using wrong env var prefix | Vite uses `VITE_` prefix, Create React App uses `REACT_APP_` |\n| Not handling loading state | Always check `isLoading` before rendering auth-dependent UI |\n| Storing tokens in localStorage | Never manually store tokens - SDK handles secure storage automatically |\n| Missing Auth0Provider wrapper | Entire app must be wrapped in `<Auth0Provider>` |\n| Provider not at root level | Auth0Provider must wrap all components that use auth hooks |\n| Wrong import path for env vars | Vite uses `import.meta.env.VITE_*`, CRA uses `process.env.REACT_APP_*` |\n| Using `acr_values` redirect for in-app MFA | Use `useAuth0().mfa` API for in-app enrollment/challenge/verify flows |\n| Not catching `MfaRequiredError` | Wrap `getAccessTokenSilently` in try/catch and check `instanceof MfaRequiredError` |\n| Making direct HTTP calls to MFA endpoints | Use the `mfa` property from `useAuth0()` — it handles token management automatically |\n| Forgetting refresh tokens for step-up MFA | Set `useRefreshTokens={true}` on Auth0Provider when using `interactiveErrorHandler=\"popup\"` |\n\n---\n\n## Related Skills\n\n- `auth0-quickstart` - Basic Auth0 setup\n- `auth0-migration` - Migrate from another auth provider\n- `auth0-mfa` - Add Multi-Factor Authentication\n\n---\n\n## Quick Reference\n\n**Core Hooks:**\n- `useAuth0()` - Main authentication hook\n- `isAuthenticated` - Check if user is logged in\n- `user` - User profile information\n- `loginWithRedirect()` - Initiate login\n- `logout()` - Log out user\n- `getAccessTokenSilently()` - Get access token for API calls\n- `mfa` - MFA API client for enrollment, challenge, and verification\n  - `mfa.getAuthenticators(mfaToken)` - List enrolled authenticators\n  - `mfa.getEnrollmentFactors(mfaToken)` - Get available enrollment factors\n  - `mfa.enroll(params)` - Enroll new authenticator (OTP, SMS, Email, Voice, Push)\n  - `mfa.challenge(params)` - Initiate MFA challenge\n  - `mfa.verify(params)` - Verify MFA challenge and complete authentication\n\n**MFA Error Types (import from `@auth0/auth0-react`):**\n- `MfaRequiredError` - Thrown by `getAccessTokenSilently` when MFA is needed (has `mfa_token` and `mfa_requirements`)\n- `MfaEnrollmentError`, `MfaChallengeError`, `MfaVerifyError` - Thrown by respective `mfa.*` methods\n\n**Common Use Cases:**\n- Login/Logout buttons → See Step 4 above\n- Protected routes → [Integration Guide](references/integration.md#protected-routes)\n- API calls with tokens → [Integration Guide](references/integration.md#calling-apis)\n- Error handling → [Integration Guide](references/integration.md#error-handling)\n- MFA handling → [Integration Guide](references/integration.md#mfa-handling)\n\n---\n\n## References\n\n- [Auth0 React SDK Documentation](https://auth0.com/docs/libraries/auth0-react)\n- [Auth0 React Quickstart](https://auth0.com/docs/quickstart/spa/react)\n- [SDK GitHub Repository](https://github.com/auth0/auth0-react)\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7cjgtjqyx9kzrhcrr56tyzd183x56s\",\n  \"slug\": \"auth0-react\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1776271712728\n}\n\nFile v1.0.0:references/api.md\n\n# Auth0 React SDK API Reference\n\nComplete API documentation for @auth0/auth0-react SDK.\n\n---\n\n## Auth0Provider Configuration\n\n### Complete Configuration Options\n\n```tsx\nimport { Auth0Provider } from '@auth0/auth0-react';\n\n<Auth0Provider\n  // Required\n  domain=\"your-tenant.auth0.com\"\n  clientId=\"your-client-id\"\n\n  // Authorization parameters\n  authorizationParams={{\n    redirect_uri: window.location.origin,\n    audience: 'https://your-api-identifier', // For API calls\n    scope: 'openid profile email', // Default scopes\n    connection: 'google-oauth2', // Force specific connection\n    prompt: 'login', // Force login prompt\n    ui_locales: 'en', // Localization\n    screen_hint: 'signup', // Show signup page by default\n  }}\n\n  // Token management\n  cacheLocation=\"localstorage\" // or \"memory\" for stricter security (default: \"memory\")\n  useRefreshTokens={true} // Enable refresh tokens (default: false)\n  useRefreshTokensFallback={false} // Fall back to iframe if refresh token exchange fails (default: false)\n  useMrrt={false} // Enable Multi-Refresh-Token for multi-tenant apps (default: false)\n\n  // MFA / Step-up\n  interactiveErrorHandler=\"popup\" // Automatically handle MFA via popup (requires useRefreshTokens)\n\n  // Advanced options\n  skipRedirectCallback={false} // Skip automatic callback handling\n  context={Auth0Context} // Custom React context\n\n  // Callbacks\n  onRedirectCallback={(appState) => {\n    // Handle redirect after login\n    // appState receives the custom state passed to loginWithRedirect()\n    // Example: if login was called with appState: { targetUrl: '/dashboard' }\n    // then appState.targetUrl will be '/dashboard' here\n    window.location.replace(appState?.returnTo || '/');\n  }}\n>\n  <App />\n</Auth0Provider>\n```\n\n### Configuration Properties\n\n| Property | Type | Default | Description |\n|----------|------|---------|-------------|\n| `domain` | string | **Required** | Your Auth0 tenant domain |\n| `clientId` | string | **Required** | Your Auth0 application client ID |\n| `authorizationParams` | object | `{}` | Authorization parameters (see below) |\n| `cacheLocation` | `'memory' \\| 'localstorage'` | `'memory'` | Where to store tokens |\n| `useRefreshTokens` | boolean | `false` | Enable refresh token rotation |\n| `useRefreshTokensFallback` | boolean | `false` | Fall back to iframe if refresh token exchange fails |\n| `useMrrt` | boolean | `false` | Enable Multi-Refresh-Token support for multi-tenant apps. Requires `useRefreshTokens` and `useRefreshTokensFallback` to be `true` |\n| `workerUrl` | string | - | Custom worker script URL for token calls. Useful for CSP compliance when using `useRefreshTokens: true` with `cacheLocation: 'memory'` |\n| `context` | React.Context | - | Custom React context for nested Auth0Providers. Allows multiple Auth0Providers in same app |\n| `interactiveErrorHandler` | `'popup'` | - | Automatically handle MFA via popup when `getAccessTokenSilently` encounters `mfa_required`. Requires `useRefreshTokens={true}` |\n| `skipRedirectCallback` | boolean | `false` | Skip automatic callback handling |\n| `onRedirectCallback` | function | - | Callback after successful login |\n\n### Authorization Parameters\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `redirect_uri` | string | URL to redirect after authentication |\n| `audience` | string | API audience identifier |\n| `scope` | string | Requested scopes (space-separated) |\n| `connection` | string | Force specific connection |\n| `prompt` | string | `'none'`, `'login'`, `'consent'`, or `'select_account'` |\n| `ui_locales` | string | Language code (e.g., `'en'`, `'es'`) |\n| `screen_hint` | string | `'signup'` to show signup by default |\n| `max_age` | number | Maximum authentication age in seconds |\n| `organization` | string | Organization ID for B2B |\n| `invitation` | string | Invitation ID for organization invites |\n\n---\n\n## useAuth0 Hook\n\n### Hook Interface\n\n```typescript\nconst {\n  // Authentication state\n  isLoading,\n  isAuthenticated,\n  error,\n  user,\n\n  // Methods\n  loginWithRedirect,\n  loginWithPopup,\n  logout,\n  getAccessTokenSilently,\n  getAccessTokenWithPopup,\n  getIdTokenClaims,\n  handleRedirectCallback,\n\n  // MFA API\n  mfa,\n} = useAuth0();\n```\n\n### Authentication State\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `isLoading` | boolean | True while Auth0 is initializing |\n| `isAuthenticated` | boolean | True if user is logged in |\n| `error` | Error \\| undefined | Authentication error if any |\n| `user` | User \\| undefined | User profile information |\n\n### User Object\n\n```typescript\ninterface User {\n  sub: string;          // User ID\n  name: string;         // Display name\n  email: string;        // Email address\n  email_verified: boolean;\n  picture: string;      // Avatar URL\n  updated_at: string;   // Last update timestamp\n  // Custom claims...\n}\n```\n\n### Methods\n\n#### loginWithRedirect\n\n```typescript\nawait loginWithRedirect(options?: RedirectLoginOptions);\n```\n\nRedirects to Auth0 Universal Login page.\n\n**Options:**\n```typescript\ninterface RedirectLoginOptions {\n  authorizationParams?: {\n    redirect_uri?: string;\n    audience?: string;\n    scope?: string;\n    connection?: string;\n    prompt?: 'none' | 'login' | 'consent' | 'select_account';\n    max_age?: number;\n    ui_locales?: string;\n    screen_hint?: 'signup' | 'login';\n  };\n  appState?: any; // Custom state to preserve\n  fragment?: string; // URL fragment\n}\n```\n\n**Example:**\n```tsx\n// Basic login\nawait loginWithRedirect();\n\n// Login with specific connection\nawait loginWithRedirect({\n  authorizationParams: {\n    connection: 'google-oauth2'\n  }\n});\n\n// Login with custom state (preserved through redirect)\nawait loginWithRedirect({\n  appState: { targetUrl: '/dashboard' }\n});\n// After login, onRedirectCallback receives appState.targetUrl = '/dashboard'\n```\n\n#### loginWithPopup\n\n```typescript\nawait loginWithPopup(options?: PopupLoginOptions);\n```\n\nOpens Auth0 login in popup window (better UX, but may be blocked).\n\n**Options:**\n```typescript\ninterface PopupLoginOptions {\n  authorizationParams?: AuthorizationParams;\n  config?: PopupConfigOptions; // Popup window configuration\n}\n```\n\n**Example:**\n```tsx\ntry {\n  await loginWithPopup();\n} catch (error) {\n  // Handle popup blocked or closed\n  console.error('Popup login failed:', error);\n}\n```\n\n#### logout\n\n```typescript\nlogout(options?: LogoutOptions);\n```\n\nLogs out the user and optionally redirects.\n\n**Options:**\n```typescript\ninterface LogoutOptions {\n  logoutParams?: {\n    returnTo?: string; // URL to redirect after logout\n    federated?: boolean; // Logout from identity provider too\n    client_id?: string; // Client ID (if different from current)\n  };\n  openUrl?: (url: string) => void; // Custom URL opener\n}\n```\n\n**Example:**\n```tsx\n// Basic logout\nlogout();\n\n// Logout with redirect\nlogout({\n  logoutParams: {\n    returnTo: window.location.origin\n  }\n});\n\n// Federated logout (logout from Google/Facebook too)\nlogout({\n  logoutParams: {\n    returnTo: window.location.origin,\n    federated: true\n  }\n});\n```\n\n#### getAccessTokenSilently\n\n```typescript\nconst token = await getAccessTokenSilently(options?: GetTokenSilentlyOptions);\n```\n\nGets access token without user interaction (uses refresh token or iframe).\n\n**Options:**\n```typescript\ninterface GetTokenSilentlyOptions {\n  authorizationParams?: {\n    audience?: string;\n    scope?: string;\n    ignoreCache?: boolean; // Force new token\n    timeoutInSeconds?: number; // Request timeout\n    detailedResponse?: boolean; // Return full response with expiry\n  };\n}\n```\n\n**Example:**\n```tsx\n// Basic usage\nconst token = await getAccessTokenSilently();\n\n// With specific audience\nconst token = await getAccessTokenSilently({\n  authorizationParams: {\n    audience: 'https://api.example.com'\n  }\n});\n\n// Force fresh token\nconst token = await getAccessTokenSilently({\n  authorizationParams: {\n    ignoreCache: true\n  }\n});\n\n// Get detailed response with expiry\nconst { access_token, expires_in } = await getAccessTokenSilently({\n  authorizationParams: {\n    detailedResponse: true\n  }\n});\n```\n\n#### getAccessTokenWithPopup\n\n```typescript\nconst token = await getAccessTokenWithPopup(options?: GetTokenWithPopupOptions);\n```\n\nGets access token via popup window. Useful as fallback when `getAccessTokenSilently` fails (e.g., third-party cookies blocked).\n\n**Options:**\n```typescript\ninterface GetTokenWithPopupOptions {\n  authorizationParams?: {\n    audience?: string;\n    scope?: string;\n  };\n  config?: PopupConfigOptions; // Popup window configuration\n}\n```\n\n**Example:**\n```tsx\n// Try silent auth, fall back to popup\ntry {\n  const token = await getAccessTokenSilently();\n} catch (error) {\n  // Fallback to popup if silent auth fails\n  const token = await getAccessTokenWithPopup();\n}\n\n// Direct popup usage with specific audience\nconst token = await getAccessTokenWithPopup({\n  authorizationParams: {\n    audience: 'https://api.example.com'\n  }\n});\n```\n\n#### getIdTokenClaims\n\n```typescript\nconst claims = await getIdTokenClaims();\n```\n\nReturns ID token claims.\n\n**Example:**\n```tsx\nconst claims = await getIdTokenClaims();\nconsole.log(claims.sub); // User ID\nconsole.log(claims.email);\nconsole.log(claims.custom_claim);\n```\n\n#### handleRedirectCallback\n\n```typescript\nconst result = await handleRedirectCallback(url?: string);\n```\n\nManually handle redirect callback (when `skipRedirectCallback` is true).\n\n**Returns:**\n```typescript\ninterface RedirectLoginResult {\n  appState: any; // Custom state from login\n}\n```\n\n#### mfa\n\nThe `mfa` property provides access to the MFA API client for in-app Multi-Factor Authentication flows.\n\n**Methods:**\n\n| Method | Description |\n|--------|-------------|\n| `mfa.getAuthenticators(mfaToken)` | List enrolled authenticators for the user |\n| `mfa.getEnrollmentFactors(mfaToken)` | Get available enrollment factors (when user needs to enroll) |\n| `mfa.enroll(params)` | Enroll a new authenticator (OTP, SMS, Email, Voice, Push) |\n| `mfa.challenge(params)` | Initiate an MFA challenge for an enrolled authenticator |\n| `mfa.verify(params)` | Verify an MFA challenge and complete authentication |\n\n**Enroll params:**\n\n```typescript\n// OTP enrollment\nawait mfa.enroll({ mfaToken, factorType: 'otp' });\n// Returns: { barcodeUri, recoveryCodes, ... }\n\n// SMS enrollment\nawait mfa.enroll({ mfaToken, factorType: 'sms', phoneNumber: '+12025551234' });\n\n// Email enrollment\nawait mfa.enroll({ mfaToken, factorType: 'email', email: 'user@example.com' });\n\n// Voice enrollment\nawait mfa.enroll({ mfaToken, factorType: 'voice', phoneNumber: '+12025551234' });\n\n// Push enrollment\nawait mfa.enroll({ mfaToken, factorType: 'push' });\n```\n\n**Challenge params:**\n\n```typescript\n// OTP challenge (optional — code is already in authenticator app)\nawait mfa.challenge({ mfaToken, challengeType: 'otp', authenticatorId });\n\n// SMS/Voice/Email/Push challenge (required — sends code to user)\nawait mfa.challenge({ mfaToken, challengeType: 'oob', authenticatorId });\n// Returns: { oobCode }\n```\n\n**Verify params:**\n\n```typescript\n// Verify with OTP code\nconst tokens = await mfa.verify({ mfaToken, otp: '123456' });\n\n// Verify with OOB code (SMS/Voice/Email)\nconst tokens = await mfa.verify({ mfaToken, oobCode, bindingCode: '123456' });\n\n// Verify with recovery code\nconst tokens = await mfa.verify({ mfaToken, recoveryCode: 'recovery-code-here' });\n```\n\n---\n\n### MFA Error Types\n\nAll MFA error types are importable from `@auth0/auth0-react`.\n\n| Error | When thrown | Key properties |\n|-------|-----------|----------------|\n| `MfaRequiredError` | `getAccessTokenSilently()` encounters an MFA requirement | `mfa_token`, `mfa_requirements` |\n| `MfaEnrollmentError` | `mfa.enroll()` fails | `error_description` |\n| `MfaChallengeError` | `mfa.challenge()` fails | `error_description` |\n| `MfaVerifyError` | `mfa.verify()` fails (e.g., invalid OTP code) | `error_description` |\n| `MfaListAuthenticatorsError` | `mfa.getAuthenticators()` fails | `error_description` |\n| `MfaEnrollmentFactorsError` | `mfa.getEnrollmentFactors()` fails | `error_description` |\n\n**MfaRequiredError properties:**\n- `mfa_token` — Token used for all subsequent MFA operations\n- `mfa_requirements.enroll` — Array of factor types the user can enroll in (present when user needs to set up MFA)\n- `mfa_requirements.challenge` — Array of factor types the user can challenge (present when user has enrolled authenticators)\n\n**Import:**\n\n```typescript\nimport {\n  MfaRequiredError,\n  MfaEnrollmentError,\n  MfaChallengeError,\n  MfaVerifyError,\n} from '@auth0/auth0-react';\n```\n\n---\n\n## Custom Hooks\n\n### withAuth0\n\nHigher-order component for class components:\n\n```tsx\nimport { withAuth0 } from '@auth0/auth0-react';\n\nclass Profile extends React.Component {\n  render() {\n    const { auth0, isLoading, isAuthenticated, user } = this.props;\n    // Use auth0 methods and state\n  }\n}\n\nexport default withAuth0(Profile);\n```\n\n### withAuthenticationRequired\n\nHOC to protect components requiring authentication:\n\n```tsx\nimport { withAuthenticationRequired } from '@auth0/auth0-react';\n\nconst ProtectedComponent = () => {\n  return <div>Protected content</div>;\n};\n\nexport default withAuthenticationRequired(ProtectedComponent, {\n  onRedirecting: () => <div>Loading...</div>,\n  returnTo: '/profile', // Where to return after login\n  loginOptions: {\n    authorizationParams: {\n      connection: 'google-oauth2'\n    }\n  }\n});\n```\n\n---\n\n## Testing\n\n### Testing with React Testing Library\n\n```tsx\nimport { render, screen } from '@testing-library/react';\nimport { Auth0Provider } from '@auth0/auth0-react';\nimport App from './App';\n\n// Mock Auth0\njest.mock('@auth0/auth0-react', () => ({\n  ...jest.requireActual('@auth0/auth0-react'),\n  Auth0Provider: ({ children }) => children,\n  useAuth0: () => ({\n    isLoading: false,\n    isAuthenticated: true,\n    user: {\n      name: 'Test User',\n      email: 'test@example.com'\n    },\n    loginWithRedirect: jest.fn(),\n    logout: jest.fn(),\n  }),\n}));\n\ntest('renders authenticated app', () => {\n  render(<App />);\n  expect(screen.getByText('Test User')).toBeInTheDocument();\n});\n```\n\n### Testing with Custom Mock\n\n```tsx\n// testUtils.tsx\nimport { Auth0Provider } from '@auth0/auth0-react';\n\nexport const mockAuth0User = {\n  name: 'Test User',\n  email: 'test@example.com',\n  picture: 'https://example.com/avatar.jpg',\n};\n\nexport function renderWithAuth0(ui: React.ReactElement, isAuthenticated = true) {\n  return render(\n    <Auth0Provider\n      domain=\"test.auth0.com\"\n      clientId=\"test-client-id\"\n      authorizationParams={{\n        redirect_uri: window.location.origin\n      }}\n    >\n      {ui}\n    </Auth0Provider>\n  );\n}\n```\n\n---\n\n## TypeScript Types\n\n### Import Types\n\n```typescript\nimport type {\n  Auth0ContextInterface,\n  User,\n  RedirectLoginOptions,\n  PopupLoginOptions,\n  LogoutOptions,\n  GetTokenSilentlyOptions,\n  MfaApiClient,\n  Authenticator,\n  EnrollParams,\n  ChallengeResponse,\n  VerifyParams,\n  EnrollmentFactor,\n} from '@auth0/auth0-react';\n\n// MFA error types (value imports, not type-only)\nimport {\n  MfaRequiredError,\n  MfaEnrollmentError,\n  MfaChallengeError,\n  MfaVerifyError,\n} from '@auth0/auth0-react';\n```\n\n### Type User Profile\n\n```typescript\ninterface CustomUser extends User {\n  app_metadata?: {\n    roles?: string[];\n  };\n  user_metadata?: {\n    preferences?: any;\n  };\n}\n\nconst { user } = useAuth0<CustomUser>();\nconsole.log(user?.app_metadata?.roles);\n```\n\n---\n\n## Related Skills\n\n- `auth0-quickstart` - Initial Auth0 account setup\n- `auth0-migration` - Migrate from another auth provider\n- `auth0-mfa` - Add Multi-Factor Authentication\n- `auth0-organizations` - B2B multi-tenancy support\n- `auth0-passkeys` - Add passkey authentication\n\n---\n\n## References\n\n- [Auth0 React SDK Documentation](https://auth0.com/docs/libraries/auth0-react)\n- [Auth0 React SDK GitHub](https://github.com/auth0/auth0-react)\n- [Auth0 React Quickstart](https://auth0.com/docs/quickstart/spa/react)\n- [useAuth0 Hook API](https://auth0.github.io/auth0-react/interfaces/Auth0ContextInterface.html)\n- [Auth0 React API Reference](https://auth0.github.io/auth0-react/)\n- [Auth0 Universal Login](https://auth0.com/docs/universal-login)\n- [PKCE Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-proof-key-for-code-exchange-pkce)\n\nFile v1.0.0:references/integration.md\n\n# Auth0 React Integration Patterns\n\nPractical implementation patterns and examples for common use cases.\n\n---\n\n## Protected Routes\n\n### Basic Protected Route Component\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\nimport { Navigate } from 'react-router-dom';\n\nexport function ProtectedRoute({ children }: { children: React.ReactNode }) {\n  const { isAuthenticated, isLoading, loginWithRedirect } = useAuth0();\n\n  if (isLoading) {\n    return <div>Loading...</div>;\n  }\n\n  if (!isAuthenticated) {\n    loginWithRedirect();\n    return null;\n  }\n\n  return <>{children}</>;\n}\n```\n\n### Usage with React Router\n\n```tsx\nimport { BrowserRouter, Routes, Route } from 'react-router-dom';\nimport { ProtectedRoute } from './components/ProtectedRoute';\n\nfunction App() {\n  return (\n    <BrowserRouter>\n      <Routes>\n        <Route path=\"/\" element={<Home />} />\n        <Route\n          path=\"/profile\"\n          element={\n            <ProtectedRoute>\n              <Profile />\n            </ProtectedRoute>\n          }\n        />\n      </Routes>\n    </BrowserRouter>\n  );\n}\n```\n\n---\n\n## User Profile\n\n### Display User Information\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\n\nexport function Profile() {\n  const { user, isAuthenticated } = useAuth0();\n\n  if (!isAuthenticated) {\n    return <div>Please log in</div>;\n  }\n\n  return (\n    <div>\n      <img src={user?.picture} alt={user?.name} />\n      <h2>{user?.name}</h2>\n      <p>{user?.email}</p>\n    </div>\n  );\n}\n```\n\n---\n\n## Calling APIs\n\n### Call Protected API with Access Token\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\nimport { useState } from 'react';\n\nexport function ApiTest() {\n  const { getAccessTokenSilently } = useAuth0();\n  const [data, setData] = useState(null);\n  const [error, setError] = useState(null);\n\n  const callApi = async () => {\n    try {\n      const token = await getAccessTokenSilently({\n        authorizationParams: {\n          audience: 'https://your-api-identifier', // Your API identifier\n        }\n      });\n\n      const response = await fetch('https://your-api.com/data', {\n        headers: {\n          Authorization: `Bearer ${token}`\n        }\n      });\n\n      const json = await response.json();\n      setData(json);\n    } catch (err) {\n      setError(err.message);\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={callApi}>Call API</button>\n      {error && <div>Error: {error}</div>}\n      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}\n    </div>\n  );\n}\n```\n\n### Configure Provider for API Calls\n\nWhen calling APIs, add `audience` to your Auth0Provider:\n\n```tsx\n<Auth0Provider\n  domain={import.meta.env.VITE_AUTH0_DOMAIN}\n  clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}\n  authorizationParams={{\n    redirect_uri: window.location.origin,\n    audience: 'https://your-api-identifier' // Add this\n  }}\n>\n  <App />\n</Auth0Provider>\n```\n\n---\n\n## Error Handling\n\n### Handle Loading and Error States\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\n\nexport function App() {\n  const { isLoading, error, isAuthenticated, user } = useAuth0();\n\n  if (isLoading) {\n    return <div>Loading authentication...</div>;\n  }\n\n  if (error) {\n    return <div>Authentication error: {error.message}</div>;\n  }\n\n  return isAuthenticated ? (\n    <div>\n      <h1>Welcome back, {user?.name}!</h1>\n      <AuthenticatedApp />\n    </div>\n  ) : (\n    <div>\n      <h1>Please log in</h1>\n      <LoginButton />\n    </div>\n  );\n}\n```\n\n---\n\n## Silent Authentication\n\n### Auto-login on Page Load\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\nimport { useEffect } from 'react';\n\nexport function App() {\n  const { isAuthenticated, isLoading, getAccessTokenSilently } = useAuth0();\n\n  useEffect(() => {\n    if (!isLoading && !isAuthenticated) {\n      // Attempt silent authentication\n      getAccessTokenSilently().catch(() => {\n        // User not logged in, do nothing\n      });\n    }\n  }, [isLoading, isAuthenticated, getAccessTokenSilently]);\n\n  // Rest of your app...\n}\n```\n\n---\n\n## Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| \"Invalid state\" error | Clear browser storage and try again. Ensure `redirect_uri` matches configured callback URL |\n| User stuck on loading | Check Auth0 application settings have correct callback URLs configured |\n| API calls fail with 401 | Ensure `audience` is configured in Auth0Provider and matches your API identifier |\n| Logout doesn't work | Include `returnTo` URL in logout options and configure in Auth0 \"Allowed Logout URLs\" |\n| CORS errors when calling API | Add your application URL to \"Allowed Web Origins\" in Auth0 application settings |\n| Tokens not refreshing | Enable `useRefreshTokens={true}` in Auth0Provider and ensure refresh token rotation is enabled in Auth0 |\n\n---\n\n## MFA Handling\n\nThe `@auth0/auth0-react` SDK provides a built-in MFA API for handling Multi-Factor Authentication entirely within your app — no redirects to Universal Login required. Access it via the `mfa` property from `useAuth0()`.\n\n> **Note:** MFA support via SDKs is currently in Early Access. For a simpler approach that uses Universal Login to handle MFA automatically (no custom UI), see the [Step-Up via Popup](#step-up-via-popup-simpler-approach) section below.\n\n### Catching MfaRequiredError\n\nWhen `getAccessTokenSilently()` encounters an MFA requirement, it throws `MfaRequiredError`. Catch it and inspect `mfa_requirements` to determine the flow:\n\n```tsx\nimport { useAuth0, MfaRequiredError } from '@auth0/auth0-react';\nimport { useState } from 'react';\n\nexport function ProtectedApiCall() {\n  const { getAccessTokenSilently, mfa } = useAuth0();\n  const [mfaToken, setMfaToken] = useState<string | null>(null);\n  const [error, setError] = useState<string | null>(null);\n\n  const callApi = async () => {\n    try {\n      const token = await getAccessTokenSilently();\n      // Use token to call API...\n    } catch (err) {\n      if (err instanceof MfaRequiredError) {\n        setMfaToken(err.mfa_token);\n\n        // Check if enrollment or challenge is needed\n        const factors = await mfa.getEnrollmentFactors(err.mfa_token);\n        if (factors.length > 0) {\n          // User needs to enroll — show enrollment UI\n        } else {\n          // User has authenticators — show challenge UI\n          const authenticators = await mfa.getAuthenticators(err.mfa_token);\n          // Let user pick authenticator and proceed with challenge\n        }\n      } else {\n        setError(err.message);\n      }\n    }\n  };\n\n  return <button onClick={callApi}>Call Protected API</button>;\n}\n```\n\n### OTP Enrollment\n\nWhen the user needs to set up MFA for the first time:\n\n```tsx\nimport { useAuth0, MfaEnrollmentError } from '@auth0/auth0-react';\nimport { useState } from 'react';\n\nexport function OtpEnrollment({ mfaToken }: { mfaToken: string }) {\n  const { mfa } = useAuth0();\n  const [barcodeUri, setBarcodeUri] = useState<string | null>(null);\n  const [recoveryCodes, setRecoveryCodes] = useState<string[] | null>(null);\n  const [error, setError] = useState<string | null>(null);\n\n  const startEnrollment = async () => {\n    try {\n      const enrollment = await mfa.enroll({ mfaToken, factorType: 'otp' });\n      setBarcodeUri(enrollment.barcodeUri);\n      setRecoveryCodes(enrollment.recoveryCodes);\n    } catch (err) {\n      if (err instanceof MfaEnrollmentError) {\n        setError(err.error_description);\n      }\n    }\n  };\n\n  return (\n    <div>\n      <button onClick={startEnrollment}>Set up authenticator app</button>\n      {barcodeUri && (\n        <div>\n          <p>Scan this QR code with your authenticator app:</p>\n          {/* Render barcodeUri as QR code using a library like qrcode.react */}\n          <code>{barcodeUri}</code>\n        </div>\n      )}\n      {recoveryCodes && (\n        <div>\n          <p>Save these recovery codes:</p>\n          <ul>\n            {recoveryCodes.map((code, i) => <li key={i}>{code}</li>)}\n          </ul>\n        </div>\n      )}\n    </div>\n  );\n}\n```\n\n### Challenge and Verify\n\nWhen the user already has enrolled authenticators:\n\n```tsx\nimport {\n  useAuth0,\n  MfaChallengeError,\n  MfaVerifyError,\n} from '@auth0/auth0-react';\nimport { useState } from 'react';\n\nexport function MfaChallenge({ mfaToken }: { mfaToken: string }) {\n  const { mfa } = useAuth0();\n  const [otp, setOtp] = useState('');\n  const [error, setError] = useState<string | null>(null);\n\n  const handleVerify = async () => {\n    try {\n      // For OTP authenticators, you can skip challenge() and go straight to verify()\n      const tokens = await mfa.verify({ mfaToken, otp });\n      // User is now authenticated — tokens are cached by the SDK\n      console.log('MFA complete, access token:', tokens.access_token);\n    } catch (err) {\n      if (err instanceof MfaVerifyError) {\n        setError('Invalid code. Please try again.');\n      } else if (err instanceof MfaChallengeError) {\n        setError('Challenge failed: ' + err.error_description);\n      }\n    }\n  };\n\n  return (\n    <div>\n      <h3>Enter your verification code</h3>\n      <input\n        type=\"text\"\n        value={otp}\n        onChange={(e) => setOtp(e.target.value)}\n        placeholder=\"6-digit code\"\n        maxLength={6}\n      />\n      <button onClick={handleVerify}>Verify</button>\n      {error && <p style={{ color: 'red' }}>{error}</p>}\n    </div>\n  );\n}\n```\n\n### SMS/Email Challenge (Out-of-Band)\n\nFor SMS, Email, Voice, or Push authenticators, you must call `challenge()` first to send the code:\n\n```tsx\n// Initiate challenge to send code via SMS/Email\nconst response = await mfa.challenge({\n  mfaToken,\n  challengeType: 'oob',\n  authenticatorId: authenticator.id,\n});\n\n// Verify with the OOB code and the binding code the user received\nconst tokens = await mfa.verify({\n  mfaToken,\n  oobCode: response.oobCode,\n  bindingCode: userEnteredCode,\n});\n```\n\n### Step-Up via Popup (Simpler Approach)\n\nIf you don't need a custom MFA UI, configure `interactiveErrorHandler` to let the SDK handle MFA automatically via a Universal Login popup:\n\n```tsx\n<Auth0Provider\n  domain={import.meta.env.VITE_AUTH0_DOMAIN}\n  clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}\n  authorizationParams={{\n    redirect_uri: window.location.origin,\n    audience: 'https://your-api-identifier',\n  }}\n  useRefreshTokens={true}\n  interactiveErrorHandler=\"popup\"\n>\n  <App />\n</Auth0Provider>\n```\n\nWith this setup, `getAccessTokenSilently()` automatically opens a popup when MFA is required. No error handling needed — the token is returned after the user completes MFA in the popup.\n\n---\n\n## Security Considerations\n\n### Client-Side Security\n\n- **Never expose client secret** - React is client-side, use only public client credentials\n- **Use PKCE** - Enabled by default with @auth0/auth0-react\n- **Validate tokens on backend** - Never trust client-side token validation\n- **Use HTTPS in production** - Auth0 requires HTTPS for production redirect URLs\n- **Implement proper CORS** - Configure allowed origins in Auth0 application settings\n\n### Token Storage\n\n```tsx\n// Default: memory storage for highest security (tokens cleared on page refresh)\n<Auth0Provider\n  cacheLocation=\"memory\"\n  {...other props}\n>\n\n// Or localstorage for better UX (tokens persist across refreshes)\n<Auth0Provider\n  cacheLocation=\"localstorage\"\n  {...other props}\n>\n```\n\n### Secure API Calls\n\nAlways validate tokens on your backend:\n\n**Installation:**\n```bash\nnpm install express-oauth2-jwt-bearer\n```\n\n**Backend validation example (Node.js):**\n```javascript\nconst { auth, requiredScopes } = require('express-oauth2-jwt-bearer');\n\nconst checkJwt = auth({\n  audience: process.env.AUTH0_AUDIENCE,\n  issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`,\n});\n\napp.get('/api/private', checkJwt, (req, res) => {\n  res.json({ message: 'Secured data' });\n});\n\n// With scope validation\napp.get('/api/users', checkJwt, requiredScopes('read:users'), (req, res) => {\n  res.json({ users: [] });\n});\n```\n\n---\n\n## Advanced Patterns\n\n### Custom Login with Redirect Options\n\n```tsx\nconst { loginWithRedirect } = useAuth0();\n\n// Login with specific connection\nawait loginWithRedirect({\n  authorizationParams: {\n    connection: 'google-oauth2'\n  }\n});\n\n// Login with prompt\nawait loginWithRedirect({\n  authorizationParams: {\n    prompt: 'login' // Force login even if user has session\n  }\n});\n\n// Login with custom state\nawait loginWithRedirect({\n  appState: { targetUrl: '/protected-page' }\n});\n```\n\n### Handle Redirect Callback\n\n```tsx\nimport { useAuth0 } from '@auth0/auth0-react';\nimport { useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\n\nexport function Callback() {\n  const { handleRedirectCallback } = useAuth0();\n  const navigate = useNavigate();\n\n  useEffect(() => {\n    (async () => {\n      const result = await handleRedirectCallback();\n      const targetUrl = result.appState?.targetUrl || '/';\n      navigate(targetUrl);\n    })();\n  }, [handleRedirectCallback, navigate]);\n\n  return <div>Processing login...</div>;\n}\n```\n\n### Custom Logout\n\n```tsx\nconst { logout } = useAuth0();\n\n// Logout with custom return URL\nlogout({\n  logoutParams: {\n    returnTo: `${window.location.origin}/goodbye`\n  }\n});\n\n// Logout without redirect (federated logout)\nlogout({\n  logoutParams: {\n    federated: true\n  }\n});\n```\n\n---\n\n## Testing\n\n### Manual Testing Checklist\n\n1. **Login Flow**\n   - Start dev server: `npm run dev` (Vite) or `npm start` (CRA)\n   - Click \"Login\" button\n   - Complete Auth0 Universal Login\n   - Verify redirect back to your app with user authenticated\n   - Check user profile displays correctly\n\n2. **Logout Flow**\n   - Click \"Logout\" button\n   - Verify user is logged out\n   - Verify redirect to correct page\n\n3. **Protected Routes**\n   - Navigate to protected route while logged out\n   - Verify redirect to Auth0 login\n   - After login, verify redirect back to protected route\n\n4. **API Calls**\n   - Call protected API endpoint\n   - Verify access token is included in request\n   - Verify API responds correctly\n\n---\n\n## Next Steps\n\n- [API Reference](api.md) - Complete SDK documentation, configuration options, hooks reference\n- [Setup Guide](setup.md) - Detailed setup instructions and scripts\n- [Main Skill](../SKILL.md) - Return to main skill guide\n\nFile v1.0.0:references/setup.md\n\n# Auth0 React Setup Guide\n\nComplete setup instructions with automated scripts and manual configuration options.\n\n---\n\n## Quick Setup (Automated)\n\n**Never read the contents of `.env` at any point during setup.** The file may contain sensitive secrets that should not be exposed in the LLM context. If you determine you need to read the file for any reason, ask the user for explicit permission before doing so — do not proceed until the user confirms.\n\n**Before running any part of this setup that writes to `.env`, you MUST ask the user for explicit confirmation.** Follow the steps below precisely.\n\n### Step 1: Check for existing .env and confirm with user\n\nBefore writing to `.env`, check whether the file already exists:\n\n```bash\ntest -f .env && echo \"EXISTS\" || echo \"NOT_FOUND\"\n```\n\nThen ask the user for explicit confirmation before proceeding — do not continue until the user confirms:\n\n- If `.env` does **not** exist, ask:\n  - Question: \"This setup will create a `.env` file containing Auth0 credentials (domain and client ID). Do you want to proceed?\"\n  - Options: \"Yes, create .env\" / \"No, I'll configure it manually\"\n\n- If `.env` **already exists**, ask:\n  - Question: \"A `.env` file already exists and may contain secrets unrelated to Auth0. This setup will append Auth0 credentials to it without modifying existing content. Do you want to proceed?\"\n  - Options: \"Yes, append to existing .env\" / \"No, I'll update it manually\"\n\n**Do not proceed with writing to `.env` unless the user selects the confirmation option.**\n\n### Step 2: Run automated setup (only after confirmation)\n\n#### Bash Script (macOS/Linux)\n\nRun this script to automatically set up everything:\n\n```bash\n#!/bin/bash\n\n# Detect OS and install Auth0 CLI if needed\nif ! command -v auth0 &> /dev/null; then\n  echo \"Installing Auth0 CLI...\"\n  if [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n    brew install auth0/auth0-cli/auth0\n  elif [[ \"$OSTYPE\" == \"linux-gnu\"* ]]; then\n    curl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh | sh -s -- -b /usr/local/bin\n  elif [[ \"$OSTYPE\" == \"msys\" || \"$OSTYPE\" == \"cygwin\" ]]; then\n    echo \"Please install Auth0 CLI: https://github.com/auth0/auth0-cli#installation\"\n    exit 1\n  fi\nfi\n\n# Check if logged in to Auth0\nif ! auth0 tenants list &> /dev/null; then\n  echo \"\"\n  echo \"======================================\"\n  echo \"Auth0 Login Required\"\n  echo \"======================================\"\n  echo \"\"\n  read -p \"Do you have an Auth0 account? (y/n): \" HAS_ACCOUNT\n\n  if [[ \"$HAS_ACCOUNT\" != \"y\" ]]; then\n    echo \"\"\n    echo \"Let's create your free Auth0 account!\"\n    echo \"\"\n    echo \"1. Visit: https://auth0.com/signup\"\n    echo \"2. Sign up with your email or GitHub\"\n    echo \"3. Choose a tenant domain (e.g., 'mycompany')\"\n    echo \"4. Complete the onboarding\"\n    echo \"\"\n    read -p \"Press Enter when you've created your account...\"\n  fi\n\n  echo \"\"\n  echo \"Logging in to Auth0...\"\n  echo \"A browser will open for authentication.\"\n  echo \"\"\n  auth0 login\n\n  if ! auth0 tenants list &> /dev/null; then\n    echo \"❌ Login failed. Please try again or visit https://auth0.com/docs\"\n    exit 1\n  fi\n\n  echo \"✅ Successfully logged in to Auth0!\"\nfi\n\n# Detect if Vite or CRA\nif grep -q '\"vite\"' package.json 2>/dev/null; then\n  PREFIX=\"VITE_AUTH0\"\nelif grep -q '\"react-scripts\"' package.json 2>/dev/null; then\n  PREFIX=\"REACT_APP_AUTH0\"\nelse\n  echo \"Detecting React project type...\"\n  PREFIX=\"VITE_AUTH0\"  # Default to Vite\nfi\n\n# List apps and prompt for selection\necho \"Your Auth0 applications:\"\nauth0 apps list\n\nread -p \"Enter your Auth0 app ID (or press Enter to create a new one): \" APP_ID\n\nif [ -z \"$APP_ID\" ]; then\n  echo \"Creating new Auth0 SPA application...\"\n  APP_NAME=\"${PWD##*/}-react-app\"\n  APP_ID=$(auth0 apps create \\\n    --name \"$APP_NAME\" \\\n    --type spa \\\n    --callbacks \"http://localhost:3000,http://localhost:5173\" \\\n    --logout-urls \"http://localhost:3000,http://localhost:5173\" \\\n    --origins \"http://localhost:3000,http://localhost:5173\" \\\n    --web-origins \"http://localhost:3000,http://localhost:5173\" \\\n    --metadata \"created_by=agent_skills\" \\\n    --json | grep -o '\"client_id\":\"[^\"]*' | cut -d'\"' -f4)\n  echo \"Created app with ID: $APP_ID\"\nfi\n\n# Get app details and create .env file\necho \"Fetching Auth0 credentials...\"\nAUTH0_DOMAIN=$(auth0 apps show \"$APP_ID\" --json | grep -o '\"domain\":\"[^\"]*' | cut -d'\"' -f4)\nAUTH0_CLIENT_ID=$(auth0 apps show \"$APP_ID\" --json | grep -o '\"client_id\":\"[^\"]*' | cut -d'\"' -f4)\n\n# Append Auth0 credentials to .env\ncat >> .env << EOF\n${PREFIX}_DOMAIN=$AUTH0_DOMAIN\n${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID\nEOF\n\necho \"✅ Auth0 configuration complete!\"\necho \"Appended to .env:\"\necho \"  ${PREFIX}_DOMAIN=$AUTH0_DOMAIN\"\necho \"  ${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID\"\n```\n\n#### PowerShell Script (Windows)\n\n```powershell\n# Install Auth0 CLI if not present\nif (!(Get-Command auth0 -ErrorAction SilentlyContinue)) {\n  Write-Host \"Installing Auth0 CLI...\"\n  scoop install auth0\n}\n\n# Check if logged in\ntry {\n  auth0 tenants list | Out-Null\n} catch {\n  Write-Host \"\"\n  Write-Host \"======================================\"\n  Write-Host \"Auth0 Login Required\"\n  Write-Host \"======================================\"\n  Write-Host \"\"\n\n  $hasAccount = Read-Host \"Do you have an Auth0 account? (y/n)\"\n\n  if ($hasAccount -ne \"y\") {\n    Write-Host \"\"\n    Write-Host \"Let's create your free Auth0 account!\"\n    Write-Host \"\"\n    Write-Host \"1. Visit: https://auth0.com/signup\"\n    Write-Host \"2. Sign up with your email or GitHub\"\n    Write-Host \"3. Choose a tenant domain (e.g., 'mycompany')\"\n    Write-Host \"4. Complete the onboarding\"\n    Write-Host \"\"\n    Read-Host \"Press Enter when you've created your account\"\n  }\n\n  Write-Host \"\"\n  Write-Host \"Logging in to Auth0...\"\n  Write-Host \"A browser will open for authentication.\"\n  Write-Host \"\"\n  auth0 login\n\n  try {\n    auth0 tenants list | Out-Null\n    Write-Host \"✅ Successfully logged in to Auth0!\"\n  } catch {\n    Write-Host \"❌ Login failed. Please try again or visit https://auth0.com/docs\"\n    exit 1\n  }\n}\n\n# Detect project type\n$prefix = if (Select-String -Path \"package.json\" -Pattern '\"vite\"' -Quiet) { \"VITE_AUTH0\" }\n          elseif (Select-String -Path \"package.json\" -Pattern '\"react-scripts\"' -Quiet) { \"REACT_APP_AUTH0\" }\n          else { \"VITE_AUTH0\" }\n\n# List and select app\nWrite-Host \"Your Auth0 applications:\"\nauth0 apps list\n\n$appId = Read-Host \"Enter your Auth0 app ID (or press Enter to create new)\"\n\nif ([string]::IsNullOrEmpty($appId)) {\n  $appName = Split-Path -Leaf (Get-Location)\n  Write-Host \"Creating new Auth0 SPA application...\"\n  $appJson = auth0 apps create --name \"$appName-react-app\" --type spa `\n    --callbacks \"http://localhost:3000,http://localhost:5173\" `\n    --logout-urls \"http://localhost:3000,http://localhost:5173\" `\n    --origins \"http://localhost:3000,http://localhost:5173\" `\n    --web-origins \"http://localhost:3000,http://localhost:5173\" `\n    --metadata \"created_by=agent_skills\" --json\n\n  $appId = ($appJson | ConvertFrom-Json).client_id\n  Write-Host \"Created app with ID: $appId\"\n}\n\n# Get credentials and create .env\nWrite-Host \"Fetching Auth0 credentials...\"\n$appDetails = auth0 apps show $appId --json | ConvertFrom-Json\n\n@\"\n${prefix}_DOMAIN=$($appDetails.domain)\n${prefix}_CLIENT_ID=$($appDetails.client_id)\n\"@ | Out-File -FilePath .env -Encoding UTF8 -Append\n\nWrite-Host \"✅ Auth0 configuration complete!\"\nWrite-Host \"Appended to .env:\"\nWrite-Host \"  ${prefix}_DOMAIN=$($appDetails.domain)\"\nWrite-Host \"  ${prefix}_CLIENT_ID=$($appDetails.client_id)\"\n```\n\n---\n\n## Manual Setup\n\nIf you prefer manual setup or the scripts don't work:\n\n### Step 1: Install SDK\n\n```bash\nnpm install @auth0/auth0-react\n```\n\n### Step 2: Install Auth0 CLI\n\n**macOS:**\n```bash\nbrew install auth0/auth0-cli/auth0\n```\n\n**Linux:**\n```bash\ncurl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh | sh\n```\n\n**Windows:**\n```powershell\nscoop install auth0\n# Or: choco install auth0-cli\n```\n\n### Step 3: Get Credentials\n\n```bash\n# Login to Auth0\nauth0 login\n\n# List your apps\nauth0 apps list\n\n# Get app details (replace <app-id>)\nauth0 apps show <app-id>\n```\n\n### Step 4: Create .env File\n\n**For Vite:**\n```bash\nVITE_AUTH0_DOMAIN=<your-tenant>.auth0.com\nVITE_AUTH0_CLIENT_ID=<your-client-id>\n```\n\n**For Create React App:**\n```bash\nREACT_APP_AUTH0_DOMAIN=<your-tenant>.auth0.com\nREACT_APP_AUTH0_CLIENT_ID=<your-client-id>\n```\n\n---\n\n## Creating an Auth0 Application via Dashboard\n\nIf you prefer using the Auth0 Dashboard instead of the CLI:\n\n1. Go to [Auth0 Dashboard](https://manage.auth0.com)\n2. Navigate to **Applications** → **Applications**\n3. Click **Create Application**\n4. Choose:\n   - Name: Your app name\n   - Type: **Single Page Web Applications**\n5. Configure:\n   - **Allowed Callback URLs**: `http://localhost:3000, http://localhost:5173`\n   - **Allowed Logout URLs**: `http://localhost:3000, http://localhost:5173`\n   - **Allowed Web Origins**: `http://localhost:3000, http://localhost:5173`\n   - **Allowed Origins (CORS)**: `http://localhost:3000, http://localhost:5173`\n6. Copy your **Domain** and **Client ID**\n7. Create `.env` file as shown in Step 4 above\n\n---\n\n## Troubleshooting Setup\n\n### CLI Installation Issues\n\n**macOS - Homebrew not found:**\n```bash\n# Install Homebrew first\n/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n```\n\n**Windows - Scoop not found:**\n```powershell\n# Install Scoop first\niwr -useb get.scoop.sh | iex\n```\n\n### Login Issues\n\n**Browser doesn't open:**\n```bash\n# Use device code flow\nauth0 login --no-browser\n```\n\n**\"Not logged in\" error:**\n```bash\n# Force new login\nauth0 login --force\n```\n\n### Environment Variable Issues\n\n**Variables not loading (Vite):**\n- Ensure variables start with `VITE_`\n- Restart dev server after creating `.env`\n- Check file is named exactly `.env` (not `.env.local`)\n\n**Variables not loading (CRA):**\n- Ensure variables start with `REACT_APP_`\n- Restart dev server after creating `.env`\n- CRA doesn't support `.env` hot reload\n\n---\n\n## Next Steps\n\nAfter setup is complete:\n1. Return to [main skill guide](../SKILL.md) for integration steps\n2. See [Integration Guide](integration.md) for advanced patterns\n3. Check [API Reference](api.md) for complete SDK documentation","readmeExcerpt":"Skill: Auth0 React Owner: auth0 Summary: Deprecated — use the auth0 skill instead (run npx clawhub install auth0). 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 Tags: latest:1.1.0 Version history: v1.1.0 | 2026-07-20T14:50:48.794Z | user - ⚠️ D","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"npx clawhub install auth0"},{"language":"bash","snippet":"npm install @auth0/auth0-react"},{"language":"bash","snippet":"VITE_AUTH0_DOMAIN=your-tenant.auth0.com\nVITE_AUTH0_CLIENT_ID=your-client-id"},{"language":"bash","snippet":"REACT_APP_AUTH0_DOMAIN=your-tenant.auth0.com\nREACT_APP_AUTH0_CLIENT_ID=your-client-id"},{"language":"tsx","snippet":"import React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport { Auth0Provider } from '@auth0/auth0-react';\nimport App from './App';\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n  <React.StrictMode>\n    <Auth0Provider\n      domain={import.meta.env.VITE_AUTH0_DOMAIN} // or process.env.REACT_APP_AUTH0_DOMAIN\n      clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}\n      authorizationParams={{\n        redirect_uri: window.location.origin\n      }}\n    >\n      <App />\n    </Auth0Provider>\n  </React.StrictMode>\n);"},{"language":"tsx","snippet":"import { useAuth0 } from '@auth0/auth0-react';\n\nexport function LoginButton() {\n  const { loginWithRedirect, logout, isAuthenticated, user, isLoading } = useAuth0();\n\n  if (isLoading) return <div>Loading...</div>;\n\n  if (isAuthenticated) {\n    return (\n      <div>\n        <span>Welcome, {user?.name}</span>\n        <button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>\n          Logout\n        </button>\n      </div>\n    );\n  }\n\n  return <button onClick={() => loginWithRedirect()}>Login</button>;\n}"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: auth0-react\ndescription: >-\n  Deprecated — use the `auth0` skill instead (run `npx clawhub install auth0`).\n  Use when adding Auth0 login, logout, protected routes, or user sessions to a\n  React SPA. Integrates @auth0/auth0-react — use even if the user says \"add\n  login to my React app\" or \"protect my React routes\" without naming the SDK.\nlicense: Apache-2.0\nmetadata:\n  author: Auth0 <support@auth0.com>\n  version: 1.1.0\n  openclaw:\n    emoji: 🔐\n    homepage: https://github.com/auth0/agent-skills\n    requires:\n      bins:\n      - auth0\n    os:\n    - darwin\n    - linux\n    install:\n    - id: brew\n      kind: brew\n      formula: auth0/auth0-cli/auth0\n      bins:\n      - auth0\n      label: Install Auth0 CLI (brew)\n---\n\n# ⚠️ Deprecated — install the replacement skill\n\n**Do not use this skill.** It has been consolidated into the single `auth0`\nskill, which auto-detects your framework and routes to the same guidance for all\nAuth0 authentication work (login, logout, route protection, token validation,\nMFA, and more).\n\nClawHub does **not** install the replacement automatically. When you download\nthis outdated skill, install the consolidated one by running:\n\n```bash\nnpx clawhub install auth0\n```\n\nThen use the `auth0` skill instead — this one will not be maintained."},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7cjgtjqyx9kzrhcrr56tyzd183x56s\",\n  \"slug\": \"auth0-react\",\n  \"version\": \"1.1.0\",\n  \"publishedAt\": 1784559048794\n}"},{"path":"skill-card.md","content":"## Description:\n\nDeprecated skill that directs users to install the consolidated `auth0` skill for Auth0 React SPA login, logout, protected routes, and user sessions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[auth0](https://clawhub.ai/user/auth0)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers maintaining React SPAs use this deprecated skill as a redirect notice and should install the consolidated `auth0` skill for Auth0 authentication work, including login, logout, protected routes, and user sessions.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: This deprecated skill redirects users to install a replacement skill through an unpinned ClawHub install command.\n\nMitigation: Review the replacement auth0 skill, prefer a pinned or otherwise trusted ClawHub installer invocation when available, and run installation from a least-privilege shell without production secrets.\n\nRisk: Users may expect maintained Auth0 React implementation guidance from a retired skill.\n\nMitigation: Use this skill only as a deprecation notice and install the consolidated auth0 skill for current Auth0 authentication guidance.\n\n## Reference(s):\n\n- [Auth0 React skill page](https://clawhub.ai/auth0/skills/auth0-react)\n- [Auth0 agent skills repository](https://github.com/auth0/agent-skills)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands]\n\n**Output Format:** [Markdown with inline shell command]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Redirects users to install the consolidated auth0 skill; no maintained Auth0 React implementation guidance is provided.]\n\n## Skill Version(s):\n\n1.1.0 (source: server release metadata and skill frontmatter)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Deprecated — use the `auth0` skill instead (run `npx clawhub install auth0`). 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 Skill: Auth0 React Owner: auth0 Summary: Deprecated — use the auth0 skill instead (run npx clawhub install auth0). 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 Tags: latest:1.1.0 Version history: v1.1.0 | 2026-07-20T14:50:48.794Z | user - ⚠️ D","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":961,"uniquenessScore":48,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T02:41:26.850Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T02:41:26.850Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T04:33:01.529Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}