Skip to main content
Docs

Remix SPA Mode

Note

This guide explains how to use Clerk with Remix in SPA mode. If you are using Remix with SSR, follow the Remix quickstart.

Install @clerk/remix

The Clerk Remix SDK gives you access to prebuilt components, hooks, and helpers to make user authentication easier.

Run the following command to install the SDK:

terminal
npm install @clerk/remix
terminal
yarn add @clerk/remix
terminal
pnpm add @clerk/remix
terminal
bun add @clerk/remix

Warning

You will not need the Clerk Secret Key in Remix SPA mode, as it should never be used on the client-side.

.env
VITE_CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY

Configure ClerkApp

Clerk provides a ClerkApp wrapper to provide the authentication state to your React tree. You must pass your Publishable Key to ClerkApp.

app/root.tsx
import { ClerkApp } from '@clerk/remix'
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react'

function App() {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  )
}

// Import your Publishable Key
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY

// Wrap your app with `ClerkApp`
export default ClerkApp(App, {
  publishableKey: PUBLISHABLE_KEY,
})

Update your paths through ClerkApp options

Next, add paths to your ClerkApp options to control the behavior of the components when you sign in or sign up.

app/root.tsx
export default ClerkApp(App, {
  publishableKey: PUBLISHABLE_KEY,
  signInFallbackRedirectUrl: '/',
  signUpFallbackRedirectUrl: '/',
})

Protect your pages

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:

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 />
      </SignedIn>
      <SignedOut>
        <p>You are signed out</p>

        <SignInButton />
      </SignedOut>
    </div>
  )
}

Customization & localization

Learn how to customize and localize the Clerk components.

Clerk components

Learn more about the prebuilt components.

Client-side helpers

Learn more about our client-side helpers and how to use them.

Feedback

What did you think of this content?

Last updated on