Docs

Remix Quickstart

You will learn the following:

  • Install @clerk/remix
  • Set your Clerk API keys
  • Configure rootAuthLoader
  • Configure ClerkApp
  • Protect your pages

Learn how to use Clerk to quickly and easily add secure authentication and user management to your Remix application. This guide assumes that you are using Remix v2 or later.

Note

If you are using Remix SPA mode, follow the Remix SPA mode guide.

Install @clerk/remix

Once you have a Remix application ready, you need to install Clerk's Remix SDK. This gives you access to our prebuilt components and hooks for Remix applications.

terminal
npm install @clerk/remix
terminal
yarn add @clerk/remix
terminal
pnpm add @clerk/remix
.env.local
CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY
CLERK_SECRET_KEY=YOUR_SECRET_KEY

Configure rootAuthLoader

To configure Clerk in your Remix application, you will need to update your root loader. This will enable you to have access to authentication state in any Remix routes.

Update your root.tsx file with the following code:

app/root.tsx
import type { MetaFunction, LoaderFunction } from '@remix-run/node'
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react'

// Import rootAuthLoader
import { rootAuthLoader } from '@clerk/remix/ssr.server'

export const meta: MetaFunction = () => [
  {
    charset: 'utf-8',
    title: 'New Remix App',
    viewport: 'width=device-width,initial-scale=1',
  },
]

// Export as the root route loader
export const loader: LoaderFunction = (args) => rootAuthLoader(args)

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        {children}
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  )
}

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

If you need to load in additional data, you can pass your loader directly to the rootAuthLoader.

app/root.tsx
// Imports

export const loader: LoaderFunction = (args) => {
  return rootAuthLoader(args, ({ request }) => {
    const { sessionId, userId, getToken } = request.auth
    // Add logic to fetch data
    return { yourData: 'here' }
  })
}

// Additional application code

Configure ClerkApp

Clerk provides a ClerkApp wrapper to provide the authentication state to your React tree. This helper works with Remix SSR out-of-the-box and follows the "higher-order component" paradigm.

Update your root.tsx file with the following code:

app/root.tsx
import type { MetaFunction, LoaderFunction } from '@remix-run/node'

import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react'

import { rootAuthLoader } from '@clerk/remix/ssr.server'
// Import ClerkApp
import { ClerkApp } from '@clerk/remix'

export const meta: MetaFunction = () => [
  {
    charset: 'utf-8',
    title: 'New Remix App',
    viewport: 'width=device-width,initial-scale=1',
  },
]

export const loader: LoaderFunction = (args) => rootAuthLoader(args)

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        {children}
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  )
}

function App() {
  return <Outlet />
}

export default ClerkApp(App)

Protect your pages

Client-side

To protect your pages on the client-side, you can use Clerk's prebuilt control components that control the visibility of content based on the user's authentication state.

The following example uses the following components:

routes/_index.tsx
import {
  SignInButton,
  SignOutButton,
  SignUpButton,
  SignedIn,
  SignedOut,
  UserButton,
} from '@clerk/remix'

export default function Index() {
  return (
    <div>
      <h1>Index Route</h1>
      <SignedIn>
        <p>You are signed in!</p>
        <UserButton />

        <SignOutButton />
      </SignedIn>
      <SignedOut>
        <p>You are signed out</p>

        <SignInButton />

        <SignUpButton />
      </SignedOut>
    </div>
  )
}

Server-side

To protect your routes, use the getAuth() function in your loader. This function retrieves the authentication state from the request object, returning an Auth object that includes the userId, allowing you to determine if the user is authenticated.

routes/_index.tsx
import { UserButton } from '@clerk/remix'
import { getAuth } from '@clerk/remix/ssr.server'
import { LoaderFunction, redirect } from '@remix-run/node'

export const loader: LoaderFunction = async (args) => {
  const { userId } = await getAuth(args)
  if (!userId) {
    return redirect('/sign-in')
  }
  return {}
}

export default function Index() {
  return (
    <div>
      <h1>Index route</h1>
      <p>You are signed in!</p>
      <UserButton />
    </div>
  )
}

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.

Create custom sign-up and sign-in pages

Learn how add custom sign-up and sign-in pages with Clerk components.

Read user and session data

Learn how to use Clerk's hooks and helpers to access the active session and user data in your Remix application.

Customization & localization

Learn how to customize and localize the Clerk components.

Clerk components

Learn more about Clerk's prebuilt components.

Feedback

What did you think of this content?

Last updated on