Auth0 Authentication SDK for React Router v7 applications.
Beta release. APIs may change before GA.
The SDK is built on Auth0's foundational
@auth0/auth0-server-js package. It consumes the
foundation rather than re-implementing OIDC, session, and token logic, so behavior stays consistent
with the rest of the Auth0 ecosystem.
- Installation
- Package structure
- Features
- Quick start
- Protecting routes
- Known limitations
- Security considerations
- Feedback
npm install @auth0/auth0-react-routerThis SDK relies on the following peer dependencies, which you install in your own app:
| Package | Version |
|---|---|
react |
>=18.0.0 |
react-dom |
>=18.0.0 |
react-router |
>=7.0.0 |
@auth0/auth0-spa-js |
>=2.0.0 (SPA mode only) |
The SDK is one package with six entry points. Each entry point is tree-shakeable and the bundle
boundary is enforced by the exports map, so server code never enters the client bundle and client
code never enters the server bundle.
| Import path | Contents |
|---|---|
@auth0/auth0-react-router (root, resolves to /client) |
Provider, hooks, UI components, route guards |
@auth0/auth0-react-router/server |
Auth0Server class, handlers, session and token helpers, middleware |
@auth0/auth0-react-router/routes |
Pre-built route config objects for the full OIDC flow |
@auth0/auth0-react-router/errors |
Typed error classes |
@auth0/auth0-react-router/types |
TypeScript types |
@auth0/auth0-react-router/testing |
Test utilities, mock factories, test provider |
The root import resolves to /client, the browser-safe surface, so the convenient path is also the
safe one. Server-only APIs require the explicit /server import.
Auth route handlers take the Auth0Server instance as their first argument —
handleLogin(auth0, request), handleCallback(auth0, request). Session and token helpers that only
need to read the encrypted cookie — getSession(request), getAccessToken(request) — work from
the request alone. This keeps each helper easy to use directly in a loader or action without
threading the instance through every call site.
Authentication
- Login, callback, and logout handled server-side with an encrypted JWE session cookie.
- Back-channel logout so Auth0 can end a user's session from the Dashboard or another app.
- Pre-built route helpers (
auth0Routes,handleAuth) to register the full OIDC flow in one line, or individual handlers (handleLogin,handleCallback,handleLogout) for custom paths.
Route protection
requireSessionandrequireUserthrow a302redirect from any loader when the user is not authenticated.defineRouteAuthmiddleware enforces role-based access at the route level and stores the authenticated user in React Router context for downstream loaders.requireClaimsandbearerTokenMiddlewareprotect API routes that expect a Bearer token.
React hooks and components
- Hooks:
useAuth0,useUser,useSession. - Conditional rendering:
SignedIn,SignedOut,AuthLoading. - Guards:
RequireAuth,RequireRole. - Pre-built buttons:
LoginButton,LogoutButton.
Server-side tokens
getSession,getAccessToken,updateSession,deleteSession, andcreateApiClientare available in loaders and actions. Tokens stay on the server and are never sent to the browser.
SPA mode
- Optional client-side flow backed by
@auth0/auth0-spa-js, auto-detected fromVITE_AUTH0_DOMAINandVITE_AUTH0_CLIENT_ID. No changes needed toAuth0Provider.
Testing utilities
- Mock factories (
createMockUser,createMockSession,createMockTokenSet), a drop-inWithAuthtest provider, and loader helpers (createMockLoader,createMockBearerRequest) so you can test authenticated flows without a real Auth0 tenant.
The minimal setup is three pieces.
1. Create one Auth0Server instance per app (not per request):
// app/auth0.server.ts
import { Auth0Server } from '@auth0/auth0-react-router/server';
export const auth0 = new Auth0Server();The instance reads configuration from environment variables. You can also pass values directly to the constructor.
| Variable | Description |
|---|---|
AUTH0_DOMAIN |
Your Auth0 tenant domain, e.g. example.us.auth0.com |
AUTH0_CLIENT_ID |
Application client ID |
AUTH0_CLIENT_SECRET |
Application client secret |
AUTH0_SESSION_SECRET |
Random string (min 32 chars) used to encrypt the session cookie |
AUTH0_APP_BASE_URL |
Full URL of your app, e.g. https://example.com |
AUTH0_AUDIENCE |
API audience, if requesting access tokens for an API (optional) |
AUTH0_SCOPE |
OAuth scopes, defaults to openid profile email (optional) |
2. Register the auth routes:
// app/routes.ts
import { auth0Routes } from '@auth0/auth0-react-router/routes';
import { auth0 } from './auth0.server';
export default [
{
id: 'root',
path: '/',
// ...
children: [
...auth0Routes(auth0) // registers /auth/login, /auth/callback, /auth/logout
]
}
];auth0Routes is the quickest option. If you need custom paths or logic, use the individual
handlers (handleLogin, handleCallback, handleLogout) directly in your own route files, or use
handleAuth on a splat route to dispatch all three from one file.
3. Add the provider to the root layout:
// app/root.tsx
import { Outlet } from 'react-router';
import { Auth0Provider } from '@auth0/auth0-react-router';
import { rootAuthLoader } from '@auth0/auth0-react-router/server';
export const loader = ({ request }) => rootAuthLoader(request);
export default function Root() {
return (
<html lang="en">
<body>
<Auth0Provider>
<Outlet />
</Auth0Provider>
</body>
</html>
);
}Auth0Provider reads the session via useRouteLoaderData('root'), which matches the route's
id — the id: 'root' set on the route object in step 2. Make sure your root route has that id,
otherwise the provider won't find the session.
That is enough for working login, callback, and logout.
Server-side — call requireSession from a loader. It returns the session or throws a 302
redirect to /auth/login with a returnTo parameter so the user lands back where they started:
import { requireSession } from '@auth0/auth0-react-router/server';
export const loader = async ({ request }) => {
const session = await requireSession(request);
return { user: session.user };
};Client-side — wrap UI in RequireAuth or use the conditional rendering components:
import {
RequireAuth,
SignedIn,
SignedOut,
LoginButton,
LogoutButton
} from '@auth0/auth0-react-router';
// redirect to login if not authenticated
function Dashboard() {
return (
<RequireAuth>
<DashboardContent />
</RequireAuth>
);
}
// show/hide based on auth state
function Header() {
return (
<nav>
<SignedIn>
<LogoutButton />
</SignedIn>
<SignedOut>
<LoginButton />
</SignedOut>
</nav>
);
}Role-based access — use defineRouteAuth to enforce a role at the route level:
import {
defineRouteAuth,
auth0UserContext
} from '@auth0/auth0-react-router/server';
const adminAuth = defineRouteAuth({ role: 'admin' });
export const handle = adminAuth.handle;
export const middleware = adminAuth.middleware;
export const loader = ({ context }) => {
const user = context.get(auth0UserContext);
return { user };
};Requests without the required role receive a 403. Roles are read from the
https://auth0.com/claims/roles claim by default; pass rolesClaim to override.
- React Router middleware —
auth0Middleware,bearerTokenMiddleware, anddefineRouteAuthrequire React Router ≥ 7.9.0, which introduced the middleware API. On earlier 7.x releases use the per-loader helpers (getSession,requireSession, etc.) instead. - DPoP (sender-constrained tokens) is not supported. It is planned once the underlying
@auth0/auth0-server-jsfoundation gains native support.
The SDK never writes PII or token values to any log output. Be careful not to introduce logging in your own loaders or actions:
// ❌ avoid
export const loader = async ({ request }) => {
const session = await getSession(request);
console.log(session.user.email, session.tokenSets); // logs PII and credentials
};
// ✅ safe
export const loader = async ({ request }) => {
const session = await getSession(request);
return { user: session.user };
};AUTH0_CLIENT_SECRET and AUTH0_SESSION_SECRET should never appear in logs. Treat
them like passwords — load them from environment variables and keep them out of any
debug or error output.
We appreciate feedback and contribution to this repo! Before you get started, please read the following:
- Auth0's general contribution guidelines
- Auth0's code of conduct guidelines
- This repo's contribution guide
To provide feedback or report a bug, please raise an issue on our issue tracker.
Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.

Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout Why Auth0?
This project is licensed under the Apache License 2.0. See the LICENSE file for more info.