Skip to content

feat: Add React Router docs #1760

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 35 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
df3c8bf
initial
LekoArts Dec 2, 2024
1767f16
add quickstart
LekoArts Dec 3, 2024
4721ebb
Linting
LekoArts Dec 3, 2024
9909a11
fix code snippet
LekoArts Dec 3, 2024
95392a9
add beta tags
LekoArts Dec 3, 2024
932ff16
add sign-in sign-up page content
LekoArts Dec 3, 2024
ed817a0
Add React Router icon (#1763)
bradlc Dec 3, 2024
5a3c422
Merge branch 'main' into lekoarts/eco-248-addupdate-documentation
LekoArts Dec 4, 2024
9d5a136
improve guides
LekoArts Dec 4, 2024
bbb2247
linting
LekoArts Dec 4, 2024
472069a
more docs
LekoArts Dec 4, 2024
7e0bb63
fix steps
LekoArts Dec 4, 2024
8410453
library mode
LekoArts Dec 4, 2024
8d9c6dc
add RR to two other docs
LekoArts Dec 4, 2024
15f492b
linting
LekoArts Dec 4, 2024
0a4f1ca
update quickstart
LekoArts Dec 4, 2024
ea177b1
fix typos
LekoArts Dec 4, 2024
9ad0a51
update clerkprovider wording
LekoArts Dec 5, 2024
8be1cd5
delete add-react-router guide (obsolete)
LekoArts Dec 5, 2024
949ca2d
update env var
LekoArts Dec 9, 2024
e6d8ea8
Merge branch 'main' into lekoarts/eco-248-addupdate-documentation
LekoArts Dec 10, 2024
1253bbf
Merge branch 'main' into lekoarts/eco-248-addupdate-documentation
victoriaxyz Dec 10, 2024
d5d29a1
refactor
victoriaxyz Dec 11, 2024
13ccb64
Apply suggestions from code review
victoriaxyz Dec 11, 2024
1c1dac7
follow-up fixes
LekoArts Dec 11, 2024
a29c74b
last set of changes
LekoArts Dec 11, 2024
2b8bcd2
linting :D
LekoArts Dec 11, 2024
8b7a8a6
code review
alexisintech Dec 11, 2024
e7aa1d8
add the fallback redirect url props back
alexisintech Dec 11, 2024
9bbb1e5
improvements
LekoArts Dec 12, 2024
6303eae
typo
LekoArts Dec 12, 2024
8cd5fd6
add beta callouts to react router docs
alexisintech Dec 12, 2024
818671e
Update docs/references/react-router/root-auth-loader.mdx
alexisintech Dec 12, 2024
eb35bbf
update callouts
alexisintech Dec 12, 2024
fd668b0
update signInUrl signUpUrl prop descriptions
alexisintech Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ Find all the guides and resources you need to develop with Clerk.
- [TanStack Start (Beta)](/docs/quickstarts/tanstack-start)
- Easily add secure and SSR-friendly authentication to your TanStack Start application with Clerk.
- ![](data:image/webp;base64,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)

---

- [React Router (Beta)](/docs/quickstarts/react-router)
- Easily add secure, edge- and SSR-friendly authentication to React Router with Clerk.
- {<svg viewBox="0 0 32 32"><path fill="#F44250" d="M25.6 15.568a3.196 3.196 0 0 1-3.2 3.19 3.193 3.193 0 0 0-3.2 3.189 3.196 3.196 0 0 1-3.2 3.19 3.193 3.193 0 0 1-2.263-.935 3.172 3.172 0 0 1-.937-2.255 3.193 3.193 0 0 1 3.2-3.19 3.196 3.196 0 0 0 3.2-3.189 3.194 3.194 0 0 0-3.2-3.19 3.193 3.193 0 0 1-3.2-3.189A3.193 3.193 0 0 1 16 6c1.767.001 3.2 1.429 3.2 3.19a3.193 3.193 0 0 0 3.2 3.19c1.768 0 3.2 1.427 3.2 3.19Z"/><path style={{ fill: 'var(--light, #121212) var(--dark, #fff)' }} d="M12.8 15.568a3.195 3.195 0 0 0-3.2-3.19 3.195 3.195 0 0 0-3.2 3.19 3.195 3.195 0 0 0 3.2 3.19c1.767 0 3.2-1.428 3.2-3.19ZM6.4 21.947a3.195 3.195 0 0 0-3.2-3.19 3.195 3.195 0 0 0-3.2 3.19 3.195 3.195 0 0 0 3.2 3.19c1.767 0 3.2-1.429 3.2-3.19ZM32 21.947a3.195 3.195 0 0 0-3.2-3.19 3.195 3.195 0 0 0-3.2 3.19 3.195 3.195 0 0 0 3.2 3.19c1.767 0 3.2-1.429 3.2-3.19Z"/></svg>}
</Cards>

## Explore by backend framework
Expand Down
55 changes: 55 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
"href": "/docs/quickstarts/nextjs",
"icon": "nextjs"
},
{
"title": "React Router",
"tag": "(Beta)",
"href": "/docs/quickstarts/react-router",
"icon": "react-router"
},
{
"title": "Remix",
"href": "/docs/quickstarts/remix",
Expand Down Expand Up @@ -2382,6 +2388,55 @@
]
]
},
{
"title": "React Router",
"collapse": true,
"icon": "react-router",
"tag": "(Beta)",
"items": [
[
{
"title": "Overview",
"href": "/docs/references/react-router/overview"
},
{
"title": "Guides",
"items": [
[
{
"title": "Read session and user data",
"href": "/docs/references/react-router/read-session-data"
},
{
"title": "Add custom sign up and sign in pages",
"href": "/docs/references/react-router/custom-signup-signin-pages"
},
{
"title": "Library mode",
"href": "/docs/references/react-router/library-mode"
}
]
]
},
{
"title": "General References",
"items": [
[
{
"title": "`rootAuthLoader()`",
"wrap": false,
"href": "/docs/references/react-router/root-auth-loader"
},
{
"title": "`getAuth()`",
"href": "/docs/references/react-router/get-auth"
}
]
]
}
]
]
},
{
"title": "Remix",
"collapse": true,
Expand Down
1 change: 1 addition & 0 deletions docs/manifest.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
"react",
"redwood",
"remix",
"react-router",
"rocket",
"route",
"ruby",
Expand Down
270 changes: 270 additions & 0 deletions docs/quickstarts/react-router.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
---
title: React Router Quickstart
description: Learn how to use Clerk to quickly and easily add secure authentication and user management to your React Router application.
---

<TutorialHero
framework="react-router"
exampleRepo={[
{
title: "React Router Quickstart Repo",
link: "https://github.com/clerk/clerk-react-router-quickstart"

}
]}
beforeYouStart={[
{
title: "Set up a Clerk application",
link: "/docs/quickstarts/setup-clerk",
icon: "clerk",
},
{
title: "Install React Router as a framework",
link: "https://reactrouter.com/start/framework/installation",
icon: "react-router",
}
]}
>
- Install `@clerk/react-router`
- Set your Clerk API keys
- Configure `rootAuthLoader`
- Add `<ClerkProvider>`
- Add Clerk components
</TutorialHero>

Learn how to use Clerk to quickly and easily add secure authentication and user management to your React Router app. This guide assumes that you are using React Router v7 or later.

<Steps>
### Install `@clerk/react-router`

Clerk's React Router SDK gives you access to prebuilt components, hooks, and helpers to make user authentication easier.

Run the following command to install the SDK:

<CodeBlockTabs options={["npm", "yarn", "pnpm"]}>
```bash {{ filename: 'terminal' }}
npm install @clerk/react-router
```

```bash {{ filename: 'terminal' }}
yarn add @clerk/react-router
```

```bash {{ filename: 'terminal' }}
pnpm add @clerk/react-router
```
</CodeBlockTabs>

### Set your Clerk API keys

<SignedIn>
Add the following keys to your `.env` file. These keys can always be retrieved from the [API Keys](https://dashboard.clerk.com/last-active?path=api-keys) page of your Clerk Dashboard.
</SignedIn>

<SignedOut>
1. Navigate to the Clerk Dashboard.
1. In the navigation sidebar, select [API Keys](https://dashboard.clerk.com/last-active?path=api-keys).
1. In the **Quick Copy** section, copy your Clerk publishable and secret key.
1. Paste your keys into your `.env` file.

The final result should resemble the following:
</SignedOut>

```env {{ filename: '.env' }}
CLERK_PUBLISHABLE_KEY={{pub_key}}
CLERK_SECRET_KEY={{secret}}
```

### Configure `rootAuthLoader`

To configure Clerk in your React Router app, you will need to update your root loader. This will enable you to have access to authentication state in any React Router route.

Update your `root.tsx` file with the following code:

```tsx {{ filename: 'app/root.tsx', mark: [1, [6, 8]], collapsible: true }}
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>
)
}
```

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

```tsx {{ filename: 'app/root.tsx' }}
// Imports

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

// Rest of the root.tsx code
```

### Add `<ClerkProvider>`

The [`<ClerkProvider>`](/docs/components/clerk-provider) component wraps your app to provide active session and user context to Clerk's hooks and other components. The data from the root `loader` you added in the previous step is available as `loaderData` to the default App export inside `root.tsx`. Pass the `loaderData` to `<ClerkProvider>`.

```tsx {{ filename: 'app/root.tsx' }}
// Imports
import { ClerkProvider } from '@clerk/react-router'

export default function App({ loaderData }: Route.ComponentProps) {
return (
<ClerkProvider loaderData={loaderData}>
<Outlet />
</ClerkProvider>
)
}

// Rest of the root.tsx code
```

### Add Clerk components

You can control which content signed-in and signed-out users can see with Clerk's [prebuilt control components](/docs/components/overview#what-are-control-components). Create a header using the following components:

- [`<SignedIn>`](/docs/components/control/signed-in): Children of this component can only be seen while **signed in**.
- [`<SignedOut>`](/docs/components/control/signed-out): Children of this component can only be seen while **signed out**.
- [`<UserButton />`](/docs/components/user/user-button): Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options.
- [`<SignInButton />`](/docs/components/unstyled/sign-in-button): An unstyled component that links to the sign-in page. In this example, since no props or [environment variables](/docs/deployments/clerk-environment-variables) are set for the sign-in URL, this component links to the [Account Portal sign-in page](/docs/customization/account-portal/overview#sign-in).

Add them to the App component:

```tsx {{ filename: 'app/root.tsx', mark: [2, [7, 17]] }}
// Imports
import { ClerkProvider, SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/react-router'

export default function App({ loaderData }: Route.ComponentProps) {
return (
<ClerkProvider loaderData={loaderData}>
<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:

<CodeBlockTabs options={["npm", "yarn", "pnpm"]}>
```bash {{ filename: 'terminal' }}
npm run dev
```

```bash {{ filename: 'terminal' }}
yarn dev
```

```bash {{ filename: 'terminal' }}
pnpm dev
```
</CodeBlockTabs>

Visit your app's homepage at [`http://localhost:5173`](http://localhost:5173). Sign up to create your first user.
</Steps>

## Next steps

<Cards>
- [Create custom sign-up and sign-in pages](/docs/references/react-router/custom-signup-signin-pages)
- Learn how add custom sign-up and sign-in pages with Clerk components.

---

- [Read session and data](/docs/references/react-router/read-session-data)
- Learn how to use Clerk's hooks and helpers to access the active session and user data in your React Router app.

---

- [Customization & localization](/docs/customization/overview)
- Learn how to customize and localize the Clerk components.

---

- [Clerk components](/docs/components/overview)
- Learn more about the prebuilt components.
</Cards>
Loading
Loading