Remix Quickstart
You will learn the following:
- Install
@clerk/remix
- Set your Clerk API keys
- Configure
rootAuthLoader
- Configure
ClerkApp
- Protect your pages
Before you start
Example repository
Learn how to use Clerk to quickly and easily add secure authentication and user management to your Remix app. This guide assumes that you are using Remix v2 or later.
Install @clerk/remix
Clerk's Remix SDK gives you access to prebuilt components, hooks, and helpers to make user authentication easier.
Run the following command to install the SDK:
npm install @clerk/remix
yarn add @clerk/remix
pnpm add @clerk/remix
Add the following keys to your .env.local
file. These keys can always be retrieved from the API keys page in the Clerk Dashboard.
- In the Clerk Dashboard, navigate to the API keys page.
- In the Quick Copy section, copy your Clerk Publishable and Secret Keys.
- Paste your keys into your
.env.local
file.
The final result should resemble the following:
CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY
CLERK_SECRET_KEY=YOUR_SECRET_KEY
Configure rootAuthLoader
To configure Clerk in your Remix app, 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:
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
.
// Your imports
export const loader: LoaderFunction = (args) => {
return rootAuthLoader(args, ({ request }) => {
const { sessionId, userId, getToken } = request.auth
// Add logic to fetch data
return { yourData: 'here' }
})
}
// Your additional app 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:
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, Clerk's prebuilt control components control the visibility of content based on the user's authentication state.
The following example uses the following components:
<SignedIn>
: Children of this component can only be seen while signed in.<SignedOut>
: Children of this component can only be seen while signed out.<UserButton />
: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options.<SignInButton />
: An unstyled component that links to the sign-in page. In this example, since no props or environment variables are set for the sign-in URL, this component links to the Account Portal sign-in page
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 />
</SignedIn>
<SignedOut>
<p>You are signed out</p>
<SignInButton />
</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.
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:
npm run dev
yarn dev
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 app.
Customization & localization
Learn how to customize and localize the Clerk components.
Clerk components
Learn more about the prebuilt components.
Feedback
Last updated on