Skip to main content
@auth0/auth0-react-router is currently in beta (1.0.0-beta.2). The API may change before the stable 1.0 release.

Use AI to integrate Auth0

If you use an AI coding assistant like Claude Code, Cursor, or GitHub Copilot, you can add Auth0 authentication automatically in minutes using agent skills.Install:
Then ask your AI assistant:
Your AI assistant will automatically create your Auth0 application, fetch credentials, install @auth0/auth0-react-router, configure the provider, and set up your routes. Full agent skills documentation →
Prerequisites: Before you begin, ensure you have the following installed:
  • Node.js 18 or newer (20 LTS recommended)
  • npm 9+, yarn 1.22+, or pnpm 8+
  • jq - Required for Auth0 CLI setup
  • React Router framework mode, v7 or later (react-router.config.ts present)

Get Started

This quickstart demonstrates how to add Auth0 authentication to a React Router application. You’ll build a secure app with login, logout, and user profile features using the Auth0 React Router SDK. The SDK handles the OIDC flow server-side and stores the session in a JWE-encrypted cookie — tokens never reach the browser.
1

Create a new React Router project

Create a new React Router project for this Quickstart:
Open the project:
Skip this step if you are adding Auth0 to an existing React Router app.
2

Install the Auth0 React Router SDK

3

Configure Auth0

Create an Auth0 application and set the callback and logout URLs.
4

Configure environment variables

Create a .env file at the root of your project:
Never commit .env to version control. Add it to .gitignore before your first commit.
5

Create the Auth0 server instance

Create app/auth0.server.ts. The .server.ts suffix tells React Router’s bundler to exclude this file from the client bundle, keeping your secrets server-only.
app/auth0.server.ts
6

Add the auth routes

Create a splat route that handles all /auth/* paths. handleAuth dispatches internally to handleLogin, handleCallback, handleLogout, and handleBackchannelLogout based on the URL path and HTTP method.
app/routes/auth.$.tsx
Register the route in your route config:
app/routes.ts
7

Configure the root layout

Add Auth0Provider and rootAuthLoader to app/root.tsx. rootAuthLoader decrypts the session cookie and passes the auth state to the provider — no tokens are sent to the browser.
app/root.tsx
Auth0Provider reads session data from useRouteLoaderData('root'), so the root route must have the id root. With file-based routing React Router sets this from the filename automatically. With a custom route config, pass { id: 'root' } to the layout() call.
8

Add login and logout

Use the built-in components to show login and logout controls. LoginButton redirects to /auth/login and LogoutButton redirects to /auth/logout. Auth0 handles the OIDC flow and redirects the user back to your app after sign-in.
app/routes/_index.tsx
9

Show the user profile

Use the useUser hook to access the authenticated user’s profile in any client component. Pair it with requireSession in the loader to block unauthenticated requests at the server before the page renders.
app/routes/profile.tsx
10

Run your application

Open http://localhost:5173 in your browser and click Log in. You will be redirected to the Auth0 Universal Login page. After signing in you will be redirected back to your app.
Your app now has working login and logout. The session is stored in a JWE-encrypted cookie — access tokens stay on the server and are never sent to the browser.

Troubleshooting

Cause: The redirect URL Auth0 receives does not match any value in Allowed Callback URLs.Fix: In Auth0 DashboardApplications > Applications → select your app → Application Settings, confirm Allowed Callback URLs is set to http://localhost:5173/auth/callback. Remove any trailing slashes or extra whitespace, then click Save Changes.
Cause: The auth.$.tsx splat route is missing or not registered in routes.ts.Fix: Confirm app/routes/auth.$.tsx exists and that app/routes.ts includes route('auth/*', 'routes/auth.$.tsx'). Restart the dev server after editing routes.ts.
Cause: rootAuthLoader is not exported from app/root.tsx, or the root route does not have the id root.Fix: Confirm app/root.tsx exports export const loader = ({ request }) => rootAuthLoader(request). With a custom route config, register the root layout as layout('root.tsx', { id: 'root' }, [...routes]).
Cause: defineRouteAuth and auth0Middleware require React Router 7.9.0 or later, which introduced the middleware API.Fix: Upgrade react-router to >=7.9.0, or protect routes individually using requireSession / requireUser in each loader instead.

Advanced Usage

Add AUTH0_AUDIENCE to .env with your API’s identifier (from Auth0 DashboardApplications > APIsAPI Settings → Identifier). Then use getAccessToken in a loader — the token never reaches the browser:
app/routes/data.tsx
Use defineRouteAuth middleware (React Router ≥ 7.9.0) to enforce roles at the route level. Roles are read from the https://auth0.com/claims/roles claim by default:
app/routes/admin.tsx
Requests without the required role receive a 403.
The SDK can run in a purely client-side mode backed by @auth0/auth0-spa-js. Add VITE_AUTH0_DOMAIN and VITE_AUTH0_CLIENT_ID to your .envAuth0Provider detects these automatically and switches to the PKCE flow. No other code changes are required.
Do not set both AUTH0_* and VITE_AUTH0_* variables at the same time. Hybrid mode is not supported — when both are present, SPA logout will not clear the server-side session cookie.