From 95d2a059acbcbd3e40949735b00178ca9f28aca2 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 1 Oct 2025 07:49:20 -0700 Subject: [PATCH 01/12] Add React Router middleware docs --- .../getting-started/quickstart.js-backend.mdx | 7 +-- .../quickstart.react-router.mdx | 51 ++++++++++++------- ...fying-oauth-access-tokens.react-router.mdx | 4 +- .../sessions/customize-session-tokens.mdx | 5 +- docs/guides/sessions/session-tokens.mdx | 7 ++- docs/guides/users/reading.react-router.mdx | 18 +++---- docs/manifest.json | 4 ++ .../react-router/clerk-middleware.mdx | 34 +++++++++++++ .../react-router/root-auth-loader.mdx | 10 ++-- public/manifest.proposal.json | 1 + 10 files changed, 89 insertions(+), 52 deletions(-) create mode 100644 docs/reference/react-router/clerk-middleware.mdx create mode 100644 public/manifest.proposal.json diff --git a/docs/getting-started/quickstart.js-backend.mdx b/docs/getting-started/quickstart.js-backend.mdx index 4c7be4fd79..621f9cc8a6 100644 --- a/docs/getting-started/quickstart.js-backend.mdx +++ b/docs/getting-started/quickstart.js-backend.mdx @@ -419,8 +419,7 @@ The [`Auth`](/docs/reference/backend/types/auth-object) object contains importan ```tsx {{ filename: 'app/routes/profile.tsx' }} import { redirect } from 'react-router' - import { getAuth } from '@clerk/react-router/ssr.server' - import { createClerkClient } from '@clerk/react-router/api.server' + import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { @@ -433,9 +432,7 @@ The [`Auth`](/docs/reference/backend/types/auth-object) object contains importan } // Use the JS Backend SDK's `getUser()` method to get the Backend User object - const user = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }).users.getUser( - userId, - ) + const user = await clerkClient.users.getUser(userId) // Return the Backend User object return { diff --git a/docs/getting-started/quickstart.react-router.mdx b/docs/getting-started/quickstart.react-router.mdx index 0a1b9a6c30..c9f1df950c 100644 --- a/docs/getting-started/quickstart.react-router.mdx +++ b/docs/getting-started/quickstart.react-router.mdx @@ -15,7 +15,7 @@ sdk: react-router beforeYouStart={[ { title: "Set up a Clerk application", - link: "/docs/getting-started/quickstart/setup-clerk", + link: "/docs/quickstarts/setup-clerk", icon: "clerk", }, { @@ -26,14 +26,14 @@ sdk: react-router ]} /> -React Router can be used in different modes: **declarative**, **data**, or **framework**. This tutorial explains how to use React Router in **framework** mode. To use React Router in **declarative** mode instead, see the [dedicated guide](/docs/guides/development/declarative-mode). +React Router can be used in different modes: **declarative**, **data**, or **framework**. This tutorial explains how to use React Router in **framework** mode. To use React Router in **declarative** mode instead, see the [dedicated guide](/docs/references/react-router/declarative-mode). This tutorial assumes that you're using React Router **v7.1.2 or later** in framework mode. ## Install `@clerk/react-router` - The [Clerk React Router SDK](/docs/reference/react-router/overview) provides prebuilt components, hooks, and helpers to make it easy to integrate authentication and user management in your React Router app. + The [Clerk React Router SDK](/docs/references/react-router/overview) provides prebuilt components, hooks, and helpers to make it easy to integrate authentication and user management in your React Router app. Run the following command to install the SDK: @@ -74,23 +74,36 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram CLERK_SECRET_KEY={{secret}} ``` - ## Configure `rootAuthLoader()` + ## Add `clerkMiddleware()` and `rootAuthLoader()` to your app - The `rootAuthLoader()` function provides access to authentication state in any React Router route. + `clerkMiddleware()` grants you access to user authentication state throughout your app. - The following code shows how to add this function to your `root.tsx` file. If you're using [Clerk's React Router quickstart](https://github.com/clerk/clerk-react-router-quickstart) or the [React Router template](https://reactrouter.com/start/framework/installation), most of this code will already be present. + React Router middleware requires opting in via a future flag. Add the following to your `react-router.config.ts` file: - To load additional data or configure options, see the [`rootAuthLoader()`](/docs/reference/react-router/root-auth-loader) reference. + ```ts {{ filename: 'react-router.config.ts' }} + import type { Config } from "@react-router/dev/config"; + + export default { + // ... + future: { + v8_middleware: true, + }, + } satisfies Config; + ``` + + The following code shows how to configure both functions in your `root.tsx` file. If you're using [Clerk's React Router quickstart](https://github.com/clerk/clerk-react-router-quickstart) or the [React Router template](https://reactrouter.com/start/framework/installation), most of this code will already be present. + + To load additional data or configure options, see the [`clerkMiddleware()`](/docs/references/react-router/clerk-middleware) reference. ```tsx {{ filename: 'app/root.tsx', mark: [1, [6, 8]], collapsible: true }} - import { rootAuthLoader } from '@clerk/react-router/ssr.server' + import { clerkMiddleware, rootAuthLoader } from '@clerk/react-router/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 middleware: Route.MiddlewareFunction[] = [clerkMiddleware()] + + export const loader = (args: Route.LoaderArgs) => rootAuthLoader(args) export const links: Route.LinksFunction = () => [ { rel: 'preconnect', href: 'https://fonts.googleapis.com' }, @@ -164,10 +177,10 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram The following example adds `` and creates a header using the following Clerk components: - - [``](/docs/reference/components/control/signed-in): Children of this component can only be seen while **signed in**. - - [``](/docs/reference/components/control/signed-out): Children of this component can only be seen while **signed out**. - - [``](/docs/reference/components/user/user-button): Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. - - [``](/docs/reference/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/guides/development/clerk-environment-variables) are set for the sign-in URL, this component links to the [Account Portal sign-in page](/docs/guides/customizing-clerk/account-portal#sign-in). + - [``](/docs/components/control/signed-in): Children of this component can only be seen while **signed in**. + - [``](/docs/components/control/signed-out): Children of this component can only be seen while **signed out**. + - [``](/docs/components/user/user-button): Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. + - [``](/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/account-portal/overview#sign-in). ```tsx {{ filename: 'app/root.tsx' }} // Other imports @@ -223,16 +236,16 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram ## Next steps - - [Create a custom sign-in-or-up page](/docs/react-router/guides/development/custom-sign-in-or-up-page) + - [Create a custom sign-in-or-up page](/docs/references/react-router/custom-sign-in-or-up-page) - Learn how add custom sign-in-or-up page with Clerk components. --- - - [Read session and user data](/docs/react-router/guides/users/reading) - - Learn how to use Clerk's hooks and helpers to access the session and user data in your React Router app. + - [Read session and user 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. --- - - [Declarative mode](/docs/guides/development/declarative-mode) + - [Declarative mode](/docs/references/react-router/declarative-mode) - Learn how to use Clerk with React Router in declarative mode to add authentication to your application. diff --git a/docs/guides/development/verifying-oauth-access-tokens.react-router.mdx b/docs/guides/development/verifying-oauth-access-tokens.react-router.mdx index 1f561d75f7..8c58caf469 100644 --- a/docs/guides/development/verifying-oauth-access-tokens.react-router.mdx +++ b/docs/guides/development/verifying-oauth-access-tokens.react-router.mdx @@ -20,7 +20,7 @@ In the following example, the `acceptsToken` parameter is set to only accept `oa - If the token is valid, it returns the authenticated user's subject and their associated scopes for use in the application logic. ```tsx -import { getAuth } from '@clerk/react-router/ssr.server' +import { getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { @@ -43,7 +43,7 @@ In the following example, the `acceptsToken` parameter is set to accept any toke - Otherwise, it logs that the request uses a machine token and specifies its type. ```tsx -import { getAuth } from '@clerk/react-router/ssr.server' +import { getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { diff --git a/docs/guides/sessions/customize-session-tokens.mdx b/docs/guides/sessions/customize-session-tokens.mdx index 44165444b8..1cca3a0b1c 100644 --- a/docs/guides/sessions/customize-session-tokens.mdx +++ b/docs/guides/sessions/customize-session-tokens.mdx @@ -190,13 +190,12 @@ This guide will show you how to customize a session token to include additional ```tsx {{ filename: 'app/routes/profile.tsx' }} import { redirect } from 'react-router' - import { getAuth } from '@clerk/react-router/ssr.server' - import { createClerkClient } from '@clerk/react-router/api.server' + import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { // Use `getAuth()` to access `isAuthenticated` and the user's ID and session claims - const { isAuthenticated, userId, sessionClaims } = await getAuth(args) + const { isAuthenticated, sessionClaims } = await getAuth(args) // Protect the route by checking if the user is signed in if (!isAuthenticated) { diff --git a/docs/guides/sessions/session-tokens.mdx b/docs/guides/sessions/session-tokens.mdx index d5179e7cb2..a3b9b7037b 100644 --- a/docs/guides/sessions/session-tokens.mdx +++ b/docs/guides/sessions/session-tokens.mdx @@ -256,8 +256,7 @@ Then, when you need to access the other metadata fields, you can fetch them usin ```tsx {{ filename: 'app/routes/profile.tsx' }} import { redirect } from 'react-router' - import { getAuth } from '@clerk/react-router/ssr.server' - import { createClerkClient } from '@clerk/react-router/api.server' + import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { @@ -269,8 +268,8 @@ Then, when you need to access the other metadata fields, you can fetch them usin return redirect('/sign-in?redirect_url=' + args.request.url) } - // Use the JS Backend SDK's `getUser()` method to get the Backend User object - const user = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }).users.getUser( + // Get the Backend User object + const user = await clerkClient.users.getUser( userId, ) diff --git a/docs/guides/users/reading.react-router.mdx b/docs/guides/users/reading.react-router.mdx index 06289fae50..7662818ab2 100644 --- a/docs/guides/users/reading.react-router.mdx +++ b/docs/guides/users/reading.react-router.mdx @@ -20,8 +20,7 @@ In the following example, the `userId` is passed to the JS Backend SDK's `getUse ```tsx {{ filename: 'app/routes/profile.tsx' }} import { redirect } from 'react-router' -import { getAuth } from '@clerk/react-router/ssr.server' -import { createClerkClient } from '@clerk/react-router/api.server' +import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { @@ -33,10 +32,8 @@ export async function loader(args: Route.LoaderArgs) { return redirect('/sign-in?redirect_url=' + args.request.url) } - // Instantiate the JS Backend SDK and get the user's full `Backend User` object - const user = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }).users.getUser( - userId, - ) + // Get the user's full `Backend User` object + const user = await clerkClient.users.getUser(userId) return { user: JSON.stringify(user), @@ -61,8 +58,7 @@ Unlike the previous example that loads data when the page loads, the following e ```tsx {{ filename: 'app/routes/profile-form.tsx' }} import { redirect, Form } from 'react-router' -import { getAuth } from '@clerk/react-router/ssr.server' -import { createClerkClient } from '@clerk/react-router/api.server' +import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile-form' export async function action(args: Route.ActionArgs) { @@ -78,10 +74,8 @@ export async function action(args: Route.ActionArgs) { const formData = await args.request.formData() const name = formData.get('name')?.toString() - // Instantiate the JS Backend SDK and get the user's full `Backend User` object - const user = await createClerkClient({ - secretKey: process.env.CLERK_SECRET_KEY, - }).users.getUser(userId) + // Get the user's full `Backend User` object + const user = await clerkClient.users.getUser(userId) return { name, diff --git a/docs/manifest.json b/docs/manifest.json index 7e514dda08..cd5f4df40e 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1884,6 +1884,10 @@ "title": "Overview", "href": "/docs/reference/react-router/overview" }, + { + "title": "`clerkMiddleware()`", + "href": "/docs/references/react-router/clerk-middleware" + }, { "title": "`rootAuthLoader()`", "href": "/docs/reference/react-router/root-auth-loader" diff --git a/docs/reference/react-router/clerk-middleware.mdx b/docs/reference/react-router/clerk-middleware.mdx new file mode 100644 index 0000000000..11e2d17ff3 --- /dev/null +++ b/docs/reference/react-router/clerk-middleware.mdx @@ -0,0 +1,34 @@ +--- +title: '`clerkMiddleware()` | React Router' +description: The `clerkMiddleware()` function allows you to protect your React Router application using middleware. +sdk: react-router +--- + +The `clerkMiddleware()` helper integrates Clerk authentication into your React Router application through middleware. + +## Configure `clerkMiddleware()` + +1. React Router middleware requires opting in via a future flag. Add the following to your `react-router.config.ts` file: + + ```ts {{ filename: 'react-router.config.ts' }} + import type { Config } from "@react-router/dev/config"; + + export default { + future: { + v8_middleware: true, + }, + } satisfies Config; + ``` + +2. Export `clerkMiddleware()` from your root route file: + + ```tsx {{ filename: 'app/root.tsx' }} + import { clerkMiddleware } from '@clerk/react-router/server' + import type { Route } from './+types/root' + + export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()] + ``` + +## `clerkMiddleware()` options + + diff --git a/docs/reference/react-router/root-auth-loader.mdx b/docs/reference/react-router/root-auth-loader.mdx index ffa39f5605..4a54dbb5b5 100644 --- a/docs/reference/react-router/root-auth-loader.mdx +++ b/docs/reference/react-router/root-auth-loader.mdx @@ -20,7 +20,7 @@ You can also [pass configuration options](#pass-configuration-options) to `rootA In your `root.tsx` file, add `rootAuthLoader()` to the `loader()` function. If your app doesn't have a `loader()` function yet, you'll need to add it manually. ```tsx {{ filename: 'app/root.tsx' }} -import { rootAuthLoader } from '@clerk/react-router/ssr.server' +import { rootAuthLoader } from '@clerk/react-router/server' import type { Route } from './+types/root' export async function loader(args: Route.LoaderArgs) { @@ -33,7 +33,7 @@ export async function loader(args: Route.LoaderArgs) { If you need to load in additional data, you can pass a callback to `rootAuthLoader()` that handles the route data loading with auth state. ```tsx {{ filename: 'app/root.tsx' }} -import { rootAuthLoader } from '@clerk/react-router/ssr.server' +import { rootAuthLoader } from '@clerk/react-router/server' import type { Route } from './+types/root' export async function loader(args: Route.LoaderArgs) { @@ -50,7 +50,7 @@ export async function loader(args: Route.LoaderArgs) { To pass configuration [options](#root-auth-loader-options) to `rootAuthLoader()`, you can pass an optional argument to the `rootAuthLoader()` function. ```tsx {{ filename: 'app/root.tsx' }} -import { rootAuthLoader } from '@clerk/react-router/ssr.server' +import { rootAuthLoader } from '@clerk/react-router/server' import type { Route } from './+types/root' export async function loader(args: Route.LoaderArgs) { @@ -65,7 +65,3 @@ export async function loader(args: Route.LoaderArgs) { ) } ``` - -## `rootAuthLoader()` options - - diff --git a/public/manifest.proposal.json b/public/manifest.proposal.json new file mode 100644 index 0000000000..8e62a69515 --- /dev/null +++ b/public/manifest.proposal.json @@ -0,0 +1 @@ +{"navigation":[[{"title":"Home","items":[[{"title":"Core Concepts","items":[[{"title":"How Clerk Works","href":"/docs/core-concepts/how-clerk-works"},{"title":"Integrate Clerk","href":"/docs/core-concepts/integrate-clerk"},{"title":"Clerk Objects","href":"/docs/core-concepts/clerk-objects"},{"title":"Security at Clerk","href":"/docs/core-concepts/security"},{"title":"System Limits","href":"/docs/core-concepts/system-limits"},{"title":"AI Prompt Library","href":"/docs/core-concepts/ai-prompts"},{"title":"Multi-tenant Architecture","href":"/docs/core-concepts/multi-tenant-architecture"}]]}]]}],[{"title":"Getting Started","items":[[{"title":"Quickstart","items":[[{"title":"App Router","href":"/docs/getting-started/quickstart/app-router"},{"title":"Pages Router","href":"/docs/getting-started/quickstart/pages-router"}]]}],[{"title":"Clerk Dashboard","items":[[{"title":"Setting up your Clerk account","href":"/docs/getting-started/clerk-dashboard/setting-up-your-clerk-account"},{"title":"Configure your application","href":"/docs/getting-started/clerk-dashboard/configure-your-application"}]]}],[{"title":"Next Steps","items":[[{"title":"Custom sign-in/up pages","href":"/docs/getting-started/next-steps/custom-sign-in-up-pages"},{"title":"Protect specific routes","href":"/docs/getting-started/next-steps/protect-specific-routes"},{"title":"Read user and session data","href":"/docs/getting-started/next-steps/read-user-and-session-data"},{"title":"Add middleware","href":"/docs/getting-started/next-steps/add-middleware"}]]}]]}],[{"title":"Guides","items":[[{"title":"Securing your App","items":[[{"title":"Restricting Access","href":"/docs/guides/secure/restricting-access"},{"title":"Multifactor Authentication (MFA)","href":"/docs/guides/secure/mfa"},{"title":"Bot Detection","href":"/docs/guides/secure/bot-detection"},{"title":"Banning Users","href":"/docs/guides/secure/banning-users"},{"title":"Prevent brute force attacks","href":"/docs/guides/secure/prevent-brute-force-attacks"},{"title":"Re-verification (Step-up)","href":"/docs/guides/secure/re-verification-step-up"},{"title":"Legal Compliance","href":"/docs/guides/secure/legal-compliance"},{"title":"Security Best Practices","href":"/docs/guides/secure/best-practices"},{"title":"Session Options","href":"/docs/guides/secure/session-options"}]]}],[{"title":"Managing Users","items":[[{"title":"Managing Users","href":"/docs/guides/users/managing"},{"title":"Reading Clerk Data","href":"/docs/guides/users/reading"},{"title":"Extending Clerk Data","href":"/docs/guides/users/extending"},{"title":"Syncing Clerk Data","href":"/docs/guides/users/syncing"},{"title":"Impersonation","href":"/docs/guides/users/impersonation"}]]}],[{"title":"B2B","items":[[{"title":"Overview","href":"/docs/guides/b2b/overview"},{"title":"Managing Organizations","href":"/docs/guides/b2b/managing-orgs"},{"title":"Verified Domains","href":"/docs/guides/b2b/verified-domains"},{"title":"Roles and Permissions","href":"/docs/guides/b2b/roles-and-permissions"},{"title":"SSO / Enterprise Connections","href":"/docs/guides/b2b/sso-enterprise-connections"}]]}],[{"title":"Billing","items":[[{"title":"Overview","href":"/docs/guides/billing/overview"},{"title":"Billing for B2C","href":"/docs/guides/billing/for-b2c"},{"title":"Billing for B2B","href":"/docs/guides/billing/for-b2b"}]]}],[{"title":"Customizing Clerk","items":[[{"title":"UI Customization (Appearance Prop)","href":"/docs/guides/customizing-clerk/appearance-prop"},{"title":"Account Portal","href":"/docs/guides/customizing-clerk/account-portal"},{"title":"Adding items to UI Components","href":"/docs/guides/customizing-clerk/adding-items"},{"title":"Email and SMS Templates","href":"/docs/guides/customizing-clerk/email-and-sms-templates"},{"title":"Localization (i18n)","href":"/docs/guides/customizing-clerk/localization"},{"title":"Clerk Elements (beta)","href":"/docs/guides/customizing-clerk/elements"}]]}],[{"title":"Configuring your App","items":[[{"title":"Authentication Strategies","items":[[{"title":"Social Connections","href":"/docs/guides/configure/auth-strategies/social-connections"},{"title":"Enterprise Connections","href":"/docs/guides/configure/auth-strategies/enterprise-connections"},{"title":"Web3","href":"/docs/guides/configure/auth-strategies/web3"}]],"collapse":true},{"title":"Session Token customization","href":"/docs/guides/configure/session-token-customization"},{"title":"Syncing data with webhooks","href":"/docs/guides/configure/syncing-data-with-webhooks"},{"title":"Backend Requests","href":"/docs/guides/configure/backend-requests"},{"title":"Integrations","href":"/docs/guides/configure/integrations"}]]}],[{"title":"Clerk Dashboard","items":[[{"title":"Overview","href":"/docs/guides/clerk-dashboard/overview"},{"title":"Account Portal","href":"/docs/guides/clerk-dashboard/account-portal"},{"title":"DNS & Domains","href":"/docs/guides/clerk-dashboard/dns-domains"},{"title":"Plans & Billing","href":"/docs/guides/clerk-dashboard/plans-billing"}]]}],[{"title":"Development","items":[[{"title":"Deployment","href":"/docs/guides/development/deployment"},{"title":"Testing with Clerk","href":"/docs/guides/development/testing-with-clerk"},{"title":"Managing Environments","href":"/docs/guides/development/managing-environments"},{"title":"Migrating your Data","href":"/docs/guides/development/migrating-your-data"},{"title":"Clerk environment variables","href":"/docs/guides/development/clerk-environment-variables"},{"title":"SDK Development","href":"/docs/guides/development/sdk-development"},{"title":"Upgrading Clerk","items":[[{"title":"Versioning & LTS","href":"/docs/guides/development/upgrading/versioning"},{"title":"Upgrade Guides","items":[[{"title":"Core 2","href":"/docs/guides/development/upgrading/upgrade-guides/core-2"},{"title":"Node to Express","href":"/docs/guides/development/upgrading/upgrade-guides/node-to-express"},{"title":"Expo v2","href":"/docs/guides/development/upgrading/upgrade-guides/expo-v2"},{"title":"@clerk/nextjs v6","href":"/docs/guides/development/upgrading/upgrade-guides/next-v6"},{"title":"URL based session syncing","href":"/docs/guides/development/upgrading/upgrade-guides/url-session-syncing"},{"title":"Progressive Sign Ups","href":"/docs/guides/development/upgrading/upgrade-guides/progressive-sign-ups"}]],"collapse":true}]],"collapse":true},{"title":"Troubleshooting","href":"/docs/guides/development/troubleshooting"}]]}]]}],[{"title":"Examples","items":[[{"title":"Testing","items":[[{"title":"Test Link","href":"/docs/examples/testing/test-link"}]]}]]}],[{"title":"Reference","items":[[{"title":"API Reference","items":[[{"title":"SDK Reference","href":"/docs/reference/reference/sdk"},{"title":"UI Components","href":"/docs/reference/reference/components"},{"title":"API Reference","href":"/docs/reference/reference/api-reference"}]]}]]}]]} \ No newline at end of file From c548e556fd381fbd30196281c94c1f20da09f3c3 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 1 Oct 2025 07:54:04 -0700 Subject: [PATCH 02/12] fix links --- docs/getting-started/quickstart.react-router.mdx | 14 +++++++------- docs/reference/react-router/overview.mdx | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/getting-started/quickstart.react-router.mdx b/docs/getting-started/quickstart.react-router.mdx index c9f1df950c..9130a67f94 100644 --- a/docs/getting-started/quickstart.react-router.mdx +++ b/docs/getting-started/quickstart.react-router.mdx @@ -177,10 +177,10 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram The following example adds `` and creates a header using the following Clerk components: - - [``](/docs/components/control/signed-in): Children of this component can only be seen while **signed in**. - - [``](/docs/components/control/signed-out): Children of this component can only be seen while **signed out**. - - [``](/docs/components/user/user-button): Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. - - [``](/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/account-portal/overview#sign-in). + - [``](/docs/reference/components/control/signed-in): Children of this component can only be seen while **signed in**. + - [``](/docs/reference/components/control/signed-out): Children of this component can only be seen while **signed out**. + - [``](/docs/reference/components/user/user-button): Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. + - [``](/docs/reference/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/guides/development/clerk-environment-variables) are set for the sign-in URL, this component links to the [Account Portal sign-in page](/docs/guides/customizing-clerk/account-portal#sign-in). ```tsx {{ filename: 'app/root.tsx' }} // Other imports @@ -236,16 +236,16 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram ## Next steps - - [Create a custom sign-in-or-up page](/docs/references/react-router/custom-sign-in-or-up-page) + - [Create a custom sign-in-or-up page](/docs/react-router/guides/development/custom-sign-in-or-up-page) - Learn how add custom sign-in-or-up page with Clerk components. --- - - [Read session and user data](/docs/references/react-router/read-session-data) + - [Read session and user data](/docs/react-router/guides/users/reading) - Learn how to use Clerk's hooks and helpers to access the active session and user data in your React Router app. --- - - [Declarative mode](/docs/references/react-router/declarative-mode) + - [Declarative mode](/docs/guides/development/declarative-mode) - Learn how to use Clerk with React Router in declarative mode to add authentication to your application. diff --git a/docs/reference/react-router/overview.mdx b/docs/reference/react-router/overview.mdx index 00a08d469a..c20e55f8e8 100644 --- a/docs/reference/react-router/overview.mdx +++ b/docs/reference/react-router/overview.mdx @@ -17,6 +17,7 @@ Because the React Router SDK is built on top of the [React SDK](/docs/reference/ The following references show how to integrate Clerk features into applications using React Router server functions and API routes. - [`getAuth()`](/docs/reference/react-router/get-auth) +- [`clerkMiddleware()`](/docs/reference/react-router/clerk-middleware) - [`rootAuthLoader()`](/docs/reference/react-router/root-auth-loader) ## React Router implementations From a08ebf069e5ee4835676e627c92a203a86d850f5 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 1 Oct 2025 17:22:01 -0700 Subject: [PATCH 03/12] run format --- .../quickstart.react-router.mdx | 4 +- docs/guides/sessions/session-tokens.mdx | 4 +- .../react-router/clerk-middleware.mdx | 6 +- public/manifest.proposal.json | 304 +++++++++++++++++- 4 files changed, 309 insertions(+), 9 deletions(-) diff --git a/docs/getting-started/quickstart.react-router.mdx b/docs/getting-started/quickstart.react-router.mdx index 9130a67f94..3aae508aa5 100644 --- a/docs/getting-started/quickstart.react-router.mdx +++ b/docs/getting-started/quickstart.react-router.mdx @@ -81,14 +81,14 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram React Router middleware requires opting in via a future flag. Add the following to your `react-router.config.ts` file: ```ts {{ filename: 'react-router.config.ts' }} - import type { Config } from "@react-router/dev/config"; + import type { Config } from '@react-router/dev/config' export default { // ... future: { v8_middleware: true, }, - } satisfies Config; + } satisfies Config ``` The following code shows how to configure both functions in your `root.tsx` file. If you're using [Clerk's React Router quickstart](https://github.com/clerk/clerk-react-router-quickstart) or the [React Router template](https://reactrouter.com/start/framework/installation), most of this code will already be present. diff --git a/docs/guides/sessions/session-tokens.mdx b/docs/guides/sessions/session-tokens.mdx index a3b9b7037b..d5a4396658 100644 --- a/docs/guides/sessions/session-tokens.mdx +++ b/docs/guides/sessions/session-tokens.mdx @@ -269,9 +269,7 @@ Then, when you need to access the other metadata fields, you can fetch them usin } // Get the Backend User object - const user = await clerkClient.users.getUser( - userId, - ) + const user = await clerkClient.users.getUser(userId) // Return the Backend User object return { diff --git a/docs/reference/react-router/clerk-middleware.mdx b/docs/reference/react-router/clerk-middleware.mdx index 11e2d17ff3..1ed2881f48 100644 --- a/docs/reference/react-router/clerk-middleware.mdx +++ b/docs/reference/react-router/clerk-middleware.mdx @@ -11,16 +11,16 @@ The `clerkMiddleware()` helper integrates Clerk authentication into your React R 1. React Router middleware requires opting in via a future flag. Add the following to your `react-router.config.ts` file: ```ts {{ filename: 'react-router.config.ts' }} - import type { Config } from "@react-router/dev/config"; + import type { Config } from '@react-router/dev/config' export default { future: { v8_middleware: true, }, - } satisfies Config; + } satisfies Config ``` -2. Export `clerkMiddleware()` from your root route file: +1. Export `clerkMiddleware()` from your root route file: ```tsx {{ filename: 'app/root.tsx' }} import { clerkMiddleware } from '@clerk/react-router/server' diff --git a/public/manifest.proposal.json b/public/manifest.proposal.json index 8e62a69515..44440de742 100644 --- a/public/manifest.proposal.json +++ b/public/manifest.proposal.json @@ -1 +1,303 @@ -{"navigation":[[{"title":"Home","items":[[{"title":"Core Concepts","items":[[{"title":"How Clerk Works","href":"/docs/core-concepts/how-clerk-works"},{"title":"Integrate Clerk","href":"/docs/core-concepts/integrate-clerk"},{"title":"Clerk Objects","href":"/docs/core-concepts/clerk-objects"},{"title":"Security at Clerk","href":"/docs/core-concepts/security"},{"title":"System Limits","href":"/docs/core-concepts/system-limits"},{"title":"AI Prompt Library","href":"/docs/core-concepts/ai-prompts"},{"title":"Multi-tenant Architecture","href":"/docs/core-concepts/multi-tenant-architecture"}]]}]]}],[{"title":"Getting Started","items":[[{"title":"Quickstart","items":[[{"title":"App Router","href":"/docs/getting-started/quickstart/app-router"},{"title":"Pages Router","href":"/docs/getting-started/quickstart/pages-router"}]]}],[{"title":"Clerk Dashboard","items":[[{"title":"Setting up your Clerk account","href":"/docs/getting-started/clerk-dashboard/setting-up-your-clerk-account"},{"title":"Configure your application","href":"/docs/getting-started/clerk-dashboard/configure-your-application"}]]}],[{"title":"Next Steps","items":[[{"title":"Custom sign-in/up pages","href":"/docs/getting-started/next-steps/custom-sign-in-up-pages"},{"title":"Protect specific routes","href":"/docs/getting-started/next-steps/protect-specific-routes"},{"title":"Read user and session data","href":"/docs/getting-started/next-steps/read-user-and-session-data"},{"title":"Add middleware","href":"/docs/getting-started/next-steps/add-middleware"}]]}]]}],[{"title":"Guides","items":[[{"title":"Securing your App","items":[[{"title":"Restricting Access","href":"/docs/guides/secure/restricting-access"},{"title":"Multifactor Authentication (MFA)","href":"/docs/guides/secure/mfa"},{"title":"Bot Detection","href":"/docs/guides/secure/bot-detection"},{"title":"Banning Users","href":"/docs/guides/secure/banning-users"},{"title":"Prevent brute force attacks","href":"/docs/guides/secure/prevent-brute-force-attacks"},{"title":"Re-verification (Step-up)","href":"/docs/guides/secure/re-verification-step-up"},{"title":"Legal Compliance","href":"/docs/guides/secure/legal-compliance"},{"title":"Security Best Practices","href":"/docs/guides/secure/best-practices"},{"title":"Session Options","href":"/docs/guides/secure/session-options"}]]}],[{"title":"Managing Users","items":[[{"title":"Managing Users","href":"/docs/guides/users/managing"},{"title":"Reading Clerk Data","href":"/docs/guides/users/reading"},{"title":"Extending Clerk Data","href":"/docs/guides/users/extending"},{"title":"Syncing Clerk Data","href":"/docs/guides/users/syncing"},{"title":"Impersonation","href":"/docs/guides/users/impersonation"}]]}],[{"title":"B2B","items":[[{"title":"Overview","href":"/docs/guides/b2b/overview"},{"title":"Managing Organizations","href":"/docs/guides/b2b/managing-orgs"},{"title":"Verified Domains","href":"/docs/guides/b2b/verified-domains"},{"title":"Roles and Permissions","href":"/docs/guides/b2b/roles-and-permissions"},{"title":"SSO / Enterprise Connections","href":"/docs/guides/b2b/sso-enterprise-connections"}]]}],[{"title":"Billing","items":[[{"title":"Overview","href":"/docs/guides/billing/overview"},{"title":"Billing for B2C","href":"/docs/guides/billing/for-b2c"},{"title":"Billing for B2B","href":"/docs/guides/billing/for-b2b"}]]}],[{"title":"Customizing Clerk","items":[[{"title":"UI Customization (Appearance Prop)","href":"/docs/guides/customizing-clerk/appearance-prop"},{"title":"Account Portal","href":"/docs/guides/customizing-clerk/account-portal"},{"title":"Adding items to UI Components","href":"/docs/guides/customizing-clerk/adding-items"},{"title":"Email and SMS Templates","href":"/docs/guides/customizing-clerk/email-and-sms-templates"},{"title":"Localization (i18n)","href":"/docs/guides/customizing-clerk/localization"},{"title":"Clerk Elements (beta)","href":"/docs/guides/customizing-clerk/elements"}]]}],[{"title":"Configuring your App","items":[[{"title":"Authentication Strategies","items":[[{"title":"Social Connections","href":"/docs/guides/configure/auth-strategies/social-connections"},{"title":"Enterprise Connections","href":"/docs/guides/configure/auth-strategies/enterprise-connections"},{"title":"Web3","href":"/docs/guides/configure/auth-strategies/web3"}]],"collapse":true},{"title":"Session Token customization","href":"/docs/guides/configure/session-token-customization"},{"title":"Syncing data with webhooks","href":"/docs/guides/configure/syncing-data-with-webhooks"},{"title":"Backend Requests","href":"/docs/guides/configure/backend-requests"},{"title":"Integrations","href":"/docs/guides/configure/integrations"}]]}],[{"title":"Clerk Dashboard","items":[[{"title":"Overview","href":"/docs/guides/clerk-dashboard/overview"},{"title":"Account Portal","href":"/docs/guides/clerk-dashboard/account-portal"},{"title":"DNS & Domains","href":"/docs/guides/clerk-dashboard/dns-domains"},{"title":"Plans & Billing","href":"/docs/guides/clerk-dashboard/plans-billing"}]]}],[{"title":"Development","items":[[{"title":"Deployment","href":"/docs/guides/development/deployment"},{"title":"Testing with Clerk","href":"/docs/guides/development/testing-with-clerk"},{"title":"Managing Environments","href":"/docs/guides/development/managing-environments"},{"title":"Migrating your Data","href":"/docs/guides/development/migrating-your-data"},{"title":"Clerk environment variables","href":"/docs/guides/development/clerk-environment-variables"},{"title":"SDK Development","href":"/docs/guides/development/sdk-development"},{"title":"Upgrading Clerk","items":[[{"title":"Versioning & LTS","href":"/docs/guides/development/upgrading/versioning"},{"title":"Upgrade Guides","items":[[{"title":"Core 2","href":"/docs/guides/development/upgrading/upgrade-guides/core-2"},{"title":"Node to Express","href":"/docs/guides/development/upgrading/upgrade-guides/node-to-express"},{"title":"Expo v2","href":"/docs/guides/development/upgrading/upgrade-guides/expo-v2"},{"title":"@clerk/nextjs v6","href":"/docs/guides/development/upgrading/upgrade-guides/next-v6"},{"title":"URL based session syncing","href":"/docs/guides/development/upgrading/upgrade-guides/url-session-syncing"},{"title":"Progressive Sign Ups","href":"/docs/guides/development/upgrading/upgrade-guides/progressive-sign-ups"}]],"collapse":true}]],"collapse":true},{"title":"Troubleshooting","href":"/docs/guides/development/troubleshooting"}]]}]]}],[{"title":"Examples","items":[[{"title":"Testing","items":[[{"title":"Test Link","href":"/docs/examples/testing/test-link"}]]}]]}],[{"title":"Reference","items":[[{"title":"API Reference","items":[[{"title":"SDK Reference","href":"/docs/reference/reference/sdk"},{"title":"UI Components","href":"/docs/reference/reference/components"},{"title":"API Reference","href":"/docs/reference/reference/api-reference"}]]}]]}]]} \ No newline at end of file +{ + "navigation": [ + [ + { + "title": "Home", + "items": [ + [ + { + "title": "Core Concepts", + "items": [ + [ + { "title": "How Clerk Works", "href": "/docs/core-concepts/how-clerk-works" }, + { "title": "Integrate Clerk", "href": "/docs/core-concepts/integrate-clerk" }, + { "title": "Clerk Objects", "href": "/docs/core-concepts/clerk-objects" }, + { "title": "Security at Clerk", "href": "/docs/core-concepts/security" }, + { "title": "System Limits", "href": "/docs/core-concepts/system-limits" }, + { "title": "AI Prompt Library", "href": "/docs/core-concepts/ai-prompts" }, + { "title": "Multi-tenant Architecture", "href": "/docs/core-concepts/multi-tenant-architecture" } + ] + ] + } + ] + ] + } + ], + [ + { + "title": "Getting Started", + "items": [ + [ + { + "title": "Quickstart", + "items": [ + [ + { "title": "App Router", "href": "/docs/getting-started/quickstart/app-router" }, + { "title": "Pages Router", "href": "/docs/getting-started/quickstart/pages-router" } + ] + ] + } + ], + [ + { + "title": "Clerk Dashboard", + "items": [ + [ + { + "title": "Setting up your Clerk account", + "href": "/docs/getting-started/clerk-dashboard/setting-up-your-clerk-account" + }, + { + "title": "Configure your application", + "href": "/docs/getting-started/clerk-dashboard/configure-your-application" + } + ] + ] + } + ], + [ + { + "title": "Next Steps", + "items": [ + [ + { + "title": "Custom sign-in/up pages", + "href": "/docs/getting-started/next-steps/custom-sign-in-up-pages" + }, + { + "title": "Protect specific routes", + "href": "/docs/getting-started/next-steps/protect-specific-routes" + }, + { + "title": "Read user and session data", + "href": "/docs/getting-started/next-steps/read-user-and-session-data" + }, + { "title": "Add middleware", "href": "/docs/getting-started/next-steps/add-middleware" } + ] + ] + } + ] + ] + } + ], + [ + { + "title": "Guides", + "items": [ + [ + { + "title": "Securing your App", + "items": [ + [ + { "title": "Restricting Access", "href": "/docs/guides/secure/restricting-access" }, + { "title": "Multifactor Authentication (MFA)", "href": "/docs/guides/secure/mfa" }, + { "title": "Bot Detection", "href": "/docs/guides/secure/bot-detection" }, + { "title": "Banning Users", "href": "/docs/guides/secure/banning-users" }, + { "title": "Prevent brute force attacks", "href": "/docs/guides/secure/prevent-brute-force-attacks" }, + { "title": "Re-verification (Step-up)", "href": "/docs/guides/secure/re-verification-step-up" }, + { "title": "Legal Compliance", "href": "/docs/guides/secure/legal-compliance" }, + { "title": "Security Best Practices", "href": "/docs/guides/secure/best-practices" }, + { "title": "Session Options", "href": "/docs/guides/secure/session-options" } + ] + ] + } + ], + [ + { + "title": "Managing Users", + "items": [ + [ + { "title": "Managing Users", "href": "/docs/guides/users/managing" }, + { "title": "Reading Clerk Data", "href": "/docs/guides/users/reading" }, + { "title": "Extending Clerk Data", "href": "/docs/guides/users/extending" }, + { "title": "Syncing Clerk Data", "href": "/docs/guides/users/syncing" }, + { "title": "Impersonation", "href": "/docs/guides/users/impersonation" } + ] + ] + } + ], + [ + { + "title": "B2B", + "items": [ + [ + { "title": "Overview", "href": "/docs/guides/b2b/overview" }, + { "title": "Managing Organizations", "href": "/docs/guides/b2b/managing-orgs" }, + { "title": "Verified Domains", "href": "/docs/guides/b2b/verified-domains" }, + { "title": "Roles and Permissions", "href": "/docs/guides/b2b/roles-and-permissions" }, + { "title": "SSO / Enterprise Connections", "href": "/docs/guides/b2b/sso-enterprise-connections" } + ] + ] + } + ], + [ + { + "title": "Billing", + "items": [ + [ + { "title": "Overview", "href": "/docs/guides/billing/overview" }, + { "title": "Billing for B2C", "href": "/docs/guides/billing/for-b2c" }, + { "title": "Billing for B2B", "href": "/docs/guides/billing/for-b2b" } + ] + ] + } + ], + [ + { + "title": "Customizing Clerk", + "items": [ + [ + { + "title": "UI Customization (Appearance Prop)", + "href": "/docs/guides/customizing-clerk/appearance-prop" + }, + { "title": "Account Portal", "href": "/docs/guides/customizing-clerk/account-portal" }, + { "title": "Adding items to UI Components", "href": "/docs/guides/customizing-clerk/adding-items" }, + { + "title": "Email and SMS Templates", + "href": "/docs/guides/customizing-clerk/email-and-sms-templates" + }, + { "title": "Localization (i18n)", "href": "/docs/guides/customizing-clerk/localization" }, + { "title": "Clerk Elements (beta)", "href": "/docs/guides/customizing-clerk/elements" } + ] + ] + } + ], + [ + { + "title": "Configuring your App", + "items": [ + [ + { + "title": "Authentication Strategies", + "items": [ + [ + { + "title": "Social Connections", + "href": "/docs/guides/configure/auth-strategies/social-connections" + }, + { + "title": "Enterprise Connections", + "href": "/docs/guides/configure/auth-strategies/enterprise-connections" + }, + { "title": "Web3", "href": "/docs/guides/configure/auth-strategies/web3" } + ] + ], + "collapse": true + }, + { + "title": "Session Token customization", + "href": "/docs/guides/configure/session-token-customization" + }, + { + "title": "Syncing data with webhooks", + "href": "/docs/guides/configure/syncing-data-with-webhooks" + }, + { "title": "Backend Requests", "href": "/docs/guides/configure/backend-requests" }, + { "title": "Integrations", "href": "/docs/guides/configure/integrations" } + ] + ] + } + ], + [ + { + "title": "Clerk Dashboard", + "items": [ + [ + { "title": "Overview", "href": "/docs/guides/clerk-dashboard/overview" }, + { "title": "Account Portal", "href": "/docs/guides/clerk-dashboard/account-portal" }, + { "title": "DNS & Domains", "href": "/docs/guides/clerk-dashboard/dns-domains" }, + { "title": "Plans & Billing", "href": "/docs/guides/clerk-dashboard/plans-billing" } + ] + ] + } + ], + [ + { + "title": "Development", + "items": [ + [ + { "title": "Deployment", "href": "/docs/guides/development/deployment" }, + { "title": "Testing with Clerk", "href": "/docs/guides/development/testing-with-clerk" }, + { "title": "Managing Environments", "href": "/docs/guides/development/managing-environments" }, + { "title": "Migrating your Data", "href": "/docs/guides/development/migrating-your-data" }, + { + "title": "Clerk environment variables", + "href": "/docs/guides/development/clerk-environment-variables" + }, + { "title": "SDK Development", "href": "/docs/guides/development/sdk-development" }, + { + "title": "Upgrading Clerk", + "items": [ + [ + { "title": "Versioning & LTS", "href": "/docs/guides/development/upgrading/versioning" }, + { + "title": "Upgrade Guides", + "items": [ + [ + { "title": "Core 2", "href": "/docs/guides/development/upgrading/upgrade-guides/core-2" }, + { + "title": "Node to Express", + "href": "/docs/guides/development/upgrading/upgrade-guides/node-to-express" + }, + { + "title": "Expo v2", + "href": "/docs/guides/development/upgrading/upgrade-guides/expo-v2" + }, + { + "title": "@clerk/nextjs v6", + "href": "/docs/guides/development/upgrading/upgrade-guides/next-v6" + }, + { + "title": "URL based session syncing", + "href": "/docs/guides/development/upgrading/upgrade-guides/url-session-syncing" + }, + { + "title": "Progressive Sign Ups", + "href": "/docs/guides/development/upgrading/upgrade-guides/progressive-sign-ups" + } + ] + ], + "collapse": true + } + ] + ], + "collapse": true + }, + { "title": "Troubleshooting", "href": "/docs/guides/development/troubleshooting" } + ] + ] + } + ] + ] + } + ], + [ + { + "title": "Examples", + "items": [ + [{ "title": "Testing", "items": [[{ "title": "Test Link", "href": "/docs/examples/testing/test-link" }]] }] + ] + } + ], + [ + { + "title": "Reference", + "items": [ + [ + { + "title": "API Reference", + "items": [ + [ + { "title": "SDK Reference", "href": "/docs/reference/reference/sdk" }, + { "title": "UI Components", "href": "/docs/reference/reference/components" }, + { "title": "API Reference", "href": "/docs/reference/reference/api-reference" } + ] + ] + } + ] + ] + } + ] + ] +} From c5acd7eb0fc7bbbbe88f01426624c6b548b5599a Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 1 Oct 2025 17:24:14 -0700 Subject: [PATCH 04/12] fix links --- docs/getting-started/quickstart.react-router.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/getting-started/quickstart.react-router.mdx b/docs/getting-started/quickstart.react-router.mdx index 3aae508aa5..0b7459bbf5 100644 --- a/docs/getting-started/quickstart.react-router.mdx +++ b/docs/getting-started/quickstart.react-router.mdx @@ -15,7 +15,7 @@ sdk: react-router beforeYouStart={[ { title: "Set up a Clerk application", - link: "/docs/quickstarts/setup-clerk", + link: "/docs/getting-started/quickstart/setup-clerk", icon: "clerk", }, { @@ -26,14 +26,14 @@ sdk: react-router ]} /> -React Router can be used in different modes: **declarative**, **data**, or **framework**. This tutorial explains how to use React Router in **framework** mode. To use React Router in **declarative** mode instead, see the [dedicated guide](/docs/references/react-router/declarative-mode). +React Router can be used in different modes: **declarative**, **data**, or **framework**. This tutorial explains how to use React Router in **framework** mode. To use React Router in **declarative** mode instead, see the [dedicated guide](/docs/guides/development/declarative-mode). This tutorial assumes that you're using React Router **v7.1.2 or later** in framework mode. ## Install `@clerk/react-router` - The [Clerk React Router SDK](/docs/references/react-router/overview) provides prebuilt components, hooks, and helpers to make it easy to integrate authentication and user management in your React Router app. + The [Clerk React Router SDK](/docs/reference/react-router/overview) provides prebuilt components, hooks, and helpers to make it easy to integrate authentication and user management in your React Router app. Run the following command to install the SDK: @@ -242,7 +242,7 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram --- - [Read session and user data](/docs/react-router/guides/users/reading) - - Learn how to use Clerk's hooks and helpers to access the active session and user data in your React Router app. + - Learn how to use Clerk's hooks and helpers to access the session and user data in your React Router app. --- From 68a56d72b87f2362d5bbace0f4ef0c405e372669 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 1 Oct 2025 17:26:25 -0700 Subject: [PATCH 05/12] fix links --- docs/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/manifest.json b/docs/manifest.json index cd5f4df40e..feb931647d 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1886,7 +1886,7 @@ }, { "title": "`clerkMiddleware()`", - "href": "/docs/references/react-router/clerk-middleware" + "href": "/docs/reference/react-router/clerk-middleware" }, { "title": "`rootAuthLoader()`", From 79894c02b67d366793f13320fc4773717851e196 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Wed, 1 Oct 2025 17:28:06 -0700 Subject: [PATCH 06/12] fix links --- docs/getting-started/quickstart.react-router.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/quickstart.react-router.mdx b/docs/getting-started/quickstart.react-router.mdx index 0b7459bbf5..190abb309f 100644 --- a/docs/getting-started/quickstart.react-router.mdx +++ b/docs/getting-started/quickstart.react-router.mdx @@ -93,7 +93,7 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram The following code shows how to configure both functions in your `root.tsx` file. If you're using [Clerk's React Router quickstart](https://github.com/clerk/clerk-react-router-quickstart) or the [React Router template](https://reactrouter.com/start/framework/installation), most of this code will already be present. - To load additional data or configure options, see the [`clerkMiddleware()`](/docs/references/react-router/clerk-middleware) reference. + To load additional data or configure options, see the [`clerkMiddleware()`](/docs/reference/react-router/clerk-middleware) reference. ```tsx {{ filename: 'app/root.tsx', mark: [1, [6, 8]], collapsible: true }} import { clerkMiddleware, rootAuthLoader } from '@clerk/react-router/server' From f7758860d0e171856d4a39e01ff2f1758e652d6f Mon Sep 17 00:00:00 2001 From: Sarah Soutoul Date: Thu, 2 Oct 2025 10:28:39 -0600 Subject: [PATCH 07/12] docs review --- docs/getting-started/quickstart.react-router.mdx | 6 +++--- docs/manifest.json | 2 +- docs/reference/react-router/root-auth-loader.mdx | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/getting-started/quickstart.react-router.mdx b/docs/getting-started/quickstart.react-router.mdx index 9130a67f94..f4dfa93e28 100644 --- a/docs/getting-started/quickstart.react-router.mdx +++ b/docs/getting-started/quickstart.react-router.mdx @@ -26,14 +26,14 @@ sdk: react-router ]} /> -React Router can be used in different modes: **declarative**, **data**, or **framework**. This tutorial explains how to use React Router in **framework** mode. To use React Router in **declarative** mode instead, see the [dedicated guide](/docs/references/react-router/declarative-mode). +React Router can be used in different modes: **declarative**, **data**, or **framework**. This tutorial explains how to use React Router in **framework** mode. To use React Router in **declarative** mode instead, see the [dedicated guide](/docs/guides/development/declarative-mode). This tutorial assumes that you're using React Router **v7.1.2 or later** in framework mode. ## Install `@clerk/react-router` - The [Clerk React Router SDK](/docs/references/react-router/overview) provides prebuilt components, hooks, and helpers to make it easy to integrate authentication and user management in your React Router app. + The [Clerk React Router SDK](/docs/reference/react-router/overview) provides prebuilt components, hooks, and helpers to make it easy to integrate authentication and user management in your React Router app. Run the following command to install the SDK: @@ -93,7 +93,7 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram The following code shows how to configure both functions in your `root.tsx` file. If you're using [Clerk's React Router quickstart](https://github.com/clerk/clerk-react-router-quickstart) or the [React Router template](https://reactrouter.com/start/framework/installation), most of this code will already be present. - To load additional data or configure options, see the [`clerkMiddleware()`](/docs/references/react-router/clerk-middleware) reference. + To load additional data or configure options, see the [`clerkMiddleware()`](/docs/reference/react-router/clerk-middleware) reference. ```tsx {{ filename: 'app/root.tsx', mark: [1, [6, 8]], collapsible: true }} import { clerkMiddleware, rootAuthLoader } from '@clerk/react-router/server' diff --git a/docs/manifest.json b/docs/manifest.json index cd5f4df40e..feb931647d 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1886,7 +1886,7 @@ }, { "title": "`clerkMiddleware()`", - "href": "/docs/references/react-router/clerk-middleware" + "href": "/docs/reference/react-router/clerk-middleware" }, { "title": "`rootAuthLoader()`", diff --git a/docs/reference/react-router/root-auth-loader.mdx b/docs/reference/react-router/root-auth-loader.mdx index 4a54dbb5b5..6417dcae89 100644 --- a/docs/reference/react-router/root-auth-loader.mdx +++ b/docs/reference/react-router/root-auth-loader.mdx @@ -65,3 +65,7 @@ export async function loader(args: Route.LoaderArgs) { ) } ``` + +## `rootAuthLoader()` options + + From 1493e18edc056806fe7ae667a9a3c131aa973594 Mon Sep 17 00:00:00 2001 From: Sarah Soutoul Date: Thu, 2 Oct 2025 10:34:40 -0600 Subject: [PATCH 08/12] Remove manifest proposal --- public/manifest.proposal.json | 303 ---------------------------------- 1 file changed, 303 deletions(-) delete mode 100644 public/manifest.proposal.json diff --git a/public/manifest.proposal.json b/public/manifest.proposal.json deleted file mode 100644 index 44440de742..0000000000 --- a/public/manifest.proposal.json +++ /dev/null @@ -1,303 +0,0 @@ -{ - "navigation": [ - [ - { - "title": "Home", - "items": [ - [ - { - "title": "Core Concepts", - "items": [ - [ - { "title": "How Clerk Works", "href": "/docs/core-concepts/how-clerk-works" }, - { "title": "Integrate Clerk", "href": "/docs/core-concepts/integrate-clerk" }, - { "title": "Clerk Objects", "href": "/docs/core-concepts/clerk-objects" }, - { "title": "Security at Clerk", "href": "/docs/core-concepts/security" }, - { "title": "System Limits", "href": "/docs/core-concepts/system-limits" }, - { "title": "AI Prompt Library", "href": "/docs/core-concepts/ai-prompts" }, - { "title": "Multi-tenant Architecture", "href": "/docs/core-concepts/multi-tenant-architecture" } - ] - ] - } - ] - ] - } - ], - [ - { - "title": "Getting Started", - "items": [ - [ - { - "title": "Quickstart", - "items": [ - [ - { "title": "App Router", "href": "/docs/getting-started/quickstart/app-router" }, - { "title": "Pages Router", "href": "/docs/getting-started/quickstart/pages-router" } - ] - ] - } - ], - [ - { - "title": "Clerk Dashboard", - "items": [ - [ - { - "title": "Setting up your Clerk account", - "href": "/docs/getting-started/clerk-dashboard/setting-up-your-clerk-account" - }, - { - "title": "Configure your application", - "href": "/docs/getting-started/clerk-dashboard/configure-your-application" - } - ] - ] - } - ], - [ - { - "title": "Next Steps", - "items": [ - [ - { - "title": "Custom sign-in/up pages", - "href": "/docs/getting-started/next-steps/custom-sign-in-up-pages" - }, - { - "title": "Protect specific routes", - "href": "/docs/getting-started/next-steps/protect-specific-routes" - }, - { - "title": "Read user and session data", - "href": "/docs/getting-started/next-steps/read-user-and-session-data" - }, - { "title": "Add middleware", "href": "/docs/getting-started/next-steps/add-middleware" } - ] - ] - } - ] - ] - } - ], - [ - { - "title": "Guides", - "items": [ - [ - { - "title": "Securing your App", - "items": [ - [ - { "title": "Restricting Access", "href": "/docs/guides/secure/restricting-access" }, - { "title": "Multifactor Authentication (MFA)", "href": "/docs/guides/secure/mfa" }, - { "title": "Bot Detection", "href": "/docs/guides/secure/bot-detection" }, - { "title": "Banning Users", "href": "/docs/guides/secure/banning-users" }, - { "title": "Prevent brute force attacks", "href": "/docs/guides/secure/prevent-brute-force-attacks" }, - { "title": "Re-verification (Step-up)", "href": "/docs/guides/secure/re-verification-step-up" }, - { "title": "Legal Compliance", "href": "/docs/guides/secure/legal-compliance" }, - { "title": "Security Best Practices", "href": "/docs/guides/secure/best-practices" }, - { "title": "Session Options", "href": "/docs/guides/secure/session-options" } - ] - ] - } - ], - [ - { - "title": "Managing Users", - "items": [ - [ - { "title": "Managing Users", "href": "/docs/guides/users/managing" }, - { "title": "Reading Clerk Data", "href": "/docs/guides/users/reading" }, - { "title": "Extending Clerk Data", "href": "/docs/guides/users/extending" }, - { "title": "Syncing Clerk Data", "href": "/docs/guides/users/syncing" }, - { "title": "Impersonation", "href": "/docs/guides/users/impersonation" } - ] - ] - } - ], - [ - { - "title": "B2B", - "items": [ - [ - { "title": "Overview", "href": "/docs/guides/b2b/overview" }, - { "title": "Managing Organizations", "href": "/docs/guides/b2b/managing-orgs" }, - { "title": "Verified Domains", "href": "/docs/guides/b2b/verified-domains" }, - { "title": "Roles and Permissions", "href": "/docs/guides/b2b/roles-and-permissions" }, - { "title": "SSO / Enterprise Connections", "href": "/docs/guides/b2b/sso-enterprise-connections" } - ] - ] - } - ], - [ - { - "title": "Billing", - "items": [ - [ - { "title": "Overview", "href": "/docs/guides/billing/overview" }, - { "title": "Billing for B2C", "href": "/docs/guides/billing/for-b2c" }, - { "title": "Billing for B2B", "href": "/docs/guides/billing/for-b2b" } - ] - ] - } - ], - [ - { - "title": "Customizing Clerk", - "items": [ - [ - { - "title": "UI Customization (Appearance Prop)", - "href": "/docs/guides/customizing-clerk/appearance-prop" - }, - { "title": "Account Portal", "href": "/docs/guides/customizing-clerk/account-portal" }, - { "title": "Adding items to UI Components", "href": "/docs/guides/customizing-clerk/adding-items" }, - { - "title": "Email and SMS Templates", - "href": "/docs/guides/customizing-clerk/email-and-sms-templates" - }, - { "title": "Localization (i18n)", "href": "/docs/guides/customizing-clerk/localization" }, - { "title": "Clerk Elements (beta)", "href": "/docs/guides/customizing-clerk/elements" } - ] - ] - } - ], - [ - { - "title": "Configuring your App", - "items": [ - [ - { - "title": "Authentication Strategies", - "items": [ - [ - { - "title": "Social Connections", - "href": "/docs/guides/configure/auth-strategies/social-connections" - }, - { - "title": "Enterprise Connections", - "href": "/docs/guides/configure/auth-strategies/enterprise-connections" - }, - { "title": "Web3", "href": "/docs/guides/configure/auth-strategies/web3" } - ] - ], - "collapse": true - }, - { - "title": "Session Token customization", - "href": "/docs/guides/configure/session-token-customization" - }, - { - "title": "Syncing data with webhooks", - "href": "/docs/guides/configure/syncing-data-with-webhooks" - }, - { "title": "Backend Requests", "href": "/docs/guides/configure/backend-requests" }, - { "title": "Integrations", "href": "/docs/guides/configure/integrations" } - ] - ] - } - ], - [ - { - "title": "Clerk Dashboard", - "items": [ - [ - { "title": "Overview", "href": "/docs/guides/clerk-dashboard/overview" }, - { "title": "Account Portal", "href": "/docs/guides/clerk-dashboard/account-portal" }, - { "title": "DNS & Domains", "href": "/docs/guides/clerk-dashboard/dns-domains" }, - { "title": "Plans & Billing", "href": "/docs/guides/clerk-dashboard/plans-billing" } - ] - ] - } - ], - [ - { - "title": "Development", - "items": [ - [ - { "title": "Deployment", "href": "/docs/guides/development/deployment" }, - { "title": "Testing with Clerk", "href": "/docs/guides/development/testing-with-clerk" }, - { "title": "Managing Environments", "href": "/docs/guides/development/managing-environments" }, - { "title": "Migrating your Data", "href": "/docs/guides/development/migrating-your-data" }, - { - "title": "Clerk environment variables", - "href": "/docs/guides/development/clerk-environment-variables" - }, - { "title": "SDK Development", "href": "/docs/guides/development/sdk-development" }, - { - "title": "Upgrading Clerk", - "items": [ - [ - { "title": "Versioning & LTS", "href": "/docs/guides/development/upgrading/versioning" }, - { - "title": "Upgrade Guides", - "items": [ - [ - { "title": "Core 2", "href": "/docs/guides/development/upgrading/upgrade-guides/core-2" }, - { - "title": "Node to Express", - "href": "/docs/guides/development/upgrading/upgrade-guides/node-to-express" - }, - { - "title": "Expo v2", - "href": "/docs/guides/development/upgrading/upgrade-guides/expo-v2" - }, - { - "title": "@clerk/nextjs v6", - "href": "/docs/guides/development/upgrading/upgrade-guides/next-v6" - }, - { - "title": "URL based session syncing", - "href": "/docs/guides/development/upgrading/upgrade-guides/url-session-syncing" - }, - { - "title": "Progressive Sign Ups", - "href": "/docs/guides/development/upgrading/upgrade-guides/progressive-sign-ups" - } - ] - ], - "collapse": true - } - ] - ], - "collapse": true - }, - { "title": "Troubleshooting", "href": "/docs/guides/development/troubleshooting" } - ] - ] - } - ] - ] - } - ], - [ - { - "title": "Examples", - "items": [ - [{ "title": "Testing", "items": [[{ "title": "Test Link", "href": "/docs/examples/testing/test-link" }]] }] - ] - } - ], - [ - { - "title": "Reference", - "items": [ - [ - { - "title": "API Reference", - "items": [ - [ - { "title": "SDK Reference", "href": "/docs/reference/reference/sdk" }, - { "title": "UI Components", "href": "/docs/reference/reference/components" }, - { "title": "API Reference", "href": "/docs/reference/reference/api-reference" } - ] - ] - } - ] - ] - } - ] - ] -} From 98dd1f7bd74c39da048c9a7d5e4f3129899c8c04 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Thu, 2 Oct 2025 11:44:56 -0700 Subject: [PATCH 09/12] add args to clerkClient --- docs/getting-started/quickstart.js-backend.mdx | 2 +- docs/guides/sessions/customize-session-tokens.mdx | 2 +- docs/guides/sessions/session-tokens.mdx | 2 +- docs/guides/users/reading.react-router.mdx | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/getting-started/quickstart.js-backend.mdx b/docs/getting-started/quickstart.js-backend.mdx index 621f9cc8a6..8fbebf7735 100644 --- a/docs/getting-started/quickstart.js-backend.mdx +++ b/docs/getting-started/quickstart.js-backend.mdx @@ -432,7 +432,7 @@ The [`Auth`](/docs/reference/backend/types/auth-object) object contains importan } // Use the JS Backend SDK's `getUser()` method to get the Backend User object - const user = await clerkClient.users.getUser(userId) + const user = await clerkClient(args).users.getUser(userId) // Return the Backend User object return { diff --git a/docs/guides/sessions/customize-session-tokens.mdx b/docs/guides/sessions/customize-session-tokens.mdx index 1cca3a0b1c..9b4576019b 100644 --- a/docs/guides/sessions/customize-session-tokens.mdx +++ b/docs/guides/sessions/customize-session-tokens.mdx @@ -190,7 +190,7 @@ This guide will show you how to customize a session token to include additional ```tsx {{ filename: 'app/routes/profile.tsx' }} import { redirect } from 'react-router' - import { clerkClient, getAuth } from '@clerk/react-router/server' + import { getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { diff --git a/docs/guides/sessions/session-tokens.mdx b/docs/guides/sessions/session-tokens.mdx index d5a4396658..4a19c97bcb 100644 --- a/docs/guides/sessions/session-tokens.mdx +++ b/docs/guides/sessions/session-tokens.mdx @@ -269,7 +269,7 @@ Then, when you need to access the other metadata fields, you can fetch them usin } // Get the Backend User object - const user = await clerkClient.users.getUser(userId) + const user = await clerkClient(args).users.getUser(userId) // Return the Backend User object return { diff --git a/docs/guides/users/reading.react-router.mdx b/docs/guides/users/reading.react-router.mdx index 7662818ab2..da2f6f3190 100644 --- a/docs/guides/users/reading.react-router.mdx +++ b/docs/guides/users/reading.react-router.mdx @@ -33,7 +33,7 @@ export async function loader(args: Route.LoaderArgs) { } // Get the user's full `Backend User` object - const user = await clerkClient.users.getUser(userId) + const user = await clerkClient(args).users.getUser(userId) return { user: JSON.stringify(user), @@ -75,7 +75,7 @@ export async function action(args: Route.ActionArgs) { const name = formData.get('name')?.toString() // Get the user's full `Backend User` object - const user = await clerkClient.users.getUser(userId) + const user = await clerkClient(args).users.getUser(userId) return { name, From 3aabe1d4ab1b1e5bcd16bc85b474cb56ef3032f4 Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Thu, 2 Oct 2025 15:40:07 -0700 Subject: [PATCH 10/12] remove auth loader options --- docs/_partials/root-auth-loader.mdx | 99 ------------------- .../react-router/root-auth-loader.mdx | 23 ----- 2 files changed, 122 deletions(-) delete mode 100644 docs/_partials/root-auth-loader.mdx diff --git a/docs/_partials/root-auth-loader.mdx b/docs/_partials/root-auth-loader.mdx deleted file mode 100644 index c449ac391a..0000000000 --- a/docs/_partials/root-auth-loader.mdx +++ /dev/null @@ -1,99 +0,0 @@ -The `rootAuthLoader()` function accepts an optional object. The following options are available: - - - - `audience?` - - `string | string[]` - - A string or list of [audiences](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3). If passed, it is checked against the `aud` claim in the token. - - --- - - - `authorizedParties?` - - `string[]` - - An allowlist of origins to verify against, to protect your application from the subdomain cookie leaking attack. For example: `['http://localhost:3000', 'https://example.com']` - - --- - - - `domain?` - - `string` - - The domain used for satellites to inform Clerk where this application is deployed. - - --- - - - `isSatellite?` - - `boolean` - - When using Clerk's satellite feature, this should be set to `true` for secondary domains. - - --- - - - `jwtKey` - - `string` - - Used to verify the session token in a networkless manner. Supply the **JWKS Public Key** from the [**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#api-and-sdk-configuration) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). - - --- - - - `proxyUrl?` - - `string` - - Specify the URL of the proxy, if using a proxy. - - --- - - - `publishableKey` - - `string` - - The Clerk Publishable Key for your instance. This can be found in the **[**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page -> Show Publishable Key** section in the Clerk Dashboard. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys) instead. - - --- - - - `secretKey?` - - `string` - - The Clerk Secret Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys) instead. - - --- - - - `signInUrl` - - `string` - - This URL will be used for any redirects that might happen and needs to point to your primary application on the client-side. This option is optional for production instances. **It is required to be set for a satellite application in a development instance.** It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. - - --- - - - `signUpUrl` - - `string` - - This URL will be used for any redirects that might happen and needs to point to your primary application on the client-side. This option is optional for production instances but **must be set for a satellite application in a development instance.** It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. - - --- - - - `signInFallbackRedirectUrl?` - - `string` - - The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Defaults to `/`. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. - - --- - - - `signUpFallbackRedirectUrl?` - - `string` - - The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Defaults to `/`. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. - - --- - - - `signInForceRedirectUrl?` - - `string` - - If provided, this URL will always be redirected to after the user signs in. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. - - --- - - - `signUpForceRedirectUrl?` - - `string` - - If provided, this URL will always be redirected to after the user signs up. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. - diff --git a/docs/reference/react-router/root-auth-loader.mdx b/docs/reference/react-router/root-auth-loader.mdx index 4a54dbb5b5..6440c310de 100644 --- a/docs/reference/react-router/root-auth-loader.mdx +++ b/docs/reference/react-router/root-auth-loader.mdx @@ -13,8 +13,6 @@ You can use the `rootAuthLoader()` in two different ways: - [Without a callback](#without-a-callback), which will just return the auth state - [With a callback function](#with-a-callback) to handle custom data loading while having access to auth state -You can also [pass configuration options](#pass-configuration-options) to `rootAuthLoader()` no matter which method you use. - ### Without a callback In your `root.tsx` file, add `rootAuthLoader()` to the `loader()` function. If your app doesn't have a `loader()` function yet, you'll need to add it manually. @@ -44,24 +42,3 @@ export async function loader(args: Route.LoaderArgs) { }) } ``` - -### Pass configuration options - -To pass configuration [options](#root-auth-loader-options) to `rootAuthLoader()`, you can pass an optional argument to the `rootAuthLoader()` function. - -```tsx {{ filename: 'app/root.tsx' }} -import { rootAuthLoader } from '@clerk/react-router/server' -import type { Route } from './+types/root' - -export async function loader(args: Route.LoaderArgs) { - return rootAuthLoader( - args, - ({ request, context, params }) => { - const { sessionId, userId, getToken } = request.auth - // Add logic to fetch data - return { yourData: 'here' } - }, - { signInUrl: '/sign-in' }, // Options - ) -} -``` From 68e2c3fe77b51e7cfc14c62e92ace8b3aa04013e Mon Sep 17 00:00:00 2001 From: wobsoriano Date: Thu, 2 Oct 2025 15:40:42 -0700 Subject: [PATCH 11/12] Add back root auth loader options --- docs/_partials/root-auth-loader.mdx | 99 +++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 docs/_partials/root-auth-loader.mdx diff --git a/docs/_partials/root-auth-loader.mdx b/docs/_partials/root-auth-loader.mdx new file mode 100644 index 0000000000..c449ac391a --- /dev/null +++ b/docs/_partials/root-auth-loader.mdx @@ -0,0 +1,99 @@ +The `rootAuthLoader()` function accepts an optional object. The following options are available: + + + - `audience?` + - `string | string[]` + + A string or list of [audiences](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3). If passed, it is checked against the `aud` claim in the token. + + --- + + - `authorizedParties?` + - `string[]` + + An allowlist of origins to verify against, to protect your application from the subdomain cookie leaking attack. For example: `['http://localhost:3000', 'https://example.com']` + + --- + + - `domain?` + - `string` + + The domain used for satellites to inform Clerk where this application is deployed. + + --- + + - `isSatellite?` + - `boolean` + + When using Clerk's satellite feature, this should be set to `true` for secondary domains. + + --- + + - `jwtKey` + - `string` + + Used to verify the session token in a networkless manner. Supply the **JWKS Public Key** from the [**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#api-and-sdk-configuration) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). + + --- + + - `proxyUrl?` + - `string` + + Specify the URL of the proxy, if using a proxy. + + --- + + - `publishableKey` + - `string` + + The Clerk Publishable Key for your instance. This can be found in the **[**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page -> Show Publishable Key** section in the Clerk Dashboard. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys) instead. + + --- + + - `secretKey?` + - `string` + + The Clerk Secret Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys) instead. + + --- + + - `signInUrl` + - `string` + + This URL will be used for any redirects that might happen and needs to point to your primary application on the client-side. This option is optional for production instances. **It is required to be set for a satellite application in a development instance.** It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. + + --- + + - `signUpUrl` + - `string` + + This URL will be used for any redirects that might happen and needs to point to your primary application on the client-side. This option is optional for production instances but **must be set for a satellite application in a development instance.** It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. + + --- + + - `signInFallbackRedirectUrl?` + - `string` + + The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Defaults to `/`. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. + + --- + + - `signUpFallbackRedirectUrl?` + - `string` + + The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Defaults to `/`. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. + + --- + + - `signInForceRedirectUrl?` + - `string` + + If provided, this URL will always be redirected to after the user signs in. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. + + --- + + - `signUpForceRedirectUrl?` + - `string` + + If provided, this URL will always be redirected to after the user signs up. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. + From ecdc3cead2339343bcf157c351e51a520d9c1b84 Mon Sep 17 00:00:00 2001 From: Alexis Aguilar <98043211+alexisintech@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:48:46 -0400 Subject: [PATCH 12/12] updates --- docs/_partials/organization-sync-options.mdx | 68 +++++++++++++++ .../quickstart.react-router.mdx | 82 +++++++++++++++++-- docs/reference/astro/clerk-middleware.mdx | 4 + docs/reference/express/clerk-middleware.mdx | 4 + docs/reference/nextjs/clerk-middleware.mdx | 69 +--------------- docs/reference/nuxt/clerk-middleware.mdx | 8 ++ .../react-router/clerk-middleware.mdx | 8 +- 7 files changed, 167 insertions(+), 76 deletions(-) create mode 100644 docs/_partials/organization-sync-options.mdx diff --git a/docs/_partials/organization-sync-options.mdx b/docs/_partials/organization-sync-options.mdx new file mode 100644 index 0000000000..1dc9e50a29 --- /dev/null +++ b/docs/_partials/organization-sync-options.mdx @@ -0,0 +1,68 @@ +The `organizationSyncOptions` property on the [`clerkMiddleware()`](#clerk-middleware-options) options +object has the type `OrganizationSyncOptions`, which has the following properties: + + + - `organizationPatterns` + - [Pattern](#pattern)\[] + + Specifies URL patterns that are organization-specific, containing an organization ID or slug as a path parameter. If a request + matches this path, the organization identifier will be used to set that org as active. + + If the route also matches the `personalAccountPatterns` prop, this prop takes precedence. + + Patterns must have a path parameter named either `:id` (to match a Clerk organization ID) or `:slug` (to match a Clerk organization slug). + + > [!WARNING] + > If the organization can't be activated—either because it doesn't exist or the user lacks access—the previously [active organization](!active-organization) will remain unchanged. Components must detect this case and provide an appropriate error and/or resolution pathway, such as calling `notFound()` or displaying an [``](/docs/reference/components/organization/organization-switcher). + + Common examples: + + - `["/orgs/:slug", "/orgs/:slug/(.*)"]` + - `["/orgs/:id", "/orgs/:id/(.*)"]` + - `["/app/:any/orgs/:slug", "/app/:any/orgs/:slug/(.*)"]` + + --- + + - `personalAccountPatterns` + - [Pattern](#pattern)\[] + + URL patterns for resources that exist within the context of a user's [personal account](/docs/guides/organizations/overview#allow-personal-accounts). + + If the route also matches the `organizationPattern` prop, the `organizationPattern` prop takes precedence. + + Common examples: + + - `["/me", "/me/(.*)"]` + - `["/user/:any", "/user/:any/(.*)"]` + + +### Pattern + +A `Pattern` is a `string` that represents the structure of a URL path. In addition to any valid URL, it may include: + +- Named path parameters prefixed with a colon (e.g., `:id`, `:slug`, `:any`). +- Wildcard token, `(.*)`, which matches the remainder of the path. + +#### Examples + +- `/orgs/:slug` + +| URL | Matches | `:slug` value | +| - | - | - | +| `/orgs/acmecorp` | ✅ | `acmecorp` | +| `/orgs` | ❌ | n/a | +| `/orgs/acmecorp/settings` | ❌ | n/a | + +- `/app/:any/orgs/:id` + +| URL | Matches | `:id` value | +| - | - | - | +| `/app/petstore/orgs/org_123` | ✅ | `org_123` | +| `/app/dogstore/v2/orgs/org_123` | ❌ | n/a | + +- `/personal-account/(.*)` + +| URL | Matches | +| - | - | +| `/personal-account/settings` | ✅ | +| `/personal-account` | ❌ | diff --git a/docs/getting-started/quickstart.react-router.mdx b/docs/getting-started/quickstart.react-router.mdx index 190abb309f..ae873bfc0c 100644 --- a/docs/getting-started/quickstart.react-router.mdx +++ b/docs/getting-started/quickstart.react-router.mdx @@ -91,15 +91,15 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram } satisfies Config ``` - The following code shows how to configure both functions in your `root.tsx` file. If you're using [Clerk's React Router quickstart](https://github.com/clerk/clerk-react-router-quickstart) or the [React Router template](https://reactrouter.com/start/framework/installation), most of this code will already be present. + Then, add the following code to your `root.tsx` file to configure the `clerkMiddleware()` and `rootAuthLoader()` functions. To load additional data or configure options, see the [`clerkMiddleware()`](/docs/reference/react-router/clerk-middleware) reference. - ```tsx {{ filename: 'app/root.tsx', mark: [1, [6, 8]], collapsible: true }} - import { clerkMiddleware, rootAuthLoader } from '@clerk/react-router/server' + ```tsx {{ filename: 'app/root.tsx', mark: [4, [6, 8]], fold: [[1, 3], [10, 71]], collapsible: true }} import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router' import type { Route } from './+types/root' import stylesheet from './app.css?url' + import { clerkMiddleware, rootAuthLoader } from '@clerk/react-router/server' export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()] @@ -182,18 +182,61 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram - [``](/docs/reference/components/user/user-button): Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. - [``](/docs/reference/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/guides/development/clerk-environment-variables) are set for the sign-in URL, this component links to the [Account Portal sign-in page](/docs/guides/customizing-clerk/account-portal#sign-in). - ```tsx {{ filename: 'app/root.tsx' }} - // Other imports - + ```tsx {{ filename: 'app/root.tsx', mark: [44, [46, 58]], fold: [[2, 42], [62, 87]] }} import { ClerkProvider, SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/react-router' + import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router' + import { clerkMiddleware, rootAuthLoader } from '@clerk/react-router/server' + + import type { Route } from './+types/root' + import stylesheet from './app.css?url' + + export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()] + + export const loader = (args: Route.LoaderArgs) => 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 ( + + + + + + + + + {children} + + + + + ) + } + // Pull in the `loaderData` from the `rootAuthLoader()` function export default function App({ loaderData }: Route.ComponentProps) { return ( + // Pass the `loaderData` to the `` component
+ {/* Show the sign-in button when the user is signed out */} + {/* Show the user button when the user is signed in */} @@ -205,7 +248,32 @@ This tutorial assumes that you're using React Router **v7.1.2 or later** in fram ) } - // Rest of the root.tsx code + 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 ( +
+

{message}

+

{details}

+ {stack && ( +
+            {stack}
+          
+ )} +
+ ) + } ``` ## Create your first user diff --git a/docs/reference/astro/clerk-middleware.mdx b/docs/reference/astro/clerk-middleware.mdx index dc3b174e0e..b58376136f 100644 --- a/docs/reference/astro/clerk-middleware.mdx +++ b/docs/reference/astro/clerk-middleware.mdx @@ -99,3 +99,7 @@ export const onRequest = clerkMiddleware((auth, context) => { ## `clerkMiddleware()` options + +### `OrganizationSyncOptions` + + diff --git a/docs/reference/express/clerk-middleware.mdx b/docs/reference/express/clerk-middleware.mdx index e91d957d0f..8fdc929a7e 100644 --- a/docs/reference/express/clerk-middleware.mdx +++ b/docs/reference/express/clerk-middleware.mdx @@ -86,3 +86,7 @@ app.listen(PORT, () => { A flag to enable Clerk's handshake flow, which helps verify the session state when a session JWT has expired. It issues a `307` redirect to refresh the session JWT if the user is still logged in. Defaults to `true`. + +#### `OrganizationSyncOptions` + + diff --git a/docs/reference/nextjs/clerk-middleware.mdx b/docs/reference/nextjs/clerk-middleware.mdx index 9c14fd112d..cac459a113 100644 --- a/docs/reference/nextjs/clerk-middleware.mdx +++ b/docs/reference/nextjs/clerk-middleware.mdx @@ -402,71 +402,4 @@ export default clerkMiddleware( ### `OrganizationSyncOptions` -The `organizationSyncOptions` property on the [`clerkMiddleware()`](#clerk-middleware-options) options -object has the type `OrganizationSyncOptions`, which has the following properties: - - - - `organizationPatterns` - - [Pattern](#pattern)\[] - - Specifies URL patterns that are organization-specific, containing an organization ID or slug as a path parameter. If a request - matches this path, the organization identifier will be used to set that org as active. - - If the route also matches the `personalAccountPatterns` prop, this prop takes precedence. - - Patterns must have a path parameter named either `:id` (to match a Clerk organization ID) or `:slug` (to match a Clerk organization slug). - - > [!WARNING] - > If the organization can't be activated—either because it doesn't exist or the user lacks access—the previously [active organization](!active-organization) will remain unchanged. Components must detect this case and provide an appropriate error and/or resolution pathway, such as calling `notFound()` or displaying an [``](/docs/reference/components/organization/organization-switcher). - - Common examples: - - - `["/orgs/:slug", "/orgs/:slug/(.*)"]` - - `["/orgs/:id", "/orgs/:id/(.*)"]` - - `["/app/:any/orgs/:slug", "/app/:any/orgs/:slug/(.*)"]` - - --- - - - `personalAccountPatterns` - - [Pattern](#pattern)\[] - - URL patterns for resources that exist within the context of a user's [personal account](/docs/guides/organizations/overview#allow-personal-accounts). - - If the route also matches the `organizationPattern` prop, the `organizationPattern` prop takes precedence. - - Common examples: - - - `["/me", "/me/(.*)"]` - - `["/user/:any", "/user/:any/(.*)"]` - - -### Pattern - -A `Pattern` is a `string` that represents the structure of a URL path. In addition to any valid URL, it may include: - -- Named path parameters prefixed with a colon (e.g., `:id`, `:slug`, `:any`). -- Wildcard token, `(.*)`, which matches the remainder of the path. - -#### Examples - -- `/orgs/:slug` - -| URL | Matches | `:slug` value | -| - | - | - | -| `/orgs/acmecorp` | ✅ | `acmecorp` | -| `/orgs` | ❌ | n/a | -| `/orgs/acmecorp/settings` | ❌ | n/a | - -- `/app/:any/orgs/:id` - -| URL | Matches | `:id` value | -| - | - | - | -| `/app/petstore/orgs/org_123` | ✅ | `org_123` | -| `/app/dogstore/v2/orgs/org_123` | ❌ | n/a | - -- `/personal-account/(.*)` - -| URL | Matches | -| - | - | -| `/personal-account/settings` | ✅ | -| `/personal-account` | ❌ | + diff --git a/docs/reference/nuxt/clerk-middleware.mdx b/docs/reference/nuxt/clerk-middleware.mdx index 1be730bed7..b9ac77bda3 100644 --- a/docs/reference/nuxt/clerk-middleware.mdx +++ b/docs/reference/nuxt/clerk-middleware.mdx @@ -180,3 +180,11 @@ Now, let's add authorization-based protection to the example so that you can see + } }) ``` + +## `clerkMiddleware()` options + + + +### `OrganizationSyncOptions` + + diff --git a/docs/reference/react-router/clerk-middleware.mdx b/docs/reference/react-router/clerk-middleware.mdx index 1ed2881f48..247f7efdbf 100644 --- a/docs/reference/react-router/clerk-middleware.mdx +++ b/docs/reference/react-router/clerk-middleware.mdx @@ -10,10 +10,12 @@ The `clerkMiddleware()` helper integrates Clerk authentication into your React R 1. React Router middleware requires opting in via a future flag. Add the following to your `react-router.config.ts` file: - ```ts {{ filename: 'react-router.config.ts' }} + ```ts {{ filename: 'react-router.config.ts', mark: [[6, 8]] }} import type { Config } from '@react-router/dev/config' export default { + // ... + future: { v8_middleware: true, }, @@ -32,3 +34,7 @@ The `clerkMiddleware()` helper integrates Clerk authentication into your React R ## `clerkMiddleware()` options + +### `OrganizationSyncOptions` + +