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.js-backend.mdx b/docs/getting-started/quickstart.js-backend.mdx
index 4c7be4fd79..8fbebf7735 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(args).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..ae873bfc0c 100644
--- a/docs/getting-started/quickstart.react-router.mdx
+++ b/docs/getting-started/quickstart.react-router.mdx
@@ -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'
- ```tsx {{ filename: 'app/root.tsx', mark: [1, [6, 8]], collapsible: true }}
- import { rootAuthLoader } from '@clerk/react-router/ssr.server'
+ export default {
+ // ...
+ future: {
+ v8_middleware: true,
+ },
+ } satisfies Config
+ ```
+
+ 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: [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 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' },
@@ -169,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 */}
@@ -192,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/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..9b4576019b 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 { 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..4a19c97bcb 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,10 +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(
- userId,
- )
+ // Get the Backend User object
+ 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 06289fae50..da2f6f3190 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(args).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(args).users.getUser(userId)
return {
name,
diff --git a/docs/manifest.json b/docs/manifest.json
index a6259f5b79..c2594d7318 100644
--- a/docs/manifest.json
+++ b/docs/manifest.json
@@ -1888,6 +1888,10 @@
"title": "Overview",
"href": "/docs/reference/react-router/overview"
},
+ {
+ "title": "`clerkMiddleware()`",
+ "href": "/docs/reference/react-router/clerk-middleware"
+ },
{
"title": "`rootAuthLoader()`",
"href": "/docs/reference/react-router/root-auth-loader"
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
new file mode 100644
index 0000000000..247f7efdbf
--- /dev/null
+++ b/docs/reference/react-router/clerk-middleware.mdx
@@ -0,0 +1,40 @@
+---
+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', mark: [[6, 8]] }}
+ import type { Config } from '@react-router/dev/config'
+
+ export default {
+ // ...
+
+ future: {
+ v8_middleware: true,
+ },
+ } satisfies Config
+ ```
+
+1. 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
+
+
+
+### `OrganizationSyncOptions`
+
+
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
diff --git a/docs/reference/react-router/root-auth-loader.mdx b/docs/reference/react-router/root-auth-loader.mdx
index ffa39f5605..6440c310de 100644
--- a/docs/reference/react-router/root-auth-loader.mdx
+++ b/docs/reference/react-router/root-auth-loader.mdx
@@ -13,14 +13,12 @@ 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.
```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 +31,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) {
@@ -44,28 +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/ssr.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
- )
-}
-```
-
-## `rootAuthLoader()` options
-
-