Docs

React Router Quickstart (Beta)

You will learn the following:

  • Install @clerk/react-router
  • Set your Clerk API keys
  • Configure rootAuthLoader()
  • Add <ClerkProvider> and Clerk components

Clerk's React Router SDK provides prebuilt components, hooks, and stores to make it easy to integrate authentication and user management in your React Router app. This guide assumes that you're using React Router v7 or later.

Install @clerk/react-router

Run the following command to install the SDK:

terminal
npm install @clerk/react-router
terminal
yarn add @clerk/react-router
terminal
pnpm add @clerk/react-router
.env
VITE_CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY
CLERK_SECRET_KEY=YOUR_SECRET_KEY

Configure rootAuthLoader()

The rootAuthLoader() function provides access to authentication state in any React Router route.

The following code shows how to add this function to your root.tsx file. If you're using Clerk's React Router quickstart or the React Router template, most of this code will already be present.

To load additional data or configure options, see the rootAuthLoader() reference.

app/root.tsx
import { rootAuthLoader } from '@clerk/react-router/ssr.server'
import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router'
import type { Route } from './+types/root'
import stylesheet from './app.css?url'

export async function loader(args: Route.LoaderArgs) {
  return rootAuthLoader(args)
}

export const links: Route.LinksFunction = () => [
  { rel: 'preconnect', href: 'https://fonts.googleapis.com' },
  {
    rel: 'preconnect',
    href: 'https://fonts.gstatic.com',
    crossOrigin: 'anonymous',
  },
  {
    rel: 'stylesheet',
    href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap',
  },
  { rel: 'stylesheet', href: stylesheet },
]

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        {children}
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  )
}

export default function App() {
  return <Outlet />
}

export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
  let message = 'Oops!'
  let details = 'An unexpected error occurred.'
  let stack: string | undefined

  if (isRouteErrorResponse(error)) {
    message = error.status === 404 ? '404' : 'Error'
    details =
      error.status === 404 ? 'The requested page could not be found.' : error.statusText || details
  } else if (import.meta.env.DEV && error && error instanceof Error) {
    details = error.message
    stack = error.stack
  }

  return (
    <main className="pt-16 p-4 container mx-auto">
      <h1>{message}</h1>
      <p>{details}</p>
      {stack && (
        <pre className="w-full p-4 overflow-x-auto">
          <code>{stack}</code>
        </pre>
      )}
    </main>
  )
}

The <ClerkProvider> component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with <ClerkProvider> to make authentication globally accessible. See the reference docs for other configuration options.

It's required to pass loaderData to the <ClerkProvider> component. This data is provided by the rootAuthLoader() function. It's also recommended to pass the signUpFallbackRedirectUrl and signInFallbackRedirectUrl props. These specify the fallback URL to redirect to after the user signs up or signs in, respectively, if there's no redirect_url in the path already.

You can control which content signed-in and signed-out users can see with Clerk's prebuilt control components.

The following example adds <ClerkProvider> and creates a header using the following Clerk components:

app/root.tsx
// Other imports

import { ClerkProvider, SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/react-router'

export default function App({ loaderData }: Route.ComponentProps) {
  return (
    <ClerkProvider
      loaderData={loaderData}
      signUpFallbackRedirectUrl="/"
      signInFallbackRedirectUrl="/"
    >
      <header className="flex items-center justify-center py-8 px-4">
        <SignedOut>
          <SignInButton />
        </SignedOut>
        <SignedIn>
          <UserButton />
        </SignedIn>
      </header>
      <main>
        <Outlet />
      </main>
    </ClerkProvider>
  )
}

// Rest of the root.tsx code

Create your first user

Run your project with the following command:

terminal
npm run dev
terminal
yarn dev
terminal
pnpm dev

Visit your app's homepage at http://localhost:5173. Sign up to create your first user.

Feedback

What did you think of this content?

Last updated on