-
Notifications
You must be signed in to change notification settings - Fork 696
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
Changes from 17 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
df3c8bf
initial
LekoArts 1767f16
add quickstart
LekoArts 4721ebb
Linting
LekoArts 9909a11
fix code snippet
LekoArts 95392a9
add beta tags
LekoArts 932ff16
add sign-in sign-up page content
LekoArts ed817a0
Add React Router icon (#1763)
bradlc 5a3c422
Merge branch 'main' into lekoarts/eco-248-addupdate-documentation
LekoArts 9d5a136
improve guides
LekoArts bbb2247
linting
LekoArts 472069a
more docs
LekoArts 7e0bb63
fix steps
LekoArts 8410453
library mode
LekoArts 8d9c6dc
add RR to two other docs
LekoArts 15f492b
linting
LekoArts 0a4f1ca
update quickstart
LekoArts ea177b1
fix typos
LekoArts 9ad0a51
update clerkprovider wording
LekoArts 8be1cd5
delete add-react-router guide (obsolete)
LekoArts 949ca2d
update env var
LekoArts e6d8ea8
Merge branch 'main' into lekoarts/eco-248-addupdate-documentation
LekoArts 1253bbf
Merge branch 'main' into lekoarts/eco-248-addupdate-documentation
victoriaxyz d5d29a1
refactor
victoriaxyz 13ccb64
Apply suggestions from code review
victoriaxyz 1c1dac7
follow-up fixes
LekoArts a29c74b
last set of changes
LekoArts 2b8bcd2
linting :D
LekoArts 8b7a8a6
code review
alexisintech e7aa1d8
add the fallback redirect url props back
alexisintech 9bbb1e5
improvements
LekoArts 6303eae
typo
LekoArts 8cd5fd6
add beta callouts to react router docs
alexisintech 818671e
Update docs/references/react-router/root-auth-loader.mdx
alexisintech eb35bbf
update callouts
alexisintech fd668b0
update signInUrl signUpUrl prop descriptions
alexisintech File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,6 +125,7 @@ | |
"react", | ||
"redwood", | ||
"remix", | ||
"react-router", | ||
"rocket", | ||
"route", | ||
"ruby", | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: | ||
LekoArts marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```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}> | ||
alexisintech marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<header className="flex items-center justify-center py-8 px-4"> | ||
alexisintech marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<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> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.