--- title: Welcome to Clerk Docs description: Add complete user management to your application in minutes. template: wide lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs sourceFile: /docs/index.mdx --- Find all the guides and resources you need to develop with Clerk. * [Quickstarts & Tutorials](/docs/getting-started/quickstart/overview) * Explore our end-to-end tutorials and getting started guides for different application stacks using Clerk. * {} *** * [UI Components](/docs/reference/components/overview) * Clerk's prebuilt UI components give you a beautiful, fully-functional user management experience in minutes. * {} *** * [SDK Reference](/docs/reference/overview) * Dig into our SDK reference documentation. We have everything you need to get started setting up authentication with Clerk. * {} *** * [Security](/docs/guides/secure/restricting-access) * Account security is the top concern of every feature we build. This documentation lists some of the many protections included with Clerk. * {} * [Quickstarts & Tutorials](/docs/getting-started/quickstart/overview) * Explore our end-to-end tutorials and getting started guides for different application stacks using Clerk. * {} *** * [Views](/docs/reference/views/overview) * Clerk's prebuilt Views give you a beautiful, fully-functional user management experience in minutes. * {} *** * [SDK Reference](/docs/reference/overview) * Dig into our SDK reference documentation. We have everything you need to get started setting up authentication with Clerk. * {} *** * [Security](/docs/guides/secure/restricting-access) * Account security is the top concern of every feature we build. This documentation lists some of the many protections included with Clerk. * {} ## Explore by frontend framework {/* TODO: Keep aligned with /reference/overview */} * [Next.js](/docs/nextjs/getting-started/quickstart) * Easily add secure, beautiful, and fast authentication to Next.js with Clerk. * *** * [React](/docs/react/getting-started/quickstart) * Get started installing and initializing Clerk in a new React + Vite app. * *** * [Astro](/docs/astro/getting-started/quickstart) * Easily add secure and SSR-friendly authentication to your Astro application with Clerk. * *** * [Chrome Extension](/docs/chrome-extension/getting-started/quickstart) * Use the Chrome Extension SDK to authenticate users in your Chrome extension. * *** * [Expo](/docs/expo/getting-started/quickstart) * Use Clerk with Expo to authenticate users in your React Native application. * *** * [Android](/docs/android/getting-started/quickstart) * Use the Clerk Android SDK to authenticate users in your native Android applications. * *** * [iOS](/docs/ios/getting-started/quickstart) * Use the Clerk iOS SDK to authenticate users in your native Apple applications. * *** * [JavaScript](/docs/js-frontend/getting-started/quickstart) * The Clerk JavaScript SDK gives you access to prebuilt components and helpers to make user authentication easier. * *** * [Nuxt](/docs/nuxt/getting-started/quickstart) * Easily add secure, beautiful, and fast authentication to Nuxt with Clerk. * *** * [React Router](/docs/react-router/getting-started/quickstart) * Easily add secure, edge- and SSR-friendly authentication to React Router with Clerk. * *** * [Remix](/docs/remix/getting-started/quickstart) * Easily add secure, edge- and SSR-friendly authentication to Remix with Clerk. * *** * [TanStack React Start (beta)](/docs/tanstack-react-start/getting-started/quickstart) * Easily add secure and SSR-friendly authentication to your TanStack React Start application with Clerk. * *** * [Vue](/docs/vue/getting-started/quickstart) * Get started installing and initializing Clerk in a new Vue + Vite app. * ## Explore by backend framework {/* TODO: Keep aligned with /reference/overview */} * [JS Backend SDK](/docs/js-backend/getting-started/quickstart) * The JavaScript Backend SDK exposes our Backend API resources and low-level authentication utilities for JavaScript environments. * *** * [C#](https://github.com/clerk/clerk-sdk-csharp/blob/main/README.md) * The Clerk C# SDK is a wrapper around our Backend API to make it easier to integrate Clerk into your backend. * *** * [Express](/docs/expressjs/getting-started/quickstart) * Quickly add authentication and user management to your Express application. * *** * [Go](/docs/go/getting-started/quickstart) * The Clerk Go SDK is a wrapper around the Backend API written in Golang to make it easier to integrate Clerk into your backend. * *** * [Fastify](/docs/fastify/getting-started/quickstart) * Build secure authentication and user management flows for your Fastify server. * *** * [Python](https://github.com/clerk/clerk-sdk-python/blob/main/README.md) * The Clerk Python SDK is a wrapper around the Backend API written in Python to make it easier to integrate Clerk into your backend. * *** * [Ruby on Rails](/docs/ruby/getting-started/quickstart) * Integrate authentication and user management into your Ruby application. * ## Explore by feature * [Authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) * Clerk supports multiple authentication strategies so you can implement the strategy that makes sense for your users. * {} *** * [User management](/docs/guides/users/managing) * Complete user management. Add sign up, sign in, and profile management to your application in minutes. * {} *** * [Database integrations](/docs/guides/development/integrations/overview) * Enable Clerk-managed users to authenticate and interact directly with your database with Clerk's integrations. * {} *** * [Customization](/docs/guides/customizing-clerk/appearance-prop/overview) * Clerk's components can be customized to match the look and feel of your application. * {} *** * [Organizations](/docs/guides/organizations/overview) * Organizations are shared accounts, useful for project and team leaders. Members with elevated privileges can manage member access to the Organization's data and resources. * {} *** * [SDKs](/docs/reference/overview) * Clerk's SDKs allow you to call the Clerk server API without having to implement the calls yourself. * {} ## Learn the concepts * [What is Clerk authentication?](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) * Clerk offers multiple authentication strategies to identify legitimate users of your application, and to allow them to make authenticated requests to your backend. * ![](/docs/images/home/what-is-clerk.png){{ dark: '/docs/images/home/what-is-clerk-dark.png' }} *** * [What is the "User" object?](/docs/guides/users/managing) * The User object contains all account information that describes a user of your app in Clerk. Users can authenticate and manage their accounts, update their personal and contact info, or set up security features for their accounts. * ![](/docs/images/home/user-object.png){{ dark: '/docs/images/home/user-object-dark.png' }} *** * [How do Organizations work?](/docs/guides/organizations/overview) * Organizations allow members to collaborate across shared resources. Each member of an Organization needs to have a user account in your application. All Organization members have access to most of the Organization resources, but some members can take advantage of administrative features. * ![](/docs/images/home/organizations.png){{ dark: '/docs/images/home/organizations-dark.png' }} * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: Pin a Clerk SDK description: Learn how to pin a Clerk SDK to a specific version. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/pinning sourceFile: /docs/pinning.mdx --- Dependency pinning allows you to specify exact package versions in your project, ensuring consistent behavior across different environments and preventing unexpected updates from breaking your application. Typically, package managers use semantic versioning ([SemVer](https://semver.org/)) ranges when installing packages. When you install your Clerk SDK, you'll typically see an entry like `"@clerk/nextjs": "^1.1.0"` in your package.json. The caret (^) symbol means "any version that is compatible with 1.1.0" - this includes patch releases (1.1.1, 1.1.2) and minor releases (1.2.0, 1.3.0) but excludes major releases (2.0.0). Another range operator is the tilde (~) symbol for more restrictive versioning. An entry like `"@clerk/nextjs": "~1.1.0"` means "any version from 1.1.0 up to (but not including) 1.2.0" - this only allows patch updates within the same minor version. When you **pin a dependency**, you specify the exact version **without any range operators**. For example, `"@clerk/nextjs": "1.1.0"` means "use exactly version 1.1.0, no other version." This approach gives you complete control over which version your application uses. With Clerk, we recommend pinning your Clerk SDK in **both** of these ways: 1. Pin your Clerk SDK in your `package.json` file to a specific version (no range operators). ```json {{ filename: 'package.json', prettier: false }} "@clerk/nextjs": "1.1.0" ``` 2. Set the `clerkJsVersion` property when you initialize the Clerk integration. For most SDKs, this is done in the `` component. For SDKs like Astro or Nuxt, this is done in the configuration file. ```tsx {{ prettier: false }} ``` --- title: Maintenance Mode description: Learn about Clerk's Maintenance Mode. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/maintenance-mode sourceFile: /docs/maintenance-mode.mdx --- > \[!IMPORTANT] > Maintenance mode will be deprecated in 2025 as we upgrade our infrastructure. Once or twice per year, Clerk undergoes maintenance on its infrastructure and enters **Maintenance Mode**. During this time, users who are already signed in will not be signed out, and will continue to have access to your app. However, new sign-ups, sign-ins and user mutations will return an error. **Maintenance Mode** is a special operational state designed to minimize disruption for signed-in users during critical database upgrades or outages. ## Production instances Mutation methods (`POST`, `PATCH`, `PUT`, `DELETE`) will be rejected with a `SystemUnderMaintenance` error. This includes all new sign-ups and sign-ins. Active sessions, and session refresh requests **are not** affected. This applies to `GET` requests as well as session refresh requests ([`/touch`](/docs/reference/frontend-api/tag/sessions/post/v1/client/sessions/\{session_id}/touch) and [`/tokens`](/docs/reference/frontend-api/tag/sessions/post/v1/client/sessions/\{session_id}/tokens) endpoints). Users who are already signed in will not be signed out and will continue to have access to your app. However, any mutations to their user or org data will return the same `SystemUnderMaintenance` error. ### API errors All mutations from both the Frontend API and the Backend API will return the following `SystemUnderMaintenance` error. ```json // 503 StatusServiceUnavailable { "shortMessage": "System under maintenance", "longMessage": "We are currently undergoing maintenance and only essential operations are permitted. We will be back shortly.", "code": "maintenance_mode" } ``` ### UI components During **Maintenance Mode**, Clerk's UI components will display the following error for sign-ins, sign-ups, and all mutations to user and org data. ![The \ component with a maintenance mode error.](/docs/images/maintenance-mode/maintenance-mode-error-sm.png) ## Development instances For development instances, all requests will return a `SystemUnderMaintenance ` error, and the instance will be completely unavailable. --- title: JavaScript Backend SDK description: The JavaScript Backend SDK exposes Clerk's Backend API resources and low-level authentication utilities for JavaScript environments. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: js-backend sourceFile: /docs/getting-started/quickstart.js-backend.mdx --- [Clerk's JavaScript Backend SDK](/docs/reference/backend/overview) exposes the [Backend API](/docs/reference/backend-api){{ target: '_blank' }} resources and low-level authentication utilities **for JavaScript environments**. For example, if you wanted to get a list of all users in your application, instead of creating a fetch to [`https://api.clerk.com/v1/users`](/docs/reference/backend-api/tag/users/get/users){{ target: '_blank' }} endpoint, you can use the [`users.getUserList()`](/docs/reference/backend/user/get-user-list) method provided by the JS Backend SDK. ## Installation If you are using the JS Backend SDK on its own, you can install it using the following command: ```npm {{ filename: 'terminal' }} npm install @clerk/backend ``` Clerk SDKs expose an instance of the JS Backend SDK for use in server environments, so there is no need to install it separately. ## Usage All resource operations are mounted as sub-APIs on the `clerkClient` object. For example, if you would like to get a list of all of your application's users, you can use the `getUserList()` method on the `users` sub-API. You can find the full list of available sub-APIs and their methods in the sidenav. To access a resource, you must first instantiate a `clerkClient` instance. To instantiate a `clerkClient` instance, you must call `createClerkClient()` and pass in options. > \[!NOTE] > This example uses `process.env` to import environment variables. You may need to use an alternative method, such as `import.meta.env`, to set environment variables for your project. ```ts import { createClerkClient } from '@clerk/backend' const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) ``` ### Instantiate a default `clerkClient` instance You can use the default instance of `clerkClient` provided by whichever SDK you are using, and skip the need to pass configuration options, unless you are using Remix. For Remix, see the following section. To use the default `clerkClient` instance, set your `CLERK_SECRET_KEY` [environment variable](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys) and then import the `clerkClient` instance from the SDK as shown in the following example: ```jsx import { clerkClient } from '@clerk/nextjs/server' ``` ```js import { clerkClient } from '@clerk/astro/server' ``` ```js import { clerkClient } from '@clerk/express' ``` ```jsx import { clerkClient } from '@clerk/fastify' ``` ```js import { clerkClient } from '@clerk/nuxt/server' ``` If you are using React Router, see the following section for how to instantiate `clerkClient`. If you are using Remix, see the following section for how to instantiate `clerkClient`. ```js import { clerkClient } from '@clerk/tanstack-react-start/server' ``` ### Instantiate a custom `clerkClient` instance If you would like to customize the behavior of the JS Backend SDK, you can instantiate a `clerkClient` instance yourself by calling `createClerkClient()` and passing in options. ```jsx import { createClerkClient } from '@clerk/nextjs/server' const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) const client = await clerkClient() const userList = await client.users.getUserList() ``` If you are using Astro, you must pass the [endpoint context](https://docs.astro.build/en/reference/api-reference/#endpoint-context) when invoking the `clerkClient` function. ```jsx import { clerkClient } from '@clerk/astro/server' export async function GET(context) { const { isAuthenticated, userId, redirectToSignIn } = context.locals.auth() if (!isAuthenticated) { return redirectToSignIn() } const user = await clerkClient(context).users.getUser(userId) return new Response(JSON.stringify({ user })) } ``` ```js import { createClerkClient } from '@clerk/express' const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) const userList = await clerkClient.users.getUserList() ``` ```jsx import { createClerkClient } from '@clerk/fastify' const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) const userList = await clerkClient.users.getUserList() ``` ```tsx {{ filename: 'server/api/users/index.ts' }} import { createClerkClient } from '@clerk/nuxt/server' export default defineEventHandler(async () => { const config = useRuntimeConfig() const clerkClient = createClerkClient({ secretKey: config.clerk.secretKey }) const userList = await clerkClient.users.getUserList() return { userList } }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { createClerkClient } from '@clerk/react-router/api.server' export async function loader(args: Route.LoaderArgs) { const userList = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY, }).users.getUserList() return { userList: JSON.stringify(userList), } } export default function Users({ loaderData }: Route.ComponentProps) { return (

List of users

                {JSON.stringify(loaderData, null, 2)}
              
) } ```
If you are using Remix, you must instantiate `clerkClient` by calling the `createClerkClient()` function and passing in options. ```jsx import { createClerkClient } from '@clerk/remix/api.server' ``` Use the following tabs to see examples of how to use the JS Backend SDK in Remix Loader and Action functions. ```tsx {{ filename: 'routes/profile.tsx' }} import { LoaderFunction, redirect } from '@remix-run/node' import { getAuth } from '@clerk/remix/ssr.server' import { createClerkClient } from '@clerk/remix/api.server' export const loader: LoaderFunction = async (args) => { // Use getAuth to retrieve user data const { isAuthenticated, userId } = await getAuth(args) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } // Initialize clerkClient and perform the action, // which in this case is to get the user const user = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }).users.getUser( userId, ) // Return the user return { serialisedUser: JSON.stringify(user) } } ``` ```tsx {{ filename: 'routes/profile.tsx' }} import { ActionFunction, redirect } from '@remix-run/node' import { getAuth } from '@clerk/remix/ssr.server' import { createClerkClient } from '@clerk/remix/api.server' export const action: ActionFunction = async (args) => { // Use getAuth to retrieve user data const { isAuthenticated, userId } = await getAuth(args) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } // Initialize clerkClient and perform the action, // which in this case is to get the user const user = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }).users.getUser( userId, ) // Return the user return { serialisedUser: JSON.stringify(user) } } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { clerkClient } from '@clerk/tanstack-react-start/server' import { json } from '@tanstack/react-start' import { createServerFileRoute } from '@tanstack/react-start/server' export const ServerRoute = createServerFileRoute().methods({ GET: async ({ request, params }) => { const userList = await clerkClient({ secretKey: import.meta.env.CLERK_SECRET_KEY, }).users.getUserList() return json({ userList }) }, }) ```
## Error handling JS Backend SDK functions throw errors (`ClerkAPIResponseError`) when something goes wrong. You'll need to catch them in a `try/catch` block and handle them gracefully. For example: ```ts {{ filename: 'example.ts' }} try { const res = await someBackendApiCall() } catch (error) { // Error handling } ``` ## `createClerkClient({ options })` The `createClerkClient()` function requires an `options` object. It is recommended to set these options as [environment variables](/docs/guides/development/clerk-environment-variables#api-and-sdk-configuration) where possible, and then pass them to the function. For example, you can set the `secretKey` option using the `CLERK_SECRET_KEY` environment variable, and then pass it to the function like this: `createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })`. The following options are available: * `secretKey` (required) * `string` The Clerk Secret Key from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `jwtKey?` * `string` The **JWKS Public Key** from the [**API keys**](https://dashboard.clerk.com/~/api-keys) in the Clerk Dashboard. For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). *** * `publishableKey?` * `string` The Clerk Publishable Key from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `domain?` * `string` The domain of a [satellite application](/docs/guides/dashboard/dns-domains/satellite-domains) in a multi-domain setup. *** * `isSatellite?` * `boolean` Whether the instance is a satellite domain in a multi-domain setup. Defaults to `false`. *** * `proxyUrl?` * `string` The proxy URL from a multi-domain setup. *** * `sdkMetadata?` * `{ name: string, version: string }` Metadata about the SDK. *** * `telemetry?` * `{ disabled: boolean, debug: boolean }` [Telemetry](/docs/guides/how-clerk-works/security/clerk-telemetry) configuration. *** * `userAgent?` * `string` The User-Agent request header passed to the Clerk API. *** * `apiUrl?` * `string` The [Clerk Backend API](/docs/reference/backend-api){{ target: '_blank' }} endpoint. Defaults to `'https://api.clerk.com'`. *** * `apiVersion?` * `string` The version passed to the Clerk API. Defaults to `'v1'`. *** * `audience?` * `string | string[]` A string or list of [audiences](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3). *** * `taskUrls?` * `Record` The URL paths users are redirected to after sign-up or sign-in when specific session tasks need to be completed. For example, `{ 'choose-organization': '/onboarding/choose-organization' }` redirects users to `/onboarding/choose-organization` after sign-up if they need to choose an Organization. ## Get the `userId` and other properties The [`Auth`](/docs/reference/backend/types/auth-object) object contains important information like the current user's session ID, user ID, and Organization ID. {/* How to access the `Auth` object */} The `Auth` object is available on the `request` object in server contexts. Some frameworks provide a helper that returns the `Auth` object. See the following table for more information. | Framework | How to access the `Auth` object | | - | - | | Next.js App Router | auth() | | Next.js Pages Router | getAuth() | | Astro | locals.auth() | | Express | req.auth | | React Router | getAuth() | | Remix | getAuth() | | Tanstack React Start | auth() | | Other | `request.auth` | The following example demonstrates how to retrieve the authenticated user's ID using `request.auth` when you're not using a specific framework helper. It also shows how to use the JS Backend SDK's [`getUser()`](/docs/reference/backend/user/get-user) method to get the [Backend `User` object](/docs/reference/backend/types/backend-user). ```js import { createClerkClient } from '@clerk/backend' const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) async function getUserId(request) { // Use the `request.auth` object to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = request.auth // If user isn't authenticated, return null if (!isAuthenticated) { return null } // Use the JS Backend SDK's `getUser()` method to get the Backend User object const user = await clerkClient.users.getUser(userId) // Return the Backend User object return user } ``` The following examples demonstrate how to retrieve the authenticated user's ID using framework-specific auth helpers and how to use the JS Backend SDK's [`getUser()`](/docs/reference/backend/user/get-user) method to get the [Backend `User` object](/docs/reference/backend/types/backend-user). **If your SDK isn't listed, you can use the comments in the example to help you adapt it to your SDK.** {/* TODO: The following Tabs example is duplicated in the guides/how-clerk-works/session-tokens.mdx file. It cannot be a partial to be reused across both files because this example includes a partial and partials cannot include partials. Also, the text in each of these tabs is removed in the other file as its not relevant to that file's example. So keep these two Tabs examples in sync please. */} For Next.js, the `Auth` object is accessed using the `auth()` helper in App Router apps and the `getAuth()` function in Pages Router apps. Learn more about using these helpers. Use the following tabs to see examples of how to use these helpers to access the user's ID in your App Router or Pages Router app. ```tsx {{ filename: 'app/api/example/route.ts' }} import { auth, clerkClient } from '@clerk/nextjs/server' export async function GET() { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await auth() // Protect the route by checking if the user is signed in if (!isAuthenticated) { return new NextResponse('Unauthorized', { status: 401 }) } const client = await clerkClient() // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const user = await client.users.getUser(userId) // Return the Backend User object return NextResponse.json({ user: user }, { status: 200 }) } ``` ```tsx {{ filename: 'pages/api/auth.ts' }} import { getAuth, clerkClient } from '@clerk/nextjs/server' import type { NextApiRequest, NextApiResponse } from 'next' export default async function handler(req: NextApiRequest, res: NextApiResponse) { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(req) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return res.status(401).json({ error: 'Unauthorized' }) } // Initialize the JS Backend SDK const client = await clerkClient() // Get the user's full Backend User object const user = await client.users.getUser(userId) return res.status(200).json({ user }) } ``` For Astro, the `Auth` object is accessed using the `locals.auth()` function. Learn more about using `locals.auth()`. ```tsx {{ filename: 'src/api/example.ts' }} import { clerkClient } from '@clerk/astro/server' import type { APIRoute } from 'astro' export const GET: APIRoute = async (context) => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = context.locals.auth() // Protect the route by checking if the user is signed in if (!isAuthenticated) { return new Response('Unauthorized', { status: 401 }) } // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const user = await clerkClient(context).users.getUser(userId) // Return the Backend User object return new Response(JSON.stringify({ user })) } ``` For Express, the `Auth` object is accessed using the `getAuth()` function. Learn more about using `getAuth()`. ```js {{ filename: 'index.js' }} import { createClerkClient, getAuth } from '@clerk/express' import express from 'express' const app = express() const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) app.get('/user', async (req, res) => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = getAuth(req) // Protect the route by checking if the user is signed in if (!isAuthenticated) { res.status(401).json({ error: 'User not authenticated' }) } // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart // Use the `getUser()` method to get the Backend User object const user = await clerkClient.users.getUser(userId) // Return the Backend User object res.json(user) }) ``` For React Router, the `Auth` object is accessed using the `getAuth()` function. Learn more about using `getAuth()`. ```tsx {{ filename: 'app/routes/profile.tsx' }} import { redirect } from 'react-router' import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await getAuth(args) // Protect the route by checking if the user is signed in if (!isAuthenticated) { 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 clerkClient(args).users.getUser(userId) // Return the Backend User object return { user: JSON.stringify(user), } } ``` For Tanstack React Start, the `Auth` object is accessed using the `auth()` function. Learn more about using `auth()`. ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { auth, clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { GET: async () => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await auth() // Protect the route by checking if the user is signed in if (!isAuthenticated) { return json({ error: 'Unauthorized' }, { status: 401 }) } // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart // Use the `getUser()` method to get the Backend User object const user = await clerkClient().users.getUser(userId) // Return the Backend User object return json({ user }) }, }, }, }) ``` --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: js-backend sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. > \[!NOTE] > To see an example of how to create a pricing table page, please select one of the frontend SDKs on the sidebar. ## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the [`has()`](/docs/reference/backend/types/auth-object#has) method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The [`has()`](/docs/reference/backend/types/auth-object#has) method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the [`auth` object](/docs/reference/backend/types/auth-object), which you will access differently [depending on the framework you are using](/docs/reference/backend/types/auth-object#how-to-access-the-auth-object). > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```ts {{ filename: 'src/routes/bronze-content.ts' }} import { createClerkClient } from '@clerk/backend' const clerkClient = createClerkClient({ publishableKey: process.env.CLERK_PUBLISHABLE_KEY, secretKey: process.env.CLERK_SECRET_KEY, }) const domain = process.env.NODE_ENV === 'production' ? 'https://example.com' : 'http://localhost:3000' export async function GET(request: Request) { const authenticatedRequest = await clerkClient.authenticateRequest(request, { authorizedParties: [domain], }) const user = authenticatedRequest.toAuth() if (user === null || user.userId === null) { return new Response('Unauthorized', { status: 401 }) } const hasBronzePlan = user.has({ plan: 'bronze' }) if (!hasBronzePlan) { return new Response('For Bronze subscribers only') } return new Response('Only subscribers to the Bronze plan can access this content.') } ``` The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```ts {{ filename: 'src/routes/premium-content.ts' }} import { createClerkClient } from '@clerk/backend' const clerkClient = createClerkClient({ publishableKey: process.env.CLERK_PUBLISHABLE_KEY, secretKey: process.env.CLERK_SECRET_KEY, }) const domain = process.env.NODE_ENV === 'production' ? 'https://example.com' : 'http://localhost:3000' export async function GET(request: Request) { const authenticatedRequest = await clerkClient.authenticateRequest(request, { authorizedParties: [domain], }) const user = authenticatedRequest.toAuth() if (user === null || user.userId === null) { return new Response('Unauthorized', { status: 401 }) } const hasPremiumAccess = user.has({ feature: 'premium_access' }) if (!hasPremiumAccess) { return new Response('Only subscribers with the Premium Access feature can access this content.') } return new Response('Our Exclusive Content') } ``` The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```ts {{ filename: 'src/routes/manage-premium-content.ts' }} import { createClerkClient } from '@clerk/backend' const clerkClient = createClerkClient({ publishableKey: process.env.CLERK_PUBLISHABLE_KEY, secretKey: process.env.CLERK_SECRET_KEY, }) const domain = process.env.NODE_ENV === 'production' ? 'https://example.com' : 'http://localhost:3000' export async function GET(request: Request) { const authenticatedRequest = await clerkClient.authenticateRequest(request, { authorizedParties: [domain], }) const user = authenticatedRequest.toAuth() if (user === null || user.userId === null) { return new Response('Unauthorized', { status: 401 }) } const hasPremiumAccessManage = user.has({ permission: 'org:premium_access:manage' }) if (!hasPremiumAccessManage) { return new Response( 'Only subscribers with the Premium Access Manage permission can access this content.', ) } return new Response('Our Exclusive Content') } ``` ### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. --- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: js-backend sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. > \[!NOTE] > To see an example of how to create a pricing table page, please select one of the frontend SDKs on the sidebar. ## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the [`has()`](/docs/reference/backend/types/auth-object#has) method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The [`has()`](/docs/reference/backend/types/auth-object#has) method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the [`auth` object](/docs/reference/backend/types/auth-object), which you will access differently [depending on the framework you are using](/docs/reference/backend/types/auth-object#how-to-access-the-auth-object). The following example demonstrates how to use `has()` to check if a user has a Plan. ```ts {{ filename: 'src/routes/bronze-content.ts' }} import { createClerkClient } from '@clerk/backend' const clerkClient = createClerkClient({ publishableKey: process.env.CLERK_PUBLISHABLE_KEY, secretKey: process.env.CLERK_SECRET_KEY, }) const domain = process.env.NODE_ENV === 'production' ? 'https://example.com' : 'http://localhost:3000' export async function GET(request: Request) { const authenticatedRequest = await clerkClient.authenticateRequest(request, { authorizedParties: [domain], }) const user = authenticatedRequest.toAuth() if (user === null || user.userId === null) { return new Response('Unauthorized', { status: 401 }) } const hasBronzePlan = user.has({ plan: 'bronze' }) if (!hasBronzePlan) { return new Response('For Bronze subscribers only') } return new Response('Only subscribers to the Bronze plan can access this content.') } ``` The following example demonstrates how to use `has()` to check if a user has a Feature. ```ts {{ filename: 'src/routes/premium-content.ts' }} import { createClerkClient } from '@clerk/backend' const clerkClient = createClerkClient({ publishableKey: process.env.CLERK_PUBLISHABLE_KEY, secretKey: process.env.CLERK_SECRET_KEY, }) const domain = process.env.NODE_ENV === 'production' ? 'https://example.com' : 'http://localhost:3000' export async function GET(request: Request) { const authenticatedRequest = await clerkClient.authenticateRequest(request, { authorizedParties: [domain], }) const user = authenticatedRequest.toAuth() if (user === null || user.userId === null) { return new Response('Unauthorized', { status: 401 }) } const hasPremiumAccess = user.has({ feature: 'premium_access' }) if (!hasPremiumAccess) { return new Response('Only subscribers with the Premium Access feature can access this content.') } return new Response('Our Exclusive Content') } ``` ### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: js-backend sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: js-backend sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: Ruby Quickstart description: Learn how to use Clerk to quickly and easily add secure authentication and user management to your Ruby application. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: ruby sourceFile: /docs/getting-started/quickstart.ruby.mdx --- Learn how to use Clerk to quickly and easily add secure authentication and user management to your Ruby app. If you would like to use a framework, see the [reference docs](/docs/reference/ruby/overview). ## Install `clerk-sdk-ruby` The [Clerk Ruby SDK](/docs/reference/ruby/overview) provides a range of backend utilities to simplify user authentication and management in your application. 1. Add the following code to your application's `Gemfile`. ```ruby {{ filename: 'Gemfile' }} gem 'clerk-sdk-ruby', require: "clerk" ``` 2. Run the following command to install the SDK: ```sh {{ filename: 'terminal' }} $ bundle install ``` ## Configuration The configuration object provides a flexible way to configure the SDK. When a configuration value is not explicitly provided, it will fall back to checking the corresponding [environment variable](/docs/reference/ruby/overview#available-environment-variables). You must provide your Clerk Secret Key, which can be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The following example shows how to set up your configuration object: ```ruby Clerk.configure do |c| c.secret_key = `{{secret}}` # if omitted: ENV["CLERK_SECRET_KEY"] - API calls will fail if unset c.logger = Logger.new(STDOUT) # if omitted, no logging end ``` For more information, see [Faraday's documentation](https://lostisland.github.io/faraday/#/). ## Instantiate a `Clerk::SDK` instance All available methods are listed in the [Ruby HTTP Client documentation](https://github.com/clerk/clerk-http-client-ruby/tree/main/.generated#documentation-for-api-endpoints){{ target: '_blank' }}. The Ruby HTTP Client is a generated wrapper around the [Backend API](/docs/reference/backend-api){{ target: '_blank' }} that provides a more Ruby-friendly interface. To access available methods, you must instantiate a `Clerk::SDK` instance. ```ruby sdk = Clerk::SDK.new create_user_request = Clerk::SDK::CreateUserRequest.new( first_name: "John", last_name: "Doe", email_address: ["john.doe@example.com"], password: "password" ) # Create a user sdk.users.create(create_user_request) # List all users and ensure the user was created sdk.users.get_user_list # Get the first user created in your instance user = sdk.users.get_user_list(limit: 1).first # Use the user's ID to lock the user sdk.users.lock_user(user["id"]) # Then, unlock the user so they can sign in again sdk.users.unlock_user(user["id"]) ``` ## Next steps * [Ruby SDK Reference](/docs/reference/ruby/overview) * Learn more about the Ruby SDK. *** * [Deploy to Production](/docs/guides/development/deployment/production) * Learn how to deploy your Clerk app to production. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: ruby sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: Vue Quickstart description: Add authentication and user management to your Vue app with Clerk. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: vue sourceFile: /docs/getting-started/quickstart.vue.mdx --- This tutorial assumes that you're using [Vue 3](https://vuejs.org/) with [TypeScript](https://www.typescriptlang.org/). ### Create a Vue app using Vite Run the following commands to create a new Vue app using [Vite](https://vitejs.dev/guide/#scaffolding-your-first-vite-project): ```npm npm create vite@latest clerk-vue -- --template vue-ts cd clerk-vue npm install npm run dev ``` ### Install `@clerk/vue` The [Clerk Vue SDK](/docs/reference/vue/overview) gives you access to prebuilt components, composables, and helpers to make user authentication easier. Run the following command to install the SDK: ```npm npm install @clerk/vue ``` ### Set your Clerk API keys Add your Clerk Publishable Key to your `.env` file. This key can always be retrieved from the [**API Keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API Keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, copy your Clerk Publishable Key. 3. Paste your key into your `.env` file. The final result should resemble the following: ```env {{ filename: '.env' }} VITE_CLERK_PUBLISHABLE_KEY={{pub_key}} ``` ### Add `clerkPlugin` to your app `clerkPlugin` provides session and user context to Clerk's components and composables. It's required to pass your Clerk Publishable Key as an option. You can add an `if` statement to check that the key is imported properly. This prevents the app from running without the Publishable Key and catches TypeScript errors. The `clerkPlugin` accepts optional options, such as `{ signInForceRedirectUrl: '/dashboard' }`. See the [reference documentation](/docs/reference/vue/clerk-plugin) for more information. ```ts {{ filename: 'src/main.ts', mark: [4, [12, 14]] }} import { createApp } from 'vue' import './style.css' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Add your Clerk Publishable Key to the .env file') } const app = createApp(App) app.use(clerkPlugin, { publishableKey: PUBLISHABLE_KEY }) app.mount('#app') ``` ### Create a header with Clerk components You can control which content signed-in and signed-out users can see with Clerk's prebuilt control components. The following example creates a header using the following components: * \: Children of this component can only be seen while **signed in**. * \: Children of this component can only be seen while **signed out**. * \: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. * \: An unstyled component that links to the sign-in page or displays the sign-in modal. ```vue {{ filename: 'src/App.vue', mark: [2, [6, 13]] }} ``` ### Create your first user Run your project with the following command: ```npm npm run dev ``` Visit your app's homepage at [`http://localhost:5173`](http://localhost:5173). Sign up to create your first user. ## More resources Learn more about Clerk components, how to customize them, and how to use Clerk's client-side helpers using the following guides. * [Prebuilt components](/docs/reference/components/overview) * Learn more about Clerk's suite of components that let you quickly add authentication to your app. *** * [Customization & localization](/docs/guides/customizing-clerk/appearance-prop/overview) * Learn how to customize and localize Clerk components. *** * [Client-side helpers (composables)](/docs/reference/composables/use-user) * Learn more about Clerk's client-side helpers and how to use them. --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: vue sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```vue {{ filename: 'pages/pricing.vue' }} ``` ## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```vue {{ filename: 'src/bronze-content.vue' }} ``` The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```vue {{ filename: 'src/premium-content.vue' }} ``` The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```vue {{ filename: 'src/manage-premium-content.vue' }} ``` ### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. ```vue {{ filename: 'src/protected-content.vue' }} ``` The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. ```vue {{ filename: 'src/protected-premium-content.vue' }} ``` The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. ```vue {{ filename: 'src/protected-manage-content.vue' }} ``` --- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: vue sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```vue {{ filename: 'pages/pricing.vue' }} ``` ## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```vue {{ filename: 'src/bronze-content.vue' }} ``` The following example demonstrates how to use `has()` to check if a user has a Feature. ```vue {{ filename: 'src/premium-content.vue' }} ``` ### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. ```vue {{ filename: 'src/protected-content.vue' }} ``` The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. ```vue {{ filename: 'src/protected-premium-content.vue' }} ``` --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: vue sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: vue sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`` component" description: Clerk's component renders a UI for authenticating users with Google's One Tap API. sdk: astro, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/google-one-tap lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: chrome-extension,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/authentication/google-one-tap.mdx --- > \[!IMPORTANT] > To use Google One Tap with Clerk, you must [enable Google as a social connection in the Clerk Dashboard](/docs/guides/configure/auth-strategies/social-connections/google#configure-for-your-production-instance) and make sure to use custom credentials. The `` component renders the [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) UI so that users can use a single button to sign-up or sign-in to your Clerk application with their Google accounts. By default, this component will redirect users back to the page where the authentication flow started. However, you can override this with force redirect URL props or [force redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). > \[!TIP] > `` does not render if the user is already signed into your Clerk application, so there's no need to manually check if a user is signed in yourself before rendering it. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```vue {{ filename: 'sign-in.vue' }} ``` ## Properties * `cancelOnTapOutside?` * `boolean` If `true`, the One Tap prompt closes automatically if the user clicks outside of the prompt. Defaults to `true`. *** * `itpSupport?` * `boolean` If `true`, enables the [ITP-specific UX](https://developers.google.com/identity/gsi/web/guides/itp) when One Tap is rendered on ITP browsers such as Chrome on iOS, Safari, and FireFox. Defaults to `true`. *** * `fedCmSupport?` * `boolean` If `true`, enables Google One Tap to use [the FedCM API](https://developers.google.com/privacy-sandbox/3pcd/fedcm) to sign users in. See Google's docs on [best practices when disabling FedCM support](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap#do_not_cover_google_one_tap). Defaults to `true` *** * `signInForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs in, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). *** * `signUpForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs up, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). ## Limitations * If your application will use the Google API on behalf of your users, the `` component is not recommended, as Google does not provide Clerk with an access or refresh token that you can use. * Users with the 1Password browser extension may not be able to render the Google One Tap UI. They must disable this extension. * When testing in development, if you select the `X` button to close the Google One Tap UI, you may encounter [a cooldown](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown) that prevents you from rendering it again for a period of time. To bypass the cooldown, remove the `g_state` cookie. --- title: "`` component" description: Clerk's component renders a UI for signing in users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/authentication/sign-in.mdx --- ![The \ component renders a UI for signing in users.](/docs/images/ui-components/sign-in.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI to allow users to sign in or sign up by default. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```vue {{ filename: 'sign-in.vue' }} ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `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. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-in`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signUpFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Used for the 'Don't have an account? Sign up' link that's rendered. Defaults to `/`. 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 used as the redirect destination after the user signs up. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signUpUrl` * `string` The full URL or path to the sign-up page. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `transferable` * `boolean` Indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `waitlistUrl` * `string` Full URL or path to the waitlist page. Use this property to provide the target of the 'Waitlist' link that's rendered. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). If you've passed the `waitlistUrl` prop to the \ component, it will infer from that, and you can omit this prop. *** * `withSignUp` * `boolean` Opt into sign-in-or-up flow by setting this prop to `true`. When `true`, if a user does not exist, they will be prompted to sign up. If a user exists, they will be prompted to sign in. Defaults to `true` if the `CLERK_SIGN_IN_URL` environment variable is set. Otherwise, defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for signing up users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/authentication/sign-up.mdx --- ![The \ component renders a UI for signing up users.](/docs/images/ui-components/sign-up.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```vue {{ filename: 'sign-up.vue' }} ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `string` If provided, this URL will always be used as the redirect destination 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. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-up`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signInFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Used for the 'Already have an account? Sign in' link that's rendered. 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. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signInUrl` * `string` The full URL or path to the sign-in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: The component renders a waitlist form that allows users to join for early access to your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/waitlist lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/authentication/waitlist.mdx --- ![The \ component renders a form that allows users to join for early access to your app.](/docs/images/ui-components/waitlist.png){{ style: { maxWidth: '460px' } }} In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. [Learn more about additional features available in **Waitlist** mode](/docs/guides/secure/restricting-access#waitlist). The `` component renders a form that allows users to join for early access to your app. ## Enable Waitlist mode Before using the `` component, you must enable **Waitlist** mode in the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. ## Example > \[!WARNING] > Before using the `` component, you must provide the `waitlistUrl` prop either in the \ or \ component to ensure proper functionality. The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```vue {{ filename: 'waitlist.vue' }} ``` ## Properties All props are optional. * `afterJoinWaitlistUrl` * `string` The full URL or path to navigate to after joining the waitlist. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `signInUrl` * `string` The full URL or path to the sign in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. ## Customization To learn about how to customize Clerk components, see the [customization guide](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component renders a button that opens the checkout drawer for Plan subscriptions. sdk: react, nextjs, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/checkout-button lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react,nextjs,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/billing/checkout-button.mdx --- ![The \ component renders a button that opens the checkout drawer.](/docs/images/ui-components/checkout-button.png) The `` component renders a button that opens the checkout drawer when selected, allowing users to subscribe to a Plan for either their Personal Account or an Organization. It must be wrapped inside a \ component to ensure the user is authenticated. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. ## Usage `` must be wrapped inside a \ component to ensure the user is authenticated. ```tsx <> // ❌ This will throw an error // ✅ Correct usage ``` `` will throw an error if the `for` prop is set to `'organization'` and no Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. is set. ```tsx <> // ❌ This will throw an error if no Organization is active // ✅ Correct usage {auth.orgId ? : null} ``` `` preserves any click handlers attached to custom button elements, while maintaining the checkout drawer functionality. ```tsx ``` ### Examples ```vue {{ filename: 'pricing.vue' }} ``` ## Properties * `planId` * `string` The ID of the Plan to subscribe to. *** * `planPeriod?` * `'month' | 'annual'` The billing period for the subscription. *** * `for?` * `'user' | 'organization'` Determines whether the subscription is for the current user or Organization. Defaults to `'user'`. *** * `children?` * `React.ReactNode` A custom button element. If not provided, defaults to a button with the text "Checkout". *** * `onSubscriptionComplete?` * `() => void` A callback function that is called when a subscription is successfully completed. *** * `newSubscriptionRedirectUrl?` * `string` The URL to redirect to after a successful subscription. *** * `checkoutProps?` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. For example: ``. --- title: "`` component" description: Clerk's component renders a button that opens the Plan details drawer. sdk: react, nextjs, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/plan-details-button lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react,nextjs,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/billing/plan-details-button.mdx --- ![The \ component renders a button that opens the Plan details drawer.](/docs/images/ui-components/plan-details.png){{ style: { maxWidth: '460px' } }} The `` component renders a button that opens the Plan details drawer, allowing users to view detailed information about a specific Plan, including pricing, Features, and other Plan-specific details. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. ## Usage `` preserves any click handlers attached to custom button elements, while maintaining the Plan details drawer functionality. ```tsx ``` `` supports rendering the Plan details drawer in a custom portal container. ```tsx {{ prettier: false }} const portalRoot = document.getElementById('custom-portal') ``` ### Examples ```vue {{ filename: 'pricing.vue' }} ``` ## Properties * `planId?` * `string` The ID of the Plan to display details for. It is required if `plan` is not provided. *** * `plan?` * BillingPlanResource The Plan to display details for. It is used as initial data until the Plan is fetched from the server. *** * `children?` * `React.ReactNode` Optional custom button element. If not provided, defaults to a button with the text "Plan details". *** * `initialPlanPeriod?` * `'month' | 'annual'` Optional prop to set the initial billing period view when the Plan details drawer opens. *** * `planDetailsProps?` * `{ appearance: Appearance }` Options for the Plan details drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. For example: ``. --- title: "`` component" description: Clerk's component renders a button that opens the subscription details drawer. sdk: react, nextjs, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/subscription-details-button lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react,nextjs,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/billing/subscription-details-button.mdx --- ![The \ component renders a button that opens the subscription details drawer.](/docs/images/ui-components/subscription.png) The `` component renders a button that opens the subscription details drawer when selected, allowing users to view and manage their subscription details, whether for their Personal Account or Organization. It must be wrapped inside a \ component to ensure the user is authenticated. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. ## Usage `` must be wrapped inside a \ component to ensure the user is authenticated. ```tsx <> // ❌ This will throw an error // ✅ Correct usage ``` `` will throw an error if the `for` prop is set to `'organization'` and no Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. is set. ```tsx <> // ❌ This will throw an error if no Organization is active // ✅ Correct usage {auth.orgId ? : null} ``` ### Examples ```vue {{ filename: 'billing.vue' }} ``` ## Properties All props are optional. * `for?` * `'user' | 'organization'` Determines whether to show subscription details for the current user or Organization. Defaults to `'user'`. *** * `children?` * `React.ReactNode` Optional custom button element. If not provided, defaults to a button with the text "Subscription details". *** * `onSubscriptionCancel?` * `() => void` A callback function that is called when a subscription is cancelled. *** * `subscriptionDetailsProps?` * `{ appearance: Appearance }` Options for the subscription details drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. For example: ``. --- title: "``" description: Clerk's component displays a table of Plans and Features that users can subscribe to. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/pricing-table lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/billing/pricing-table.mdx --- ![The \ component displays a table of Plans and Features that users can subscribe to.](/docs/images/ui-components/pricing-table.png) The `` component displays a table of Plans and Features that users can subscribe to. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```vue {{ filename: 'pricing.vue' }} ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `checkoutProps` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `collapseFeatures` * `boolean` A boolean that indicates whether the Features are collapsed. **Requires `layout` to be set to `'default'`**. Defaults to `false`. *** * `ctaPosition` * `'top' | 'bottom'` The placement of the CTA button. **Requires `layout` to be set to `'default'`**. Defaults to `'bottom'`. *** * `fallback` * `JSX` An optional UI to show when the pricing table is loading. *** * `for` * `'user' | 'organization'` A string that indicates whether the pricing table is for users or [Organizations](/docs/guides/organizations/overview). If `'user'`, the pricing table will display a list of Plans and Features that **users** can subscribe to. If `'organization'`, the pricing table will display a list of Plans and Features that **Organizations** can subscribe to. Defaults to `'user'`. *** * `newSubscriptionRedirectUrl` * `string` The URL to navigate to after the user completes the checkout and selects the "Continue" button. --- title: \RedirectCallback /> description: Clerk's `` component is used to implement custom OAuth flows. It handles the OAuth callback and completes the authentication process. sdk: astro, chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/authenticate-with-redirect-callback lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: expo,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/authenticate-with-redirect-callback.mdx --- The `` component is a crucial part of implementing custom OAuth flows in your application. It serves as the callback handler for the authentication process initiated by the `authenticateWithRedirect()` method. Render it on the route specified as the `redirectUrl` in your `authenticateWithRedirect()` call. This component automatically handles the OAuth callback, completing the authentication process and managing the user's session. It uses the handleRedirectCallback() method under the hood. ## Example For an example of how to use the `` component, see the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) guide. ## Properties All props are optional. * `continueSignUpUrl?` * `string | undefined | null` The full URL or path to navigate to if the sign up requires additional information. *** * `signInUrl?` * `string` The full URL or path where the `` component is mounted. *** * `signUpUrl?` * `string` The full URL or path where the `` component is mounted. *** * `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. *** * `firstFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if first factor verification is required. *** * `secondFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) is enabled. *** * `resetPasswordUrl?` * `string` The full URL or path to navigate to during sign in, if the user is required to reset their password. *** * `transferable?` * `boolean` A boolean that indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `verifyEmailAddressUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting email verification. *** * `verifyPhoneNumberUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting phone verification. --- title: "``" description: The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loading lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/clerk-loading.mdx --- The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```vue {{ filename: 'App.vue' }} ``` --- title: "``" description: The Protect component protects content or even entire routes based on authentication, and optionally, authorization. It only renders its children when the current user is signed-in, and if performing authorization checks, if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/protect lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/protect.mdx --- The \ component protects content or even entire routes based on: * authentication: whether the user is signed-in or not. * authorization: whether the user has been granted a specific type of access control (Role, Permission, Feature, or Plan) `` **always** performs authentication checks. To perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., you can pass different props, like `role`, `permission`, `feature`, or `plan`. `` accepts a `fallback` prop that will be rendered if the user fails the authentication or authorization checks. `` can be used both client-side and server-side (in Server Components). > \[!CAUTION] > This component only **visually hides** its children when the current user is not authorized. The contents of its children remain accessible via the browser's source code even if the user fails the authorization check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Usage ### Authentication checks `` always performs authentication checks. It will render its children if the user is signed-in, and its `fallback` prop if the user is signed-out. ```vue ``` ### Authorization checks To limit who is able to see the content that `` renders, you can pass **one** of the access control props: `permission`, `role`, `feature`, or `plan`. It's recommended to use **Permission-based** authorization over **Role-based** authorization, and **Feature-based** authorization over **Plan-based** authorization, as they are more flexible, easier to manage, and more secure. If you do not pass any of the access control props, `` will render its children if the user is signed in, regardless of their Role or its Permissions. For more complex authorization logic, pass conditional logic to the `condition` prop. ### Render content by Permissions The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:invoices:create` Permission. ```vue ``` ### Render content by Role While authorization by `permission` is **recommended**, for convenience, `` allows a `role` prop to be passed. The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:billing` Role. ```vue ``` ### Render content by Plan The following example demonstrates how to use `` to protect content by checking if the user has a Plan. ```vue ``` ### Render content by Feature The following example demonstrates how to use `` to protect content by checking if the user has a Feature. ```vue ``` ### Render content conditionally The following example uses ``'s `condition` prop to conditionally render its children if the user has the correct Role. ```vue ``` ## Properties * `condition?` * `has => boolean` Optional conditional logic that renders the children if it returns `true`. *** * `fallback?` * `JSX` Optional UI to show when a user doesn't have the correct type of access control to access the protected content. *** * `feature?` * `string` Optional string corresponding to a [Feature](/docs/guides/billing/overview). *** * `plan?` * `string` Optional string corresponding to a [Plan](/docs/guides/billing/overview). *** * `permission?` * `string` Optional string corresponding to a [Permission](/docs/guides/organizations/roles-and-permissions) in the format `org::` *** * `role?` * `string` Optional string corresponding to a [Role](/docs/guides/organizations/roles-and-permissions) in the format `org:` *** * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` (deprecated)" description: The component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/redirect-to-create-organization.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToCreateOrganization() method instead. The `` component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```vue {{ filename: 'App.vue' }} ``` --- title: "``" description: The component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/redirect-to-sign-up.mdx --- The `` component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```vue {{ filename: 'App.vue' }} ``` --- title: "`` (deprecated)" description: The component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/redirect-to-organization-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToOrganizationProfile() method instead. The `` component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```vue {{ filename: 'App.vue' }} ``` --- title: "``" description: The component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/redirect-to-sign-in.mdx --- The `` component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```vue {{ filename: 'App.vue' }} ``` --- title: "``" description: The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the Clerk object without the need to check it exists. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loaded lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/clerk-loaded.mdx --- The `` component guarantees that the Clerk object has loaded (the `status` is `'ready'` or `'degraded'`) and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```vue {{ filename: 'App.vue' }} ``` --- title: "``" description: The component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-tasks lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,remix,go,astro,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/redirect-to-tasks.mdx --- The `` component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks**Session tasks** are requirements that users must fulfill in order to complete the authentication process, such as choosing an Organization.. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. The `` component is primarily intended for use in custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. If you're using prebuilt components, you typically won't need to use `` as these components manage task redirection internally. [See the guide on handling session tasks outside of prebuilt components](/docs/guides/configure/session-tasks#redirecting-to-tasks). ## Example ```vue {{ filename: 'App.vue' }} ``` --- title: "``" description: Conditionally render content only when a user is signed in. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/signed-in.mdx --- ## Overview The `` component offers authentication checks as a cross-cutting concern. Any children components wrapped by a `` component will be rendered only if there's a user with an active session signed in your application. > \[!CAUTION] > This component only **visually hides** its children when the current user is not authenticated. The contents of its children remain accessible via the browser's source code even if the user fails the authentication check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Example ```vue {{ filename: 'App.vue' }} ``` ## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` (deprecated)" description: The component will navigate to the user profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/redirect-to-user-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToUserProfile() method instead. The `` component will navigate to the Account Portal User Profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. To find your User Profile URL: 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Under **User profile**, select the **Visit** icon. ## Example ```vue {{ filename: 'App.vue' }} ``` --- title: "``" description: Conditionally render content only when a user is signed out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-out lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/control/signed-out.mdx --- The `` component offers authentication checks as a cross-cutting concern. Any child nodes wrapped by a `` component will be rendered only if there's no User signed in to your application. ## Example ```vue {{ filename: 'App.vue' }} ``` ## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` component" description: Clerk's component is used to render an Organization creation UI that allows users to create brand new Organizations within your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/organization/create-organization.mdx --- ![The \ component renders an Organization creation UI that allows users to create brand new organizations within your application.](/docs/images/ui-components/create-organization.png){{ style: { maxWidth: '492px' } }} The `` component is used to render an Organization creation UI that allows users to create brand new Organizations in your application. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```vue {{ filename: 'create-organization.vue' }} ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterCreateOrganizationUrl` * `string` Full URL or path to navigate to after creating a new organization. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/create-organization`. *** * `skipInvitationScreen` * `boolean` Hides the screen for sending invitations after an Organization is created. When left undefined, Clerk will automatically hide the screen if the number of max allowed members is equal to 1 *** * `hideSlug` * `boolean` Hides the optional slug field in the Organization creation screen. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to display Organization related memberships, invitations, and suggestions for the user. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/organization/organization-list.mdx --- ![The \ component displays Organization-related memberships and automatic invitations and suggestions for the user.](/docs/images/ui-components/organization-list.png){{ style: { maxWidth: '460px' } }} The `` component displays Organization-related memberships and automatic [invitations](/docs/guides/organizations/verified-domains#automatic-invitations) and [suggestions](/docs/guides/organizations/verified-domains#automatic-suggestions) for the user. ## Example ```vue {{ filename: 'organizations.vue' }} ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after creating a new Organization. *** * `afterSelectOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting an Organization. Defaults to `undefined`. *** * `afterSelectPersonalUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting the [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts). Defaults to `undefined`. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. Defaults to `false`. *** * `skipInvitationScreen` * `boolean | undefined` A boolean that controls whether the screen for sending invitations after an Organization is created is hidden. When `undefined`, Clerk will automatically hide the screen if the number of max allowed members is equal to 1. Defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [org-ref]: /docs/reference/javascript/organization --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured Organization management UI that allows users to manage their Organization profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/organization/organization-profile.mdx --- ![The \ component allows users to manage their Organization membership and security settings.](/docs/images/ui-components/organization-profile.png) The `` component allows users to manage their Organization membership, security, and billing settings. This component's **General** tab displays the Organization's information and the **Leave organization** button. Admins will be able to see the **Update profile** button, **Verified domains** section, and **Delete organization** button. The **Members** tab shows the Organization's members along with their join dates and Roles. Admins will have the ability to invite a member, change a member's Role, or remove them from the Organization. Admins will have tabs within the **Members** tab to view the Organization's [invitations](/docs/guides/organizations/overview#organization-invitations) and [requests](/docs/guides/organizations/verified-domains#membership-requests). The **Billing** tab displays the Plans and Features that are available to the Organization, as well as the user's billing information, such as their invoices and payment methods. ## Example ```vue {{ filename: 'organization-profile.vue' }} ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after leaving an Organization. *** * `customPages` * `CustomPages[]` An array of custom pages to add to the Organization profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/organization-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash- and virtual-based routing.
For example: `/organization-profile`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages.
Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React.
## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages](/docs/guides/customizing-clerk/adding-items/organization-profile) documentation. --- title: "`` component" description: Clerk's component is used to enable the ability to switch between available Organizations the user may be part of in your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-switcher lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/organization/organization-switcher.mdx --- ![The \ component allows a user to switch between their account types - their Personal Account and their joined Organizations.](/docs/images/ui-components/organization-switcher.png){{ style: { maxWidth: '436px' } }} The `` component allows a user to switch between their joined Organizations. If [Personal Accounts are enabled](/docs/guides/organizations/overview#allow-personal-accounts), users can also switch to their Personal Account. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple Organizations. It handles all Organization-related flows, including full Organization management for admins. Learn more about [Organizations](/docs/guides/organizations/overview). ## Example ```vue {{ filename: 'organization-switcher.vue' }} ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * `string` The full URL or path to navigate to after creating a new Organization. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after the user leaves the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `afterSelectOrganizationUrl` * `string` The full URL or path to navigate to after a successful Organization switch. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `createOrganizationMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the "Create organization" button will cause the \ component to open as a modal, or if the browser will navigate to the `createOrganizationUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `createOrganizationUrl` * `string` The full URL or path where the ``]createorg-ref component is mounted. *** * `defaultOpen` * `boolean` A boolean that controls the default state of the `` component. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. *** * `organizationProfileMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the **Manage organization** button will cause the \ component to open as a modal, or if the browser will navigate to the `organizationProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `organizationProfileProps` * `object` Specify options for the underlying \ component. For example: `{appearance: {...}}` *** * `organizationProfileUrl` * `string` The full URL or path where the \ component is mounted. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [createorg-ref]: /docs/reference/components/organization/create-organization [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "``" description: The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. sdk: expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-with-metamask lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/unstyled/sign-in-with-metamask.mdx --- The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. ## Usage ### Basic usage ```vue {{ filename: 'example.vue' }} ``` ### Custom usage In some cases, you will want to use your own button, or button text. You can do that by wrapping your button in the `` component. ```vue {{ filename: 'example.vue' }} ``` --- title: "``" description: The component is a button that links to the sign-up page or displays the sign-up modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-up-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/unstyled/sign-up-button.mdx --- The `` component is a button that, by default, links to your app's sign-up page. Your sign-up page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-up page. ## Usage ### Basic usage ```vue {{ filename: 'src/App.vue' }} ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```vue {{ filename: 'src/App.vue' }} ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-up route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'` *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). --- title: "``" description: The component is a button that links to the sign-in page or displays the sign-in modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/unstyled/sign-in-button.mdx --- The `` component is a button that, by default, links to your app's sign-in page. Your sign-in page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-in page. ## Usage ### Basic usage ```vue {{ filename: 'example.vue' }} ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```vue {{ filename: 'example.vue' }} ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-in route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'`. *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. --- title: "``" description: The `` component is a button that signs a user out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-out-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/components/unstyled/sign-out-button.mdx --- The `` component is a button that signs a user out. By default, it is a ` ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-in route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'`. *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. * `asChild?` * `boolean` If `true`, the `` component will render its children as a child of the component. --- title: "``" description: The `` component is a button that signs a user out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-out-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/components/unstyled/sign-out-button.mdx --- The `` component is a button that signs a user out. By default, it is a ` ``` ### Multi-session usage #### Sign out of all sessions Clicking the `` component signs the user out of all sessions. This is the default behavior. #### Sign out of a specific session You can sign out of a specific session by passing in a `sessionId` to the `sessionId` prop. This is useful for signing a single account out of a [multi-session application](/docs/guides/secure/session-options#multi-session-applications). In the following example, the `sessionId` is retrieved from the useAuth() hook. If the user is not signed in, the `sessionId` will be `null`, and the user is shown the \ component. If the user is signed in, the user is shown the `` component, which when clicked, signs the user out of that specific session. ```astro {{ filename: 'pages/index.astro' }} --- import { SignInButton, SignOutButton } from '@clerk/astro/components' import { useAuth } from '@clerk/astro/react' const { sessionId } = useAuth() --- {sessionId ? : } ``` ## Properties * `redirectUrl?` * `string` The full URL or path to navigate after successful sign-out. *** * `sessionId?` * `string` The ID of a specific session to sign out of. Useful for [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. * `asChild?` * `boolean` If `true`, the `` component will render its children as a child of the component. --- title: "``" description: The component is a button that links to the sign-up page or displays the sign-up modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-up-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/components/unstyled/sign-up-button.mdx --- The `` component is a button that, by default, links to your app's sign-up page. Your sign-up page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-up page. ## Usage ### Basic usage ```astro {{ filename: 'pages/sign-up.astro' }} --- import { SignUpButton } from '@clerk/astro/components' --- ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. You must pass the `asChild` prop to the `` component if you are passing children to it. ```astro {{ filename: 'src/pages/index.astro' }} --- import { SignUpButton } from '@clerk/astro/components' --- ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-up route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'` *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). * `asChild?` * `boolean` If `true`, the `` component will render its children as a child of the component. --- title: "`` component" description: Clerk's component is used to render the familiar user button UI popularized by Google. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/components/user/user-button.mdx --- ![The \ component renders the familiar user button UI popularized by Google.](/docs/images/ui-components/user-button.png){{ style: { maxWidth: '436px' } }} The `` component renders the familiar user button UI popularized by Google. When selected, it opens a dropdown menu with options to manage account settings and sign out. The "Manage account" option launches the \ component, providing access to profile and security settings. For users that have [multi-session](/docs/guides/secure/session-options#multi-session-applications) enabled, the `` also allows users to sign into multiple accounts at once and instantly switch between them without the need for a full page reload. Learn more [here](/docs/guides/secure/session-options#multi-session-applications). ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar and be able to open the popup menu. ```astro {{ filename: 'pages/index.astro' }} --- import { SignedIn, UserButton, SignInButton, SignedOut } from '@clerk/astro/components' --- ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterMultiSessionSingleSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterMultiSessionSingleSignOutUrl` to \.** The full URL or path to navigate to after signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterSignOutUrl` to \.** The full URL or path to navigate to after a successful sign-out. *** * `afterSwitchSessionUrl` * `string` The full URL or path to navigate to after a successful account change in a multi-session app. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `defaultOpen` * `boolean` Controls whether the `` should open by default during the first render. *** * `showName` * `boolean` Controls if the user name is displayed next to the user image button. *** * `signInUrl` * `string` The full URL or path to navigate to when the **Add another account** button is clicked. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `userProfileMode` * `'modal' | 'navigation'` Controls whether selecting the **Manage your account** button will cause the \ component to open as a modal, or if the browser will navigate to the `userProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `userProfileProps` * `object` Specify options for the underlying \ component. For example: `{additionalOAuthScopes: {google: ['foo', 'bar'], github: ['qux']}}`. *** * `userProfileUrl` * `string` The full URL or path leading to the user management interface. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). You can also [add custom actions and links to the `` menu](/docs/guides/customizing-clerk/adding-items/user-button). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/components/user/user-profile.mdx --- ![The \ component renders a full-featured account management UI that allows users to manage their profile and security settings.](/docs/images/ui-components/user-profile.png){{ style: { maxWidth: '100%' } }} The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile, security, and billing settings. ## Example ```astro {{ filename: 'pages/user.astro' }} --- import { UserProfile } from '@clerk/astro/components' --- ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/user-profile`. *** * `additionalOAuthScopes` * `object` Specify additional scopes per OAuth provider that your users would like to provide if not already approved. For example: `{google: ['foo', 'bar'], github: ['qux']}`. *** * `customPages` * CustomPage\[] An array of custom pages to add to the user profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/user-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages documentation](/docs/guides/customizing-clerk/adding-items/user-profile). --- title: "`` component" description: Clerk's component is used to render the familiar user avatar on its own. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-avatar lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/components/user/user-avatar.mdx --- ![The \ component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications.](/docs/images/ui-components/user-avatar.png) The `` component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications. ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar. ```astro {{ filename: 'pages/index.astro' }} --- import { SignedIn, UserAvatar, SignInButton, SignedOut } from '@clerk/astro/components' --- ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `rounded?` * `boolean` Determines whether the user avatar is displayed with rounded corners. *** * `appearance?` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` Optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: Hooks Reference description: A list of Clerk's comprehensive suite of hooks for managing authentication, sessions, sign-in and sign-up flows, Organizations, and reverification. sdk: astro, chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/hooks/overview.mdx --- Clerk offers a comprehensive suite of hooks that expose low-level access to authentication, session management, and multi-tenancy. With Clerk hooks, you can access and manage user data, handle sign-in and sign-up flows, control session management, and implement advanced flows like session reverification for sensitive actions. By using these hooks, you can extend or replace Clerk's built-in components and customize how authentication behaves in your application. ## Hooks * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: useAuth() description: Access and manage authentication state in your application with Clerk's useAuth() hook. sdk: astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/hooks/use-auth.mdx --- The `useAuth()` hook provides access to the current user's authentication state and methods to manage the active session. > \[!NOTE] > To access auth data server-side, see the Auth object reference doc. ## Parameters | Parameter | Type | Description | | ---------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `initialAuthStateOrOptions?` | null \| Record\ \| \{ treatPendingAsSignedOut?: boolean; \} | An object containing the initial authentication state or options for the `useAuth()` hook. If not provided, the hook will attempt to derive the state from the context. `treatPendingAsSignedOut` is a boolean that indicates whether pending sessions are considered as signed out or not. Defaults to `true`. | ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `undefined` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has` | `undefined` | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `undefined` | The ID of the user's active organization. | | `orgRole` | `undefined` | The current user's role in their active organization. | | `orgSlug` | `undefined` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `undefined` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `undefined` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `undefined` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `null` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (params: CheckAuthorizationParamsWithCustomPermissions) => false | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `null` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `null` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `null` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `string` | The ID of the user's active organization. | | `orgRole` | `string` | The current user's role in their active organization. | | `orgSlug` | null \| string | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | ## Example The following example demonstrates how to use the `useAuth()` hook to access the current auth state, like whether the user is signed in or not. It also includes a basic example for using the `getToken()` method to retrieve a session token for fetching data from an external resource. ```tsx {{ filename: 'src/components/external-data.jsx' }} import { useAuth } from '@clerk/astro/react' import { useState } from 'react' export default function ExternalData() { const { userId, sessionId, getToken, isLoaded, isSignedIn } = useAuth() const [data, setData] = useState(null) const fetchExternalData = async () => { const token = await getToken() const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) const json = await response.json() setData(json) } // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

Hello, {userId}! Your current active session is {sessionId}.

{data &&
{JSON.stringify(data, null, 2)}
}
) } ``` ```astro {{ filename: 'src/pages/auth.astro' }} --- import ExternalData from '../components/external-data' --- ```
--- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: go sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: Clerk Go SDK description: Learn how to integrate Clerk into your Go application using the Clerk Go SDK. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: go sourceFile: /docs/getting-started/quickstart.go.mdx --- The [Clerk Go SDK](/docs/reference/go/overview) is built on top of the [Clerk Backend API](/docs/reference/backend-api){{ target: '_blank' }}. ## Installation If you're using Go Modules and have a `go.mod` file in your project's root, you can import `clerk-sdk-go` directly in your `.go` files: ```go import ( "github.com/clerk/clerk-sdk-go/v2" ) ``` Alternatively, you can `go get` the package explicitly and it will add the necessary dependencies to your `go.mod` file: ```sh {{ filename: 'terminal' }} go get -u github.com/clerk/clerk-sdk-go/v2 ``` ## Usage For details on how to use this module, see the [Go Documentation](https://pkg.go.dev/github.com/clerk/clerk-sdk-go/v2). The Clerk Go SDK is organized using a resource-based structure similar to the [Clerk Backend API](/docs/reference/backend-api){{ target: '_blank' }}. Each API supports specific operations, like `Create` or `List`. For example, the [`actortoken`](https://github.com/clerk/clerk-sdk-go/blob/v2/actortoken/api.go) resource supports the `Create`, `Revoke`, and `GetClient` operations. For the list of supported resources, see [`https://github.com/clerk/clerk-sdk-go/tree/v2`](https://github.com/clerk/clerk-sdk-go/tree/v2) where almost each directory represents a resource. To execute API operations, you must configure Clerk Go with your Clerk Secret Key. To find your Clerk Secret Key: 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Secret Keys** section, copy your Secret Key. Depending on your use case, there are two ways to use the Clerk Go SDK: * Without a client: The best option if you're using one API key. * With a client: The best option if you're using more than one API key. For most use cases, the API **without** a client is a better choice as it requires a minimal setup and provides a more concise API for invoking operations. However, if you need to operate on multiple Clerk instances from one application, or need more flexibility for tests and mocking, you can instantiate multiple API clients with different API keys. The following examples demonstrate both approaches. ### Usage without a client If you only use one API key, you can import the packages required for the APIs you need. Then you can execute your desired request methods as functions, such as `$resource$.Get()` or `$resource$.Delete()`, where `$resource$` is the resource you want to interact with, such as [`user`](https://github.com/clerk/clerk-sdk-go/blob/v2/user/api.go). ```go {{ filename: 'main.go' }} package main import ( "context" "github.com/clerk/clerk-sdk-go/v2" "github.com/clerk/clerk-sdk-go/v2/user" ) func main() { // Each operation requires a context.Context as the first argument ctx := context.Background() // Set the API key with your Clerk Secret Key clerk.SetKey("{{secret}}") // Create a new user newUser, err := user.Create(ctx, &user.CreateParams{}) if err != nil { // Handle error } // Get user details userDetails, err := user.Get(ctx, "user_id") if err != nil { // Handle error } // List users userList, err := user.List(ctx, &user.ListParams{}) if err != nil { // Handle error } for _, u := range userList.Users { // Process each user } // Delete user deletedResource, err := user.Delete(ctx, "user_id") if err != nil { // Handle error } } ``` #### Example The following example demonstrates how to use the Clerk Go SDK to execute [Clerk Backend API](/docs/reference/backend-api){{ target: '_blank' }} operations. By executing the code in the snippet below, you will: * Create an Organization and update its slug. * Fetch all Organization memberships and loop through them to get the first one. * Get more details about the Organization's user. > \[!NOTE] > Your Clerk Secret Key is required. If you're signed into the Clerk Dashboard, your Secret Key should become visible by selecting the eye icon. Otherwise, you can retrieve your Clerk Secret Key on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ```go {{ filename: 'main.go' }} import ( "github.com/clerk/clerk-sdk-go/v2" "github.com/clerk/clerk-sdk-go/v2/organization" "github.com/clerk/clerk-sdk-go/v2/organizationmembership" "github.com/clerk/clerk-sdk-go/v2/user" ) func main() { // Each API operation requires a context.Context as the first argument. ctx := context.Background() // Set the API key clerk.SetKey("{{secret}}") // Create an organization org, err := organization.Create(ctx, &organization.CreateParams{ Name: clerk.String("Clerk Inc"), }) if err != nil { // You can get additional information on the error, if it can // be type-cast to clerk.APIErrorResponse. if apiErr, ok := err.(*clerk.APIErrorResponse); ok { apiErr.TraceID apiErr.Error() apiErr.Response.RawJSON } // handle the error panic(err) } // Update the organization org, err = organization.Update(ctx, org.ID, &organization.UpdateParams{ Slug: clerk.String("clerk"), }) if err != nil { // handle the error panic(err) } // List organization memberships listParams := organizationmembership.ListParams{} listParams.Limit = clerk.Int64(10) memberships, err := organizationmembership.List(ctx, params) if err != nil { // handle the error panic(err) } if memberships.TotalCount < 0 { return } membership := memberships[0] // Get a user usr, err := user.Get(ctx, membership.UserID) if err != nil { // handle the error panic(err) } } ``` ### Usage with a client If you're working with multiple keys, it's recommended to use Clerk Go with a client. The API packages for each resource export a `Client`, which supports all the API's operations. This way, you can create as many clients as needed, each with their own API key, as shown in the following example: ```go {{ filename: 'main.go' }} package main import ( "context" "github.com/clerk/clerk-sdk-go/v2" "github.com/clerk/clerk-sdk-go/v2/user" ) func main() { // Each operation requires a context.Context as the first argument. ctx := context.Background() // Initialize a client with an API key config := &clerk.ClientConfig{} config.Key = "{{secret}}" client := user.NewClient(config) // Create a new user newUser, err := client.Create(ctx, &user.CreateParams{}) if err != nil { // Handle error } // Get user details userDetails, err := client.Get(ctx, "user_id") if err != nil { // Handle error } // List users userList, err := client.List(ctx, &user.ListParams{}) if err != nil { // Handle error } for _, u := range userList.Users { // Process each user } // Delete user deletedResource, err := client.Delete(ctx, "user_id") if err != nil { // Handle error } } ``` --- title: TanStack React Start Quickstart (beta) description: Learn how to use Clerk to quickly and easily add secure authentication and user management to your TanStack React Start application. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: tanstack-react-start sourceFile: /docs/getting-started/quickstart.tanstack-react-start.mdx --- > \[!WARNING] > The TanStack React Start SDK is currently in beta. **It is not yet recommended for production use**. ## Install `@clerk/tanstack-react-start` The [Clerk TanStack React Start SDK](/docs/reference/tanstack-react-start/overview) gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Run the following command to install the SDK: ```npm {{ filename: 'terminal' }} npm install @clerk/tanstack-react-start ``` ## Set your Clerk API keys Add the following keys to your `.env` file. These keys can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, copy your Clerk Publishable and Secret Keys. 3. Paste your keys into your `.env` file. The final result should resemble the following: ```env {{ filename: '.env' }} VITE_CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} ``` ## Add `clerkMiddleware()` to your app [`clerkMiddleware()`](/docs/reference/tanstack-react-start/clerk-middleware) grants you access to user authentication state throughout your app, on any server function or route. Create a `src/start.ts` file with the following code: ```tsx {{ filename: 'src/start.ts' }} import { clerkMiddleware } from '@clerk/tanstack-react-start/server' import { createStart } from '@tanstack/react-start' export const startInstance = createStart(() => { return { requestMiddleware: [clerkMiddleware()], } }) ``` ## Add `` to your app The \ component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with `` to make authentication globally accessible. See the reference docs for other configuration options. Add the `` component to your app's root route, as shown in the following example: ```tsx {{ filename: 'src/routes/__root.tsx', ins: [1, 37, 59], fold: [[2, 34]] }} import { ClerkProvider } from '@clerk/tanstack-react-start' import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router' import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools' import { TanStackDevtools } from '@tanstack/react-devtools' import Header from '../components/Header' import appCss from '../styles.css?url' export const Route = createRootRoute({ head: () => ({ meta: [ { charSet: 'utf-8', }, { name: 'viewport', content: 'width=device-width, initial-scale=1', }, { title: 'TanStack Start Starter', }, ], links: [ { rel: 'stylesheet', href: appCss, }, ], }), shellComponent: RootDocument, }) function RootDocument({ children }: { children: React.ReactNode }) { return (
{children} , }, ]} /> ) } ``` ## Protect your pages ### Client-side To protect your pages on the client-side, you can use Clerk's prebuilt control components that control the visibility of content based on the user's authentication state. The following example uses the following components: * \: Children of this component can only be seen while **signed in**. * \: Children of this component can only be seen while **signed out**. * \: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. * \: 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: 'src/routes/index.tsx' }} import { SignedIn, UserButton, SignedOut, SignInButton } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (

Index Route

You are signed in

You are signed out

) } ``` ### Server-side To protect your routes, create a [server function](https://tanstack.com/start/latest/docs/framework/react/guide/server-functions) that checks the user's authentication state via the [`auth()`](/docs/reference/tanstack-react-start/auth) method. If the user is not authenticated, they are redirected to a sign-in page. If authenticated, the user's `userId` is passed to the route, allowing access to the `` component, which welcomes the user and displays their `userId`. The [`beforeLoad()`](https://tanstack.com/router/latest/docs/framework/react/api/router/RouteOptionsType#beforeload-method) method ensures authentication is checked before loading the page, and the [`loader()`](https://tanstack.com/router/latest/docs/framework/react/api/router/RouteOptionsType#loader-method) method returns the user data for use in the component. > \[!TIP] > Ensure that your app has the [TanStack Start server handler](https://tanstack.com/start/latest/docs/framework/react/guide/server-routes#handling-server-route-requests) configured in order for your server routes to work. ```tsx {{ filename: 'src/routes/index.tsx' }} import { createFileRoute, redirect } from '@tanstack/react-router' import { createServerFn } from '@tanstack/react-start' import { auth } from '@clerk/tanstack-react-start/server' const authStateFn = createServerFn({ method: 'GET' }).handler(async () => { const { isAuthenticated, userId } = await auth() if (!isAuthenticated) { // This will error because you're redirecting to a path that doesn't exist yet // You can create a sign-in route to handle this // See https://clerk.com/docs/tanstack-react-start/guides/development/custom-sign-in-or-up-page throw redirect({ to: '/sign-in', }) } return { userId } }) export const Route = createFileRoute('/')({ component: Home, beforeLoad: async () => await authStateFn(), loader: async ({ context }) => { return { userId: context.userId } }, }) function Home() { const state = Route.useLoaderData() return

Welcome! Your ID is {state.userId}!

} ``` ## Create your first user Run your project with the following command: ```npm npm run dev ``` Visit your app's homepage at [http://localhost:3000](http://localhost:3000). Sign up to create your first user. ## Next steps * [Core concepts](/docs/getting-started/core-concepts) * Before building your application, it's important to understand the core concepts and objects that drive Clerk's powerful authentication and user management system. *** * [Add a custom sign-in-or-up page](/docs/tanstack-react-start/guides/development/custom-sign-in-or-up-page) * Learn how to create a custom sign-in-or-up page using Clerk's prebuilt components. *** * [Protect content and read user data](/docs/tanstack-react-start/guides/users/reading) * Learn how to use Clerk's hooks and helpers to protect content and read session and user data. *** * [Clerk components](/docs/reference/components/overview) * Learn more about Clerk's prebuilt components. --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: tanstack-react-start sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'app/routes/pricing.tsx' }} import { PricingTable } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: PricingPage, }) function PricingPage() { return (
) } ```
## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```tsx {{ filename: 'app/routes/bronze-content.tsx' }} import { getAuth } from '@clerk/tanstack-react-start/server' import { createFileRoute } from '@tanstack/react-router' import { getWebRequest } from '@tanstack/react-start/server' export const Route = createFileRoute('/bronze-content')({ component: BronzeContentPage, beforeLoad: async () => { const request = getWebRequest() if (!request) throw new Error('Request not found') return { auth: await getAuth(request) } }, loader: async ({ context }) => { return { hasBronzePlan: context.auth.has({ plan: 'bronze' }) } }, }) function BronzeContentPage() { const { hasBronzePlan } = Route.useLoaderData() if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```tsx {{ filename: 'app/routes/premium-content.tsx' }} import { getAuth } from '@clerk/tanstack-react-start/server' import { createFileRoute } from '@tanstack/react-router' import { getWebRequest } from '@tanstack/react-start/server' export const Route = createFileRoute('/premium-content')({ component: PremiumContentPage, beforeLoad: async () => { const request = getWebRequest() if (!request) throw new Error('Request not found') return { auth: await getAuth(request) } }, loader: async ({ context }) => { return { hasPremiumAccess: context.auth.has({ feature: 'premium_access' }) } }, }) function PremiumContentPage() { const { hasPremiumAccess } = Route.useLoaderData() if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```tsx {{ filename: 'app/routes/manage-premium-content.tsx' }} import { getAuth } from '@clerk/tanstack-react-start/server' import { createFileRoute } from '@tanstack/react-router' import { getWebRequest } from '@tanstack/react-start/server' export const Route = createFileRoute('/manage-premium-content')({ component: ManagePremiumContentPage, beforeLoad: async () => { const request = getWebRequest() if (!request) throw new Error('Request not found') return { auth: await getAuth(request) } }, loader: async ({ context }) => { return { hasPremiumAccessManage: context.auth.has({ permission: 'org:premium_access:manage' }), } }, }) function ManagePremiumContentPage() { const { hasPremiumAccessManage } = Route.useLoaderData() if (!hasPremiumAccessManage) return (

Only subscribers with the Premium Access Manage permission can access this content.

) return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. ```tsx {{ filename: 'app/routes/protected-content.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/protected-content')({ component: ProtectedContentPage, }) function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. ```tsx {{ filename: 'app/routes/protected-premium-content.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/protected-premium-content')({ component: ProtectedPremiumContentPage, }) function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. ```tsx {{ filename: 'app/routes/protected-manage-content.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/protected-manage-content')({ component: ProtectedManageContentPage, }) function ProtectedManageContentPage() { return ( Only subscribers with the Premium Access Manage permission can access this content.

} >

Exclusive Management Content

This content is only visible to users with Premium Access Manage permission.

) } ```
--- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: tanstack-react-start sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'app/routes/pricing.tsx' }} import { PricingTable } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: PricingPage, }) function PricingPage() { return (
) } ```
## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```tsx {{ filename: 'app/routes/bronze-content.tsx' }} import { getAuth } from '@clerk/tanstack-react-start/server' import { createFileRoute } from '@tanstack/react-router' import { getWebRequest } from '@tanstack/react-start/server' export const Route = createFileRoute('/bronze-content')({ component: BronzeContentPage, beforeLoad: async () => { const request = getWebRequest() if (!request) throw new Error('Request not found') return { auth: await getAuth(request) } }, loader: async ({ context }) => { return { hasBronzePlan: context.auth.has({ plan: 'bronze' }) } }, }) function BronzeContentPage() { const { hasBronzePlan } = Route.useLoaderData() if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if a user has a Feature. ```tsx {{ filename: 'app/routes/premium-content.tsx' }} import { getAuth } from '@clerk/tanstack-react-start/server' import { createFileRoute } from '@tanstack/react-router' import { getWebRequest } from '@tanstack/react-start/server' export const Route = createFileRoute('/premium-content')({ component: PremiumContentPage, beforeLoad: async () => { const request = getWebRequest() if (!request) throw new Error('Request not found') return { auth: await getAuth(request) } }, loader: async ({ context }) => { return { hasPremiumAccess: context.auth.has({ feature: 'premium_access' }) } }, }) function PremiumContentPage() { const { hasPremiumAccess } = Route.useLoaderData() if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. ```tsx {{ filename: 'app/routes/protected-content.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/protected-content')({ component: ProtectedContentPage, }) function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. ```tsx {{ filename: 'app/routes/protected-premium-content.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/protected-premium-content')({ component: ProtectedPremiumContentPage, }) function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
--- title: Build your own sign-in-or-up page for your TanStack React Start app with Clerk description: Learn how to add a custom sign-in-or-up page to your TanStack React Start app with Clerk's prebuilt components. sdk: nextjs, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/custom-sign-in-or-up-page lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,remix,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/guides/development/custom-sign-in-or-up-page.tanstack-react-start.mdx --- This guide shows you how to use the \ component to build a custom page **that allows users to sign in or sign up within a single flow**. To set up separate sign-in and sign-up pages, follow this guide, and then follow the [custom sign-up page guide](/docs/tanstack-react-start/guides/development/custom-sign-up-page). > \[!NOTE] > Just getting started with Clerk and TanStack React Start? See the [quickstart tutorial](/docs/tanstack-react-start/getting-started/quickstart)! ## Build a sign-in-or-up page The following example demonstrates how to render the \ component on a dedicated page using the [TanStack Router catch-all route](https://tanstack.com/router/latest/docs/framework/react/routing/routing-concepts#splat--catch-all-routes). ```tsx {{ filename: 'src/routes/sign-in.$.tsx' }} import { SignIn } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/sign-in/$')({ component: Page, }) function Page() { return } ``` ## Configure your sign-in-or-up page Set the `CLERK_SIGN_IN_URL` environment variable to tell Clerk where the `` component is being hosted. There are other environment variables that you can set to customize Clerk's redirect behavior, such as `CLERK_SIGN_IN_FORCE_REDIRECT_URL`. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```env {{ filename: '.env' }} CLERK_SIGN_IN_URL=/sign-in ``` ## Visit your new page Run your project with the following command: ```npm npm run dev ``` Visit your new custom page locally at [localhost:3000/sign-in](http://localhost:3000/sign-in). ## Next steps * [Create custom sign-up page](/docs/tanstack-react-start/guides/development/custom-sign-up-page) * Learn how to add a custom sign-up page to your TanStack React Start app with Clerk's prebuilt components. *** * [Protect content and read user data](/docs/tanstack-react-start/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your TanStack React Start application. --- title: Build your own sign-up page for your TanStack React Start app with Clerk description: Learn how to add a custom sign-up page to your TanStack React Start app with Clerk's prebuilt components. sdk: nextjs, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/custom-sign-up-page lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,remix,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/guides/development/custom-sign-up-page.tanstack-react-start.mdx --- By default, the \ component handles signing in and signing up, but if you'd like to have a dedicated sign-up page, this guide shows you how to use the \ component to build a custom sign-up page. To set up a single sign-in-or-up page, follow the [custom sign-in-or-up page guide](/docs/tanstack-react-start/guides/development/custom-sign-in-or-up-page). > \[!NOTE] > Just getting started with Clerk and TanStack React Start? See the [quickstart tutorial](/docs/tanstack-react-start/getting-started/quickstart)! ## Build a sign-up page The following example demonstrates how to render the \ component on a dedicated sign-up page using the [TanStack Router catch-all route](https://tanstack.com/router/latest/docs/framework/react/routing/routing-concepts#splat--catch-all-routes). ```tsx {{ filename: 'src/routes/sign-up.$.tsx' }} import { SignUp } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/sign-up/$')({ component: Page, }) function Page() { return } ``` ## Configure your sign-up page * Set the `CLERK_SIGN_UP_URL` environment variable to tell Clerk where the `` component is being hosted. There are other environment variables that you can set to customize Clerk's redirect behavior, such as `CLERK_SIGN_UP_FORCE_REDIRECT_URL`. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```env {{ filename: '.env' }} CLERK_SIGN_UP_URL=/sign-up ``` ## Visit your new pages Run your project with the following command: ```npm npm run dev ``` Visit your new custom page locally at [localhost:3000/sign-up](http://localhost:3000/sign-up). ## Next steps * [Protect content and read user data](/docs/tanstack-react-start/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your TanStack React Start application. --- title: Verify OAuth access tokens in your TanStack React Start application with Clerk description: Learn how to use Clerk's helpers to verify OAuth access tokens in your TanStack React Start application. sdk: nextjs, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/verifying-oauth-access-tokens lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/guides/development/verifying-oauth-access-tokens.tanstack-react-start.mdx --- When building a resource server that needs to accept and verify OAuth access tokens issued by Clerk, it's crucial to verify these tokens on your backend to ensure the request is coming from an authenticated client. > \[!NOTE] > OAuth tokens are machine tokens. Machine token usage is free during our public beta period but will be subject to pricing once generally available. Pricing is expected to be competitive and below market averages. Clerk provides a built-in [`auth()`](/docs/reference/tanstack-react-start/auth) function that supports token validation via the `acceptsToken` parameter. This lets you specify which type(s) of token your API route should accept in your TanStack React Start application. By default, `acceptsToken` is set to `session_token`, which means OAuth tokens will **not** be accepted unless explicitly configured. You can pass either a **single token type** or an **array of token types** to `acceptsToken`. To learn more about the supported token types, see the [`auth()` parameters documentation](/docs/reference/tanstack-react-start/auth#parameters). ## Example 1: Accepting a single token type In the following example, the `acceptsToken` parameter is set to only accept `oauth_token`s. * If the token is invalid or missing, `auth()` will return `null` for `subject` and other properties, and the request will be rejected with a `401` response. * If the token is valid, it returns the authenticated user's subject and their associated scopes for use in the application logic. ```tsx export async function clerkAuth({ request }: { request: Request }) { const { subject, scopes } = await auth({ acceptsToken: 'oauth_token', }) // If auth() returns null, the token is invalid if (!subject) { throw new Error('OAuth access token is invalid') } return { subject, scopes } } ``` ## Example 2: Accepting any token type In the following example, the `acceptsToken` parameter is set to accept any token type. * If the token is a `session_token`, it logs that the request is from a user session. * Otherwise, it logs that the request uses a machine token and specifies its type. ```tsx import { createServerFn } from '@tanstack/react-start' import { auth } from '@clerk/tanstack-react-start/server' const authStateFn = createServerFn({ method: 'GET' }).handler(async () => { const { tokenType } = await auth({ acceptsToken: 'any' }) if (tokenType === 'session_token') { console.log('This is a session token from a user') } else { console.log(`This is a ${tokenType} token`) } return {} }) ``` --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: tanstack-react-start sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: Protect content and read user data description: Learn how to use Clerk's hooks and helpers to protect content and read user data in your TanStack React Start application. metadata: title: Read session and user data in your Tanstack React Start app with Clerk sdk: nextjs, expo, react-router, remix, tanstack-react-start, astro, nuxt sdkScoped: "true" canonical: /docs/:sdk:/guides/users/reading lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,expo,react-router,remix,tanstack-react-start,astro,nuxt notAvailableSdks: react,js-frontend,chrome-extension,android,ios,expressjs,fastify,go,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/guides/users/reading.tanstack-react-start.mdx --- Clerk provides a set of [hooks and helpers](/docs/reference/tanstack-react-start/overview#client-side-helpers) that you can use to protect content and read user data in your TanStack React Start application. Here are examples of how to use these helpers in both the client and server-side to get you started. ## Server-side The [`auth()`](/docs/reference/tanstack-react-start/auth) helper returns the Auth object of the currently active user, which contains important information like the current user's session ID, user ID, and Organization ID, and the `isAuthenticated` property, which can be used to protect your API routes. In some cases, you may need the full Backend User object of the currently active user. This is helpful if you want to render information, like their first and last name, directly from the server. The `clerkClient()` helper returns an instance of the JS Backend SDK, which exposes Clerk's Backend API resources through methods such as the getUser(){{ target: '_blank' }} method. This method returns the full `Backend User` object. In the following example, the `userId` is passed to the JS Backend SDK's `getUser()` method to get the user's full `Backend User` object. ```tsx {{ filename: 'src/routes/index.tsx' }} import { createFileRoute, redirect } from '@tanstack/react-router' import { createServerFn } from '@tanstack/react-start' import { clerkClient, auth } from '@clerk/tanstack-react-start/server' import { UserButton } from '@clerk/tanstack-react-start' const authStateFn = createServerFn({ method: 'GET' }).handler(async () => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await auth() // Protect the server function from unauthenticated users if (!isAuthenticated) { // This might error if you're redirecting to a path that doesn't exist yet // You can create a sign-in route to handle this // See https://clerk.com/docs/reference/tanstack-react-start/custom-sign-in-or-up-page throw redirect({ to: '/sign-in/$', }) } // Get the user's full `Backend User` object const user = await clerkClient().users.getUser(userId) return { userId, firstName: user?.firstName } }) export const Route = createFileRoute('/')({ component: Home, beforeLoad: () => authStateFn(), loader: async ({ context }) => { return { userId: context.userId, firstName: context.firstName } }, }) function Home() { const state = Route.useLoaderData() return (

Welcome, {state.firstName}!

Your ID is {state.userId}

) } ```
```ts {{ filename: 'src/routes/api/example.ts' }} import { auth, clerkClient } from '@clerk/tanstack-react-start/server' import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { GET: async () => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await auth() // Protect the API route from unauthenticated users if (!isAuthenticated) { return new Response('User not authenticated', { status: 404, }) } // Get the user's full `Backend User` object const user = await clerkClient().users.getUser(userId) // Return the `Backend User` object return json({ user }) }, }, }, }) ```
## Client-side To access session and user data on the client-side, use Clerk's `useAuth()` and `useUser()` hooks. ### `useAuth()` {/* TODO: Keep in sync with _partials/hooks/use-auth */} The useAuth(){{ target: '_blank' }} hook provides information about the current auth state, as well as helper methods to manage the current session. ```tsx {{ filename: 'routes/example.tsx' }} import { useAuth } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/example')({ component: Example, }) function Example() { const { isLoaded, isSignedIn, userId, sessionId, getToken } = useAuth() const fetchExternalData = async () => { // Use `getToken()` to get the current user's session token const token = await getToken() // Use `token` to fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return
Loading...
} // Use `isSignedIn` to check if the user is signed in if (!isSignedIn) { // You could also add a redirect to the sign-in page here return
Sign in to view this page
} return (
Hello, {userId}! Your current active session is {sessionId}.
) } ``` ### `useUser()` {/* TODO: Keep in sync with _partials/hooks/use-user */} The useUser(){{ target: '_blank' }} hook enables you to access the User object, which contains the current user's data such as their full name. The following example demonstrates how to use `useUser()` to check if the user is signed in and display their first name: ```tsx {{ filename: 'routes/example.tsx' }} import { useUser } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/example')({ component: Example, }) function Example() { const { isLoaded, isSignedIn, user } = useUser() if (!isLoaded) { return
Loading...
} if (!isSignedIn) { // You could also add a redirect to the sign-in page here return
Sign in to view this page
} return
Hello, {user.firstName}!
} ``` --- title: "``" description: The component provides session and user context to Clerk's hooks and components. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/clerk-provider lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/clerk-provider.mdx --- The `` component is required to integrate Clerk into your React application, providing session and user context to Clerk's hooks and components. The recommended approach is to wrap your entire app with `` at the entry point to make authentication globally accessible. If you only need authentication for specific routes or pieces of your application, render `` deeper in the component tree. This allows you to implement Clerk's functionality precisely where required without impacting the rest of your app. ## Example ```tsx {{ filename: 'src/routes/__root.tsx', ins: [3, 17, 27] }} import * as React from 'react' import { HeadContent, Outlet, Scripts, createRootRoute } from '@tanstack/react-router' import { ClerkProvider } from '@clerk/tanstack-react-start' export const Route = createRootRoute({ component: () => { return ( ) }, }) function RootDocument({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ## Properties | Property | Type | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `afterMultiSessionSingleSignOutUrl?` | null \| string | The full URL or path to navigate to after signing out the current user is complete. This option applies to [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). | | ~~`afterSignInUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl` or `signInForceRedirectUrl` instead. | | `afterSignOutUrl?` | null \| string | Full URL or path to navigate to after successful sign out. | | ~~`afterSignUpUrl?`~~ | null \| string | **Deprecated.** Use `signUpFallbackRedirectUrl` or `signUpForceRedirectUrl` instead. | | `allowedRedirectOrigins?` | (string \| RegExp)\[] | An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `allowedRedirectProtocols?` | string\[] | An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `appearance?` | [`Appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) | Optional object to style your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `clerkJSUrl?` | `string` | The URL that `@clerk/clerk-js` should be hot-loaded from. | | `clerkJSVariant?` | "" \| "headless" | If your web application only uses Control Components, you can set this value to `'headless'` and load a minimal ClerkJS bundle for optimal page performance. | | `clerkJSVersion?` | `string` | The npm version for `@clerk/clerk-js`. | | `domain?` | string \| (url: URL) => string | **Required if your application is a satellite application**. Sets the domain of the satellite application. | | `experimental?` | `Autocomplete`\<\{ commerce: boolean; persistClient: boolean; rethrowOfflineNetworkErrors: boolean; \}, `Record`\<`string`, `any`\>\> | Enable experimental flags to gain access to new features. These flags are not guaranteed to be stable and may change drastically in between patch or minor versions. | | `initialState?` | `Serializable`\<\{ actor: undefined \| \{ \[x: string]: unknown; sub: string; \}; factorVerificationAge: \[number, number]; organization: undefined \| OrganizationResource; orgId: undefined \| string; orgPermissions: undefined \| string\[]; orgRole: undefined \| string; orgSlug: undefined \| string; session: undefined \| SessionResource; sessionClaims: JwtPayload; sessionId: undefined \| string; sessionStatus: SessionStatusClaim; user: undefined \| UserResource; userId: undefined \| string; \}\> | Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `isSatellite?` | boolean \| (url: URL) => boolean | A boolean that indicates whether the application is a satellite application. | | `localization?` | [`LocalizationResource`](/docs/guides/customizing-clerk/localization) | Optional object to localize your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `newSubscriptionRedirectUrl?` | null \| string | The URL to navigate to after the user completes the checkout and clicks the "Continue" button. | | `nonce?` | `string` | This nonce value will be passed through to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. | | `proxyUrl?` | string \| (url: URL) => string \| (url: URL) => string | **Required for applications that run behind a reverse proxy**. The URL that Clerk will proxy requests to. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). | | `publishableKey` | `string` | The Clerk Publishable 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. | | ~~`redirectUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl`, `signInForceRedirectUrl`, `signUpFallbackRedirectUrl`, or `signUpForceRedirectUrl` instead. | | `routerPush?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "push" navigation. | | `routerReplace?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "replace" navigation. | | `sdkMetadata?` | \{ environment?: string; name: string; version: string; \} | Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `sdkMetadata.environment?` | `string` | Typically this will be the `NODE_ENV` that the SDK is currently running in. | | `sdkMetadata.name` | `string` | The npm package name of the SDK. | | `sdkMetadata.version` | `string` | The npm package version of the SDK. | | `selectInitialSession?` | (client: ClientResource) => null \| SignedInSessionResource | By default, the last signed-in session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. | | `signInFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signInForceRedirectUrl?` | null \| string | 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. | | `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. | | `signUpFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signUpForceRedirectUrl?` | null \| string | 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. | | `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. | | `standardBrowser?` | `boolean` | By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. | | `supportEmail?` | `string` | Optional support email for display in authentication screens. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `taskUrls?` | `Record`\<`"choose-organization"`, `string`\> | Customize the URL paths users are redirected to after sign-in or sign-up when specific session tasks need to be completed. When `undefined`, it uses Clerk's default task flow URLs. Defaults to `undefined`. | | `telemetry?` | false \| \{ debug?: boolean; disabled?: boolean; perEventSampling?: boolean; \} | Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. | | `touchSession?` | `boolean` | By default, the [Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/Sessions#operation/touchSession) is called during page focus to keep the last active session alive. This option allows you to disable this behavior. | | `waitlistUrl?` | `string` | The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). | ## SDK-specific properties ### Next.js * `dynamic` * `boolean` Indicates whether or not Clerk should make dynamic auth data available based on the current request. Defaults to `false`. Opts the application into dynamic rendering when `true`. For more information, see Next.js rendering modes and Clerk. ### Chrome Extension * `syncHost` * `string` To enable, pass the URL of the web application that the extension will sync the authentication state from. See the dedicated guide for more information. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: tanstack-react-start sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`` component" description: Clerk's component renders a UI for authenticating users with Google's One Tap API. sdk: astro, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/google-one-tap lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: chrome-extension,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/authentication/google-one-tap.mdx --- > \[!IMPORTANT] > To use Google One Tap with Clerk, you must [enable Google as a social connection in the Clerk Dashboard](/docs/guides/configure/auth-strategies/social-connections/google#configure-for-your-production-instance) and make sure to use custom credentials. The `` component renders the [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) UI so that users can use a single button to sign-up or sign-in to your Clerk application with their Google accounts. By default, this component will redirect users back to the page where the authentication flow started. However, you can override this with force redirect URL props or [force redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). > \[!TIP] > `` does not render if the user is already signed into your Clerk application, so there's no need to manually check if a user is signed in yourself before rendering it. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/sign-in.tsx' }} import { GoogleOneTap } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/sign-in')({ component: SignIn, }) function SignIn() { return } ``` ## Properties * `cancelOnTapOutside?` * `boolean` If `true`, the One Tap prompt closes automatically if the user clicks outside of the prompt. Defaults to `true`. *** * `itpSupport?` * `boolean` If `true`, enables the [ITP-specific UX](https://developers.google.com/identity/gsi/web/guides/itp) when One Tap is rendered on ITP browsers such as Chrome on iOS, Safari, and FireFox. Defaults to `true`. *** * `fedCmSupport?` * `boolean` If `true`, enables Google One Tap to use [the FedCM API](https://developers.google.com/privacy-sandbox/3pcd/fedcm) to sign users in. See Google's docs on [best practices when disabling FedCM support](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap#do_not_cover_google_one_tap). Defaults to `true` *** * `signInForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs in, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). *** * `signUpForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs up, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). ## Limitations * If your application will use the Google API on behalf of your users, the `` component is not recommended, as Google does not provide Clerk with an access or refresh token that you can use. * Users with the 1Password browser extension may not be able to render the Google One Tap UI. They must disable this extension. * When testing in development, if you select the `X` button to close the Google One Tap UI, you may encounter [a cooldown](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown) that prevents you from rendering it again for a period of time. To bypass the cooldown, remove the `g_state` cookie. --- title: "`` component" description: Clerk's component renders a UI for signing in users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/authentication/sign-in.mdx --- ![The \ component renders a UI for signing in users.](/docs/images/ui-components/sign-in.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI to allow users to sign in or sign up by default. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. If you would like to create a dedicated `/sign-in` page in your TanStack React Start application, there are a few requirements you must follow. See the [dedicated guide](/docs/tanstack-react-start/guides/development/custom-sign-in-or-up-page) for more information. ```tsx {{ filename: 'app/routes/sign-in.$.tsx' }} import { SignIn } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/sign-in')({ component: SignInPage, }) function SignInPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `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. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-in`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signUpFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Used for the 'Don't have an account? Sign up' link that's rendered. Defaults to `/`. 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 used as the redirect destination after the user signs up. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signUpUrl` * `string` The full URL or path to the sign-up page. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `transferable` * `boolean` Indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `waitlistUrl` * `string` Full URL or path to the waitlist page. Use this property to provide the target of the 'Waitlist' link that's rendered. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). If you've passed the `waitlistUrl` prop to the \ component, it will infer from that, and you can omit this prop. *** * `withSignUp` * `boolean` Opt into sign-in-or-up flow by setting this prop to `true`. When `true`, if a user does not exist, they will be prompted to sign up. If a user exists, they will be prompted to sign in. Defaults to `true` if the `CLERK_SIGN_IN_URL` environment variable is set. Otherwise, defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for signing up users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/authentication/sign-up.mdx --- ![The \ component renders a UI for signing up users.](/docs/images/ui-components/sign-up.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. If you would like to create a dedicated `/sign-up` page in your Tanstack React Start application, there are a few requirements you must follow. See the [dedicated guide](/docs/tanstack-react-start/guides/development/custom-sign-up-page) for more information. ```tsx {{ filename: 'app/routes/sign-up.$.tsx' }} import { SignUp } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/sign-up')({ component: SignUpPage, }) function SignUpPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `string` If provided, this URL will always be used as the redirect destination 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. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-up`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signInFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Used for the 'Already have an account? Sign in' link that's rendered. 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. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signInUrl` * `string` The full URL or path to the sign-in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: The component renders a waitlist form that allows users to join for early access to your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/waitlist lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/authentication/waitlist.mdx --- ![The \ component renders a form that allows users to join for early access to your app.](/docs/images/ui-components/waitlist.png){{ style: { maxWidth: '460px' } }} In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. [Learn more about additional features available in **Waitlist** mode](/docs/guides/secure/restricting-access#waitlist). The `` component renders a form that allows users to join for early access to your app. ## Enable Waitlist mode Before using the `` component, you must enable **Waitlist** mode in the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. ## Example > \[!WARNING] > Before using the `` component, you must provide the `waitlistUrl` prop either in the \ or \ component to ensure proper functionality. The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/waitlist.tsx' }} import { Waitlist } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/waitlist')({ component: WaitlistPage, }) function WaitlistPage() { return } ``` ## Properties All props are optional. * `afterJoinWaitlistUrl` * `string` The full URL or path to navigate to after joining the waitlist. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `signInUrl` * `string` The full URL or path to the sign in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. ## Customization To learn about how to customize Clerk components, see the [customization guide](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component renders a UI for resolving the `choose-organization` task. sdk: js-frontend, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/task-choose-organization lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/authentication/task-choose-organization.mdx --- ![The \ component renders a UI for resolving the choose-organization session task.](/docs/images/ui-components/task-choose-organization.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for resolving the `choose-organization` session task. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/overview). You can further customize your `` component by passing additional properties at the time of rendering. > \[!IMPORTANT] > The `` component cannot render when a user doesn't have current session tasks. ## Example The following example demonstrates how to host the `` component on a custom page. > \[!NOTE] > To see the full `__root.tsx` setup you need for Clerk with TanStack React Start, see the [TanStack React Start quickstart](/docs/tanstack-react-start/getting-started/quickstart). ```tsx {{ filename: 'src/routes/__root.tsx', mark: [7] }} import * as React from 'react' import { HeadContent, Scripts } from '@tanstack/react-router' import { ClerkProvider } from '@clerk/tanstack-react-start' function RootDocument({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` The `` component must be used in conjunction with the `` component. See the [dedicated guide on how to self-host the `` component](/docs/tanstack-react-start/guides/development/custom-sign-in-or-up-page). ```tsx {{ filename: 'src/routes/onboarding/choose-organization.tsx' }} import { TaskChooseOrganization } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/onboarding/choose-organization')({ component: ChooseOrganizationPage, }) function ChooseOrganizationPage() { return } ``` ## Properties All props are optional. * `redirectUrlComplete` * `string` The full URL or path to navigate to after successfully completing all tasks. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "``" description: Clerk's component displays a table of Plans and Features that users can subscribe to. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/pricing-table lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/billing/pricing-table.mdx --- ![The \ component displays a table of Plans and Features that users can subscribe to.](/docs/images/ui-components/pricing-table.png) The `` component displays a table of Plans and Features that users can subscribe to. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/pricing.tsx' }} import { PricingTable } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/pricing')({ component: PricingPage, }) function PricingPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `checkoutProps` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `collapseFeatures` * `boolean` A boolean that indicates whether the Features are collapsed. **Requires `layout` to be set to `'default'`**. Defaults to `false`. *** * `ctaPosition` * `'top' | 'bottom'` The placement of the CTA button. **Requires `layout` to be set to `'default'`**. Defaults to `'bottom'`. *** * `fallback` * `JSX` An optional UI to show when the pricing table is loading. *** * `for` * `'user' | 'organization'` A string that indicates whether the pricing table is for users or [Organizations](/docs/guides/organizations/overview). If `'user'`, the pricing table will display a list of Plans and Features that **users** can subscribe to. If `'organization'`, the pricing table will display a list of Plans and Features that **Organizations** can subscribe to. Defaults to `'user'`. *** * `newSubscriptionRedirectUrl` * `string` The URL to navigate to after the user completes the checkout and selects the "Continue" button. --- title: \RedirectCallback /> description: Clerk's `` component is used to implement custom OAuth flows. It handles the OAuth callback and completes the authentication process. sdk: astro, chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/authenticate-with-redirect-callback lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: expo,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/authenticate-with-redirect-callback.mdx --- The `` component is a crucial part of implementing custom OAuth flows in your application. It serves as the callback handler for the authentication process initiated by the `authenticateWithRedirect()` method. Render it on the route specified as the `redirectUrl` in your `authenticateWithRedirect()` call. This component automatically handles the OAuth callback, completing the authentication process and managing the user's session. It uses the handleRedirectCallback() method under the hood. ## Example For an example of how to use the `` component, see the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) guide. ## Properties All props are optional. * `continueSignUpUrl?` * `string | undefined | null` The full URL or path to navigate to if the sign up requires additional information. *** * `signInUrl?` * `string` The full URL or path where the `` component is mounted. *** * `signUpUrl?` * `string` The full URL or path where the `` component is mounted. *** * `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. *** * `firstFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if first factor verification is required. *** * `secondFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) is enabled. *** * `resetPasswordUrl?` * `string` The full URL or path to navigate to during sign in, if the user is required to reset their password. *** * `transferable?` * `boolean` A boolean that indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `verifyEmailAddressUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting email verification. *** * `verifyPhoneNumberUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting phone verification. --- title: "``" description: The component indicates that Clerk is partially operational. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-degraded lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/clerk-degraded.mdx --- The `` component indicates that Clerk is partially operational. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'app/routes/index.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The component indicates that the Clerk object has failed to load. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-failed lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/clerk-failed.mdx --- The `` component indicates that the Clerk object has failed to load. This is useful for displaying an error message to the user. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'app/routes/index.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The Protect component protects content or even entire routes based on authentication, and optionally, authorization. It only renders its children when the current user is signed-in, and if performing authorization checks, if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/protect lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/protect.mdx --- The \ component protects content or even entire routes based on: * authentication: whether the user is signed-in or not. * authorization: whether the user has been granted a specific type of access control (Role, Permission, Feature, or Plan) `` **always** performs authentication checks. To perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., you can pass different props, like `role`, `permission`, `feature`, or `plan`. `` accepts a `fallback` prop that will be rendered if the user fails the authentication or authorization checks. `` can be used both client-side and server-side (in Server Components). > \[!CAUTION] > This component only **visually hides** its children when the current user is not authorized. The contents of its children remain accessible via the browser's source code even if the user fails the authorization check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Usage ### Authentication checks `` always performs authentication checks. It will render its children if the user is signed-in, and its `fallback` prop if the user is signed-out. ```tsx {{ filename: 'app/routes/dashboard.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/dashboard')({ component: DashboardPage, }) function DashboardPage() { return ( Users that are signed-out can see this.

}>

Users that are signed-in can see this.

) } ```
### Authorization checks To limit who is able to see the content that `` renders, you can pass **one** of the access control props: `permission`, `role`, `feature`, or `plan`. It's recommended to use **Permission-based** authorization over **Role-based** authorization, and **Feature-based** authorization over **Plan-based** authorization, as they are more flexible, easier to manage, and more secure. If you do not pass any of the access control props, `` will render its children if the user is signed in, regardless of their Role or its Permissions. For more complex authorization logic, pass conditional logic to the `condition` prop. ### Render content by Permissions The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:invoices:create` Permission. ```tsx {{ filename: 'app/routes/invoices.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/invoices')({ component: InvoicesPage, }) function InvoicesPage() { return ( You do not have the Permissions to create an invoice.

} >

Users with Permission org:invoices:create can see this.

) } ```
### Render content by Role While authorization by `permission` is **recommended**, for convenience, `` allows a `role` prop to be passed. The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:billing` Role. ```tsx {{ filename: 'app/routes/billing.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/billing')({ component: BillingPage, }) function BillingPage() { return ( Only a member of the Billing department can access this content.

} >

Users with Role org:billing can see this.

) } ```
### Render content by Plan The following example demonstrates how to use `` to protect content by checking if the user has a Plan. ```tsx {{ filename: 'app/routes/bronze.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/bronze')({ component: BronzePage, }) function BronzePage() { return ( Sorry, only subscribers to the Bronze plan can access this content.

} >

Welcome, Bronze subscriber!

) } ```
### Render content by Feature The following example demonstrates how to use `` to protect content by checking if the user has a Feature. ```tsx {{ filename: 'app/routes/premium-access.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/premium-access')({ component: PremiumAccessPage, }) function PremiumAccessPage() { return ( Sorry, only subscribers with the Premium Access feature can access this content.

} >

Congratulations! You have access to the Premium Access feature.

) } ```
### Render content conditionally The following example uses ``'s `condition` prop to conditionally render its children if the user has the correct Role. ```tsx {{ filename: 'app/routes/settings.tsx' }} import { Protect } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/settings')({ component: SettingsPage, }) function SettingsPage() { return ( has({ role: 'org:admin' }) || has({ role: 'org:billing_manager' })} fallback={

Only an Admin or Billing Manager can access this content.

} >

The settings page.

) } ```
## Properties * `condition?` * `has => boolean` Optional conditional logic that renders the children if it returns `true`. *** * `fallback?` * `JSX` Optional UI to show when a user doesn't have the correct type of access control to access the protected content. *** * `feature?` * `string` Optional string corresponding to a [Feature](/docs/guides/billing/overview). *** * `plan?` * `string` Optional string corresponding to a [Plan](/docs/guides/billing/overview). *** * `permission?` * `string` Optional string corresponding to a [Permission](/docs/guides/organizations/roles-and-permissions) in the format `org::` *** * `role?` * `string` Optional string corresponding to a [Role](/docs/guides/organizations/roles-and-permissions) in the format `org:` *** * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loading lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/clerk-loading.mdx --- The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/routes/index.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the Clerk object without the need to check it exists. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loaded lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/clerk-loaded.mdx --- The `` component guarantees that the Clerk object has loaded (the `status` is `'ready'` or `'degraded'`) and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/routes/index.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "`` (deprecated)" description: The component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/redirect-to-create-organization.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToCreateOrganization() method instead. The `` component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedIn, SignedOut, RedirectToCreateOrganization } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (

You need to sign in to create an Organization.

) } ```
--- title: "`` (deprecated)" description: The component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/redirect-to-organization-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToOrganizationProfile() method instead. The `` component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedIn, SignedOut, RedirectToOrganizationProfile } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (

You need to sign in to view your Organization profile.

) } ```
--- title: "``" description: The component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/redirect-to-sign-in.mdx --- The `` component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedIn, SignedOut, RedirectToSignIn, UserButton } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (
) } ```
--- title: "``" description: The component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/redirect-to-sign-up.mdx --- The `` component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedIn, SignedOut, RedirectToSignUp, UserButton } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (
) } ```
--- title: "`` (deprecated)" description: The component will navigate to the user profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/redirect-to-user-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToUserProfile() method instead. The `` component will navigate to the Account Portal User Profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. To find your User Profile URL: 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Under **User profile**, select the **Visit** icon. ## Example ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedIn, SignedOut, RedirectToUserProfile } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (

You need to sign in to view your user profile.

) } ```
--- title: "``" description: The component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-tasks lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,remix,go,astro,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/redirect-to-tasks.mdx --- The `` component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks**Session tasks** are requirements that users must fulfill in order to complete the authentication process, such as choosing an Organization.. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. The `` component is primarily intended for use in custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. If you're using prebuilt components, you typically won't need to use `` as these components manage task redirection internally. [See the guide on handling session tasks outside of prebuilt components](/docs/guides/configure/session-tasks#redirecting-to-tasks). ## Example ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedOut, RedirectToTasks } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (
) } ```
--- title: "``" description: Conditionally render content only when a user is signed in. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/signed-in.mdx --- ## Overview The `` component offers authentication checks as a cross-cutting concern. Any children components wrapped by a `` component will be rendered only if there's a user with an active session signed in your application. > \[!CAUTION] > This component only **visually hides** its children when the current user is not authenticated. The contents of its children remain accessible via the browser's source code even if the user fails the authentication check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Example ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedIn } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (

You are signed in.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: Conditionally render content only when a user is signed out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-out lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/control/signed-out.mdx --- The `` component offers authentication checks as a cross-cutting concern. Any child nodes wrapped by a `` component will be rendered only if there's no User signed in to your application. ## Example ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedOut } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (

You are signed out.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` component" description: Clerk's component is used to render an Organization creation UI that allows users to create brand new Organizations within your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/organization/create-organization.mdx --- ![The \ component renders an Organization creation UI that allows users to create brand new organizations within your application.](/docs/images/ui-components/create-organization.png){{ style: { maxWidth: '492px' } }} The `` component is used to render an Organization creation UI that allows users to create brand new Organizations in your application. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/create-organization.tsx' }} import { CreateOrganization } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/create-organization')({ component: CreateOrganizationPage, }) function CreateOrganizationPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterCreateOrganizationUrl` * `string` Full URL or path to navigate to after creating a new organization. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/create-organization`. *** * `skipInvitationScreen` * `boolean` Hides the screen for sending invitations after an Organization is created. When left undefined, Clerk will automatically hide the screen if the number of max allowed members is equal to 1 *** * `hideSlug` * `boolean` Hides the optional slug field in the Organization creation screen. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured Organization management UI that allows users to manage their Organization profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/organization/organization-profile.mdx --- ![The \ component allows users to manage their Organization membership and security settings.](/docs/images/ui-components/organization-profile.png) The `` component allows users to manage their Organization membership, security, and billing settings. This component's **General** tab displays the Organization's information and the **Leave organization** button. Admins will be able to see the **Update profile** button, **Verified domains** section, and **Delete organization** button. The **Members** tab shows the Organization's members along with their join dates and Roles. Admins will have the ability to invite a member, change a member's Role, or remove them from the Organization. Admins will have tabs within the **Members** tab to view the Organization's [invitations](/docs/guides/organizations/overview#organization-invitations) and [requests](/docs/guides/organizations/verified-domains#membership-requests). The **Billing** tab displays the Plans and Features that are available to the Organization, as well as the user's billing information, such as their invoices and payment methods. ## Example The `` component must be embedded using the [TanStack Router catch-all route](https://tanstack.com/router/latest/docs/framework/react/routing/routing-concepts#splat--catch-all-routes) in order for the routing to work. ```tsx {{ filename: 'app/routes/organization-profile.$.tsx' }} import { OrganizationProfile } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/organization-profile/$')({ component: OrganizationProfilePage, }) function OrganizationProfilePage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after leaving an Organization. *** * `customPages` * `CustomPages[]` An array of custom pages to add to the Organization profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/organization-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash- and virtual-based routing.
For example: `/organization-profile`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages.
Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React.
## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages](/docs/guides/customizing-clerk/adding-items/organization-profile) documentation. --- title: "`` component" description: Clerk's component is used to display Organization related memberships, invitations, and suggestions for the user. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/organization/organization-list.mdx --- ![The \ component displays Organization-related memberships and automatic invitations and suggestions for the user.](/docs/images/ui-components/organization-list.png){{ style: { maxWidth: '460px' } }} The `` component displays Organization-related memberships and automatic [invitations](/docs/guides/organizations/verified-domains#automatic-invitations) and [suggestions](/docs/guides/organizations/verified-domains#automatic-suggestions) for the user. ## Example ```tsx {{ filename: 'app/routes/organizations.tsx' }} import { OrganizationList } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/organizations')({ component: OrganizationListPage, }) function OrganizationListPage() { return ( `/organization/${org.slug}`} afterSelectPersonalUrl={(user) => `/user/${user.id}`} afterSelectOrganizationUrl={(org) => `/organization/${org.slug}`} /> ) } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after creating a new Organization. *** * `afterSelectOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting an Organization. Defaults to `undefined`. *** * `afterSelectPersonalUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting the [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts). Defaults to `undefined`. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. Defaults to `false`. *** * `skipInvitationScreen` * `boolean | undefined` A boolean that controls whether the screen for sending invitations after an Organization is created is hidden. When `undefined`, Clerk will automatically hide the screen if the number of max allowed members is equal to 1. Defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [org-ref]: /docs/reference/javascript/organization --- title: "`` component" description: Clerk's component is used to enable the ability to switch between available Organizations the user may be part of in your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-switcher lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/organization/organization-switcher.mdx --- ![The \ component allows a user to switch between their account types - their Personal Account and their joined Organizations.](/docs/images/ui-components/organization-switcher.png){{ style: { maxWidth: '436px' } }} The `` component allows a user to switch between their joined Organizations. If [Personal Accounts are enabled](/docs/guides/organizations/overview#allow-personal-accounts), users can also switch to their Personal Account. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple Organizations. It handles all Organization-related flows, including full Organization management for admins. Learn more about [Organizations](/docs/guides/organizations/overview). ## Example ```tsx {{ filename: 'app/routes/organization-switcher.tsx' }} import { OrganizationSwitcher } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/organization-switcher')({ component: OrganizationSwitcherPage, }) function OrganizationSwitcherPage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * `string` The full URL or path to navigate to after creating a new Organization. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after the user leaves the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `afterSelectOrganizationUrl` * `string` The full URL or path to navigate to after a successful Organization switch. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `createOrganizationMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the "Create organization" button will cause the \ component to open as a modal, or if the browser will navigate to the `createOrganizationUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `createOrganizationUrl` * `string` The full URL or path where the ``]createorg-ref component is mounted. *** * `defaultOpen` * `boolean` A boolean that controls the default state of the `` component. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. *** * `organizationProfileMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the **Manage organization** button will cause the \ component to open as a modal, or if the browser will navigate to the `organizationProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `organizationProfileProps` * `object` Specify options for the underlying \ component. For example: `{appearance: {...}}` *** * `organizationProfileUrl` * `string` The full URL or path where the \ component is mounted. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [createorg-ref]: /docs/reference/components/organization/create-organization [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "``" description: The component is a button that links to the sign-in page or displays the sign-in modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/unstyled/sign-in-button.mdx --- The `` component is a button that, by default, links to your app's sign-in page. Your sign-in page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-in page. ## Usage ### Basic usage ```tsx {{ filename: 'app/routes/sign-in.tsx' }} import { SignInButton } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/sign-in')({ component: SignIn, }) function SignIn() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```tsx {{ filename: 'app/routes/sign-in.tsx' }} import { SignInButton } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/sign-in')({ component: SignIn, }) function SignIn() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-in route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'`. *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. --- title: "``" description: The `` component is a button that signs a user out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-out-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/unstyled/sign-out-button.mdx --- The `` component is a button that signs a user out. By default, it is a ` ) } ``` ### Multi-session usage #### Sign out of all sessions Clicking the `` component signs the user out of all sessions. This is the default behavior. #### Sign out of a specific session You can sign out of a specific session by passing in a `sessionId` to the `sessionId` prop. This is useful for signing a single account out of a [multi-session application](/docs/guides/secure/session-options#multi-session-applications). In the following example, the `sessionId` is retrieved from the useAuth() hook. If the user is not signed in, the `sessionId` will be `null`, and the user is shown the \ component. If the user is signed in, the user is shown the `` component, which when clicked, signs the user out of that specific session. ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignInButton, SignOutButton, useAuth } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { const { sessionId } = useAuth() if (!sessionId) { return } return } ``` ## Properties * `redirectUrl?` * `string` The full URL or path to navigate after successful sign-out. *** * `sessionId?` * `string` The ID of a specific session to sign out of. Useful for [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. --- title: "``" description: The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. sdk: expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-with-metamask lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/unstyled/sign-in-with-metamask.mdx --- The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. ## Usage ### Basic usage ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignInWithMetamaskButton } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return } ``` ### Custom usage In some cases, you will want to use your own button, or button text. You can do that by wrapping your button in the `` component. ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignInWithMetamaskButton } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return ( ) } ``` --- title: "``" description: The component is a button that links to the sign-up page or displays the sign-up modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-up-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/unstyled/sign-up-button.mdx --- The `` component is a button that, by default, links to your app's sign-up page. Your sign-up page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-up page. ## Usage ### Basic usage ```tsx {{ filename: 'app/routes/sign-up.tsx' }} import { SignUpButton } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/sign-up')({ component: SignUp, }) function SignUp() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignUpButton } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-up route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'` *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). --- title: "`` component" description: Clerk's component is used to render the familiar user button UI popularized by Google. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/user/user-button.mdx --- ![The \ component renders the familiar user button UI popularized by Google.](/docs/images/ui-components/user-button.png){{ style: { maxWidth: '436px' } }} The `` component renders the familiar user button UI popularized by Google. When selected, it opens a dropdown menu with options to manage account settings and sign out. The "Manage account" option launches the \ component, providing access to profile and security settings. For users that have [multi-session](/docs/guides/secure/session-options#multi-session-applications) enabled, the `` also allows users to sign into multiple accounts at once and instantly switch between them without the need for a full page reload. Learn more [here](/docs/guides/secure/session-options#multi-session-applications). ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar and be able to open the popup menu. ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedIn, UserButton, SignInButton, SignedOut } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `afterMultiSessionSingleSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterMultiSessionSingleSignOutUrl` to \.** The full URL or path to navigate to after signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterSignOutUrl` to \.** The full URL or path to navigate to after a successful sign-out. *** * `afterSwitchSessionUrl` * `string` The full URL or path to navigate to after a successful account change in a multi-session app. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `defaultOpen` * `boolean` Controls whether the `` should open by default during the first render. *** * `showName` * `boolean` Controls if the user name is displayed next to the user image button. *** * `signInUrl` * `string` The full URL or path to navigate to when the **Add another account** button is clicked. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `userProfileMode` * `'modal' | 'navigation'` Controls whether selecting the **Manage your account** button will cause the \ component to open as a modal, or if the browser will navigate to the `userProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `userProfileProps` * `object` Specify options for the underlying \ component. For example: `{additionalOAuthScopes: {google: ['foo', 'bar'], github: ['qux']}}`. *** * `userProfileUrl` * `string` The full URL or path leading to the user management interface. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). You can also [add custom actions and links to the `` menu](/docs/guides/customizing-clerk/adding-items/user-button). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/user/user-profile.mdx --- ![The \ component renders a full-featured account management UI that allows users to manage their profile and security settings.](/docs/images/ui-components/user-profile.png){{ style: { maxWidth: '100%' } }} The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile, security, and billing settings. ## Example The `` component must be embedded using the [TanStack Router catch-all route](https://tanstack.com/router/latest/docs/framework/react/routing/routing-concepts#splat--catch-all-routes) in order for the routing to work. ```tsx {{ filename: 'app/routes/user-profile.$.tsx' }} import { UserProfile } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/user-profile/$')({ component: UserProfilePage, }) function UserProfilePage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/user-profile`. *** * `additionalOAuthScopes` * `object` Specify additional scopes per OAuth provider that your users would like to provide if not already approved. For example: `{google: ['foo', 'bar'], github: ['qux']}`. *** * `customPages` * CustomPage\[] An array of custom pages to add to the user profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/user-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages documentation](/docs/guides/customizing-clerk/adding-items/user-profile). --- title: "`` component" description: Clerk's component is used to render the familiar user avatar on its own. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-avatar lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/components/user/user-avatar.mdx --- ![The \ component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications.](/docs/images/ui-components/user-avatar.png) The `` component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications. ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar. ```tsx {{ filename: 'app/routes/index.tsx' }} import { SignedIn, UserAvatar, SignInButton, SignedOut } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) function Home() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `rounded?` * `boolean` Determines whether the user avatar is displayed with rounded corners. *** * `appearance?` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` Optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`useOrganizationList()`" description: Access and manage the current user's Organization list in your React application with Clerk's useOrganizationList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-organization-list.mdx --- The `useOrganizationList()` hook provides access to the current user's Organization memberships, invitations, and suggestions. It also includes methods for creating new Organizations and managing the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganizationList()` accepts a single object with the following properties: | Property | Type | Description | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`userInvitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`userMemberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & object & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • Any of the properties described in Shared properties.
| |
`userSuggestions?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "pending" \| "accepted" \| ("pending" \| "accepted")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the suggestions by the provided status.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `userMemberships`, `userInvitations`, and `userSuggestions` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | ## Returns | Property | Type | Description | | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createOrganization` | undefined \| (CreateOrganizationParams: CreateOrganizationParams) => Promise\<OrganizationResource\> | A function that returns a `Promise` which resolves to the newly created `Organization`. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization and there is an authenticated user. Initially `false`, becomes `true` once Clerk loads with a user. | | `setActive` | undefined \| (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. | | `userInvitations` | PaginatedResourcesWithDefault\<UserOrganizationInvitationResource\> \| PaginatedResources\<UserOrganizationInvitationResource, T\["userInvitations"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization invitations. | | `userMemberships` | PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["userMemberships"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization memberships. | | `userSuggestions` | PaginatedResourcesWithDefault\<OrganizationSuggestionResource\> \| PaginatedResources\<OrganizationSuggestionResource, T\["userSuggestions"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of suggestions for organizations that the user can join. | ### `CreateOrganizationParams` | Property | Type | Description | | ------------------------- | -------- | ----------------------------- | | `name` | `string` | The name of the organization. | | `slug?` | `string` | The slug of the organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expanding and paginating attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. So by default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // userMemberships.data will never be populated const { userMemberships } = useOrganizationList() // Use default values to fetch userMemberships, such as initialPage = 1 and pageSize = 10 const { userMemberships } = useOrganizationList({ userMemberships: true, }) // Pass your own values to fetch userMemberships const { userMemberships } = useOrganizationList({ userMemberships: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `userMemberships` attribute will be populated with the first page of the user's Organization memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```tsx {{ filename: 'components/JoinedOrganizations.tsx' }} import { useOrganizationList } from '@clerk/tanstack-react-start' export function JoinedOrganizations() { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) // Handle loading state if (!isLoaded) return
Loading...
return ( <>
    {userMemberships.data?.map((mem) => (
  • {mem.organization.name}
  • ))}
) } ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `userInvitations` attribute will be populated with the first page of invitations. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of invitations. Notice the difference between this example's pagination and the infinite pagination example above. ```tsx {{ filename: 'components/UserInvitationsTable.tsx' }} import { useOrganizationList } from '@clerk/tanstack-react-start' export function UserInvitationsTable() { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { infinite: true, keepPreviousData: true, }, }) // Handle loading state if (!isLoaded || userInvitations.isLoading) return
Loading...
return ( <> {userInvitations.data?.map((inv) => ( ))}
Email Org name
{inv.emailAddress} {inv.publicOrganizationData.name}
) } ```
## Related guides * [Build a custom Organization switcher](/docs/guides/development/custom-flows/organizations/organization-switcher) * Use Clerk's API to build a custom flow for switching between Organizations *** * [Create Organizations](/docs/guides/development/custom-flows/organizations/create-organizations) * Use Clerk's API to build a custom flow for creating Organizations *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: useAuth() description: Access and manage authentication state in your application with Clerk's useAuth() hook. sdk: astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-auth.mdx --- The `useAuth()` hook provides access to the current user's authentication state and methods to manage the active session. > \[!NOTE] > To access auth data server-side, see the Auth object reference doc. ## Parameters | Parameter | Type | Description | | ---------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `initialAuthStateOrOptions?` | null \| Record\ \| \{ treatPendingAsSignedOut?: boolean; \} | An object containing the initial authentication state or options for the `useAuth()` hook. If not provided, the hook will attempt to derive the state from the context. `treatPendingAsSignedOut` is a boolean that indicates whether pending sessions are considered as signed out or not. Defaults to `true`. | ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `undefined` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has` | `undefined` | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `undefined` | The ID of the user's active organization. | | `orgRole` | `undefined` | The current user's role in their active organization. | | `orgSlug` | `undefined` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `undefined` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `undefined` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `undefined` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `null` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (params: CheckAuthorizationParamsWithCustomPermissions) => false | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `null` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `null` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `null` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `string` | The ID of the user's active organization. | | `orgRole` | `string` | The current user's role in their active organization. | | `orgSlug` | null \| string | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | ## Example The following example demonstrates how to use the `useAuth()` hook to access the current auth state, like whether the user is signed in or not. It also includes a basic example for using the `getToken()` method to retrieve a session token for fetching data from an external resource. ```tsx {{ filename: 'app/routes/index.tsx' }} import { useAuth } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: ExternalDataPage, }) function ExternalDataPage() { const { userId, sessionId, getToken, isLoaded, isSignedIn } = useAuth() const fetchExternalData = async () => { const token = await getToken() // Fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

Hello, {userId}! Your current active session is {sessionId}.

) } ```
--- title: useClerk() description: Access and manage the Clerk object in your React application with Clerk's useClerk() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-clerk lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-clerk.mdx --- > \[!WARNING] > This hook should only be used for advanced use cases, such as building a completely custom OAuth flow or as an escape hatch to access to the `Clerk` object. The `useClerk()` hook provides access to the Clerk object, allowing you to build alternatives to any Clerk Component. ## Returns Clerk — The `useClerk()` hook returns the `Clerk` object, which includes all the methods and properties listed in the Clerk reference. ## Example The following example uses the `useClerk()` hook to access the `clerk` object. The `clerk` object is used to call the openSignIn() method to open the sign-in modal. ```tsx {{ filename: 'app/routes/index.tsx' }} import { useClerk } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) export default function Home() { const clerk = useClerk() return } ``` --- title: Hooks Reference description: A list of Clerk's comprehensive suite of hooks for managing authentication, sessions, sign-in and sign-up flows, Organizations, and reverification. sdk: astro, chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/overview.mdx --- Clerk offers a comprehensive suite of hooks that expose low-level access to authentication, session management, and multi-tenancy. With Clerk hooks, you can access and manage user data, handle sign-in and sign-up flows, control session management, and implement advanced flows like session reverification for sensitive actions. By using these hooks, you can extend or replace Clerk's built-in components and customize how authentication behaves in your application. ## Hooks * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: useReverification() description: Clerk's useReverification() hook enhances a fetcher function to handle a session's reverification flow. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-reverification lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-reverification.mdx --- > \[!WARNING] > > Depending on the SDK you're using, this feature requires `@clerk/nextjs@6.12.7` or later, `@clerk/clerk-react@5.25.1` or later, `@clerk/clerk-js@5.57.1` or later and `@clerk/clerk-sdk-ruby@3.3.0` or later. Reverification allows you to prompt a user to verify their credentials before performing sensitive actions, even if they're already authenticated. For example, in a banking application, transferring money is considered a "sensitive action." Reverification can be used to confirm the user's identity. The `useReverification()` hook is used to handle a session's reverification flow. If a request requires reverification, a modal will display, prompting the user to verify their credentials. Upon successful verification, the original request will automatically retry. If you'd like to build a custom UI, you can use the onNeedsReverification option. When using reverification, a user's credentials are valid for 10 minutes. Once stale, a user will need to reverify their credentials. This time duration can be customized by using the `has()` helper on the server-side. See the [guide on reverification](/docs/guides/secure/reverification) for more information. ## Parameters | Parameter | Type | Description | | ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `fetcher` | `Fetcher extends (...args: any[]) => Promise` | A function that returns a promise. | | `options?` | `Options` | Optional configuration object extending UseReverificationOptions. | ### `UseReverificationOptions` The optional options object. | Property | Type | Description | | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | |
`onNeedsReverification?` | (properties: NeedsReverificationParameters) => void | Handler for the reverification process. Opts out of using the default UI. Use this to build a custom UI. | ### `NeedsReverificationParameters` | Property | Type | Description | | -------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `cancel` | () => void | Marks the reverification process as cancelled and rejects the original request. | | `complete` | () => void | Marks the reverification process as complete and retries the original request. | | `level` | undefined \| "first\_factor" \| "second\_factor" \| "multi\_factor" | The verification level required for the reverification process. | ## Examples The `useReverification()` hook displays a prebuilt UI when the user needs to reverify their credentials. You can also build a custom UI to handle the reverification process yourself. Use the following tabs to see examples of either option. ### Handle reverification for an action The following example demonstrates how to use the `useReverification()` hook to require a user to reverify their credentials before being able to update their primary email address. It also demonstrates how to handle the cancellation of the reverification process. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/tanstack-react-start' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification((emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {email.id !== user?.primaryEmailAddress?.id && ( )}
  • ))}
) } ```
### Handle reverification for a fetcher function The following example demonstrates how to use the `useReverification()` hook to enhance a fetcher function that fetches data from a route that requires reverification. For examples on how to set up a route that requires reverification, see the [guide on reverification](/docs/guides/secure/reverification). ```tsx {{ filename: 'src/components/AccountBalance.tsx' }} import { useReverification } from '@clerk/tanstack-react-start' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' export function AccountBalance() { const [balance, setBalance] = useState(null) const accountBalance = useReverification(async () => { const response = await fetch('/api/balance') return await response.json() }) const handleClick = async () => { try { const accountBalanceResponse = await accountBalance() setBalance(accountBalanceResponse.amount) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your account balance is {balance ? `$${balance}` : '$******'}
) } ```
The following example demonstrates how to build a custom UI when using the `useReverification()` hook. In the example, the `useReverification()` hook is used to require a user to reverify their credentials before being able to update their primary email address. It requires two components: the `` component displays the list of email addresses to choose from and it renders the second component, ``, which handles the reverification process. The example handles first factor verification using an email code, so you will need to have the [**Email verification code**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) setting enabled for your application. But you can adapt this example to handle any type of verification level or strategy. The `` component uses `useReverification()` to enhance the `update()` method, requiring the user to reverify their credentials before being able to update their primary email address. The `useReverification()` hook provides the `onNeedsReverification` option, which is a handler for building a custom UI. It provides four properties: `level`, `complete`, `cancel`, and `inProgress`. The example tracks these using the `verificationState` state variable. * The `level` property determines the verification level required for the reverification process. This example only handles first factor verification, which is done in the `` component. * The `complete` and `cancel` properties are the steps of the reverification process, which is also done in the `` component. * The `inProgress` property is used to track the state of the reverification process. When the user selects the "Make primary" button, it triggers the reverification process and sets the `inProgress` property is `true`, which displays the `` component. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/tanstack-react-start' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' import { SessionVerificationLevel } from '@clerk/types' import { VerificationComponent } from './VerificationComponent' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // TODO: Update to use exported type once available const [verificationState, setVerificationState] = useState< | { complete: () => void cancel: () => void level: SessionVerificationLevel | undefined inProgress: boolean } | undefined >(undefined) // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification( (emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), { onNeedsReverification: ({ complete, cancel, level }) => { setVerificationState({ complete, cancel, level, inProgress: true, }) }, }, ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {user?.primaryEmailAddressId !== email.id && ( )}
  • ))}
{verificationState?.inProgress && ( { verificationState.complete() setVerificationState(undefined) }} onCancel={() => { verificationState.cancel() setVerificationState(undefined) }} /> )}
) } ```
The `` component handles the reverification process. It uses the `level` property to determine the verification level, which is set to `first_factor`. First, it finds the determined starting first factor from the supported first factors. Then, it prepares the first factor verification using the `strategy` (`email_code` in this case) and `emailAddressId` properties. Finally, it attempts to verify the session with email code provided by the user. If the verification is successful, the `onComplete()` handler is called to complete the reverification process. ```tsx {{ filename: 'components/VerificationComponent.tsx', collapsible: true }} import { useEffect, useRef, useState } from 'react' import { useSession } from '@clerk/tanstack-react-start' import { EmailCodeFactor, SessionVerificationLevel, SessionVerificationResource, } from '@clerk/types' export function VerificationComponent({ level = 'first_factor', onComplete, onCancel, }: { level: SessionVerificationLevel | undefined onComplete: () => void onCancel: () => void }) { const { session } = useSession() const [code, setCode] = useState('') const reverificationRef = useRef(undefined) const [determinedStartingFirstFactor, setDeterminedStartingFirstFactor] = useState< EmailCodeFactor | undefined >() useEffect(() => { if (reverificationRef.current) { return } session?.startVerification({ level }).then(async (response) => { reverificationRef.current = response await prepareEmailVerification(response) }) }, []) const prepareEmailVerification = async (verificationResource: SessionVerificationResource) => { // To simplify the example we will only handle the first factor verification if (verificationResource.status === 'needs_first_factor') { // Determine the starting first factor from the supported first factors const determinedStartingFirstFactor = verificationResource.supportedFirstFactors?.filter( (factor) => factor.strategy === 'email_code', )[0] if (determinedStartingFirstFactor) { setDeterminedStartingFirstFactor(determinedStartingFirstFactor) // Prepare the first factor verification with the determined starting first factor await session?.prepareFirstFactorVerification({ strategy: determinedStartingFirstFactor.strategy, emailAddressId: determinedStartingFirstFactor?.emailAddressId, }) } } } const handleVerificationAttempt = async () => { try { // Attempt to verify the session with the provided code await session?.attemptFirstFactorVerification({ strategy: 'email_code', code, }) onComplete() } catch (e) { // Any error from the attempt to verify the session can be handled here console.error('Error verifying session', e) } } if (!determinedStartingFirstFactor) { return null } return (

Enter verification code sent to {determinedStartingFirstFactor.safeIdentifier || ''}

setCode(e.target.value)} />
) } ```
## Related guides See the custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). guides for examples of how to use the `useReverification()` hook, such as the [Add a phone number to a user's account](/docs/guides/development/custom-flows/account-updates/add-phone) guide. --- title: useOrganization() description: Access and manage the currently active Organization in your React application with Clerk's useOrganization() hook. search: rank: 1 sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-organization.mdx --- The `useOrganization()` hook retrieves attributes of the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganization()` accepts a single object with the following optional properties: | Property | Type | Description | | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`domains?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ enrollmentMode?: "manual\_invitation" \| "automatic\_invitation" \| "automatic\_suggestion"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `enrollmentMode`: A string that filters the domains by the provided [enrollment mode](/docs/guides/organizations/verified-domains#enrollment-mode).
  • Any of the properties described in Shared properties.
| |
`invitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: ("expired" \| "pending" \| "accepted" \| "revoked")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`membershipRequests?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the membership requests by the provided status.
  • Any of the properties described in Shared properties.
| |
`memberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ query?: string; role?: string\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `role`: An array of OrganizationCustomRoleKey.
  • `query`: A string that filters the memberships by the provided string.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes aren't populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `invitations`, `membershipRequests`, `memberships`, and `domains` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | > \[!NOTE] > These attributes are updating automatically and will re-render their respective components whenever you set a different Organization using the setActive(\{ organization }) method or update any of the memberships or invitations. No need for you to manage updating anything manually. ## Returns | Property | Type | Description | | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `domains` | null \| PaginatedResourcesWithDefault\<OrganizationDomainResource\> \| PaginatedResources\<OrganizationDomainResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's domains. | | `invitations` | null \| PaginatedResourcesWithDefault\<OrganizationInvitationResource\> \| PaginatedResources\<OrganizationInvitationResource, T\["invitations"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's invitations. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `membership` | undefined \| null \| OrganizationMembershipResource | The current organization membership. | | `membershipRequests` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipRequestResource\> \| PaginatedResources\<OrganizationMembershipRequestResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's membership requests. | | `memberships` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["memberships"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's memberships. | | `organization` | undefined \| null \| OrganizationResource | The currently active organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expand and paginate attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // invitations.data will never be populated. const { invitations } = useOrganization() // Use default values to fetch invitations, such as initialPage = 1 and pageSize = 10 const { invitations } = useOrganization({ invitations: true, }) // Pass your own values to fetch invitations const { invitations } = useOrganization({ invitations: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { invitations } = useOrganization({ invitations: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```tsx {{ filename: 'app/routes/members.tsx' }} import { useOrganization } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/members')({ component: MemberListPage, }) export default function MemberListPage() { const { memberships } = useOrganization({ memberships: { infinite: true, // Append new data to the existing list keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of memberships. Notice the difference between this example's pagination and the infinite pagination example above. ```tsx {{ filename: 'app/routes/members-paginated.tsx' }} import { useOrganization } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/members-paginated')({ component: MemberListPage, }) export default function MemberListPage() { const { memberships } = useOrganization({ memberships: { keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
## Related guides * [Update an Organization](/docs/guides/development/custom-flows/organizations/update-organizations) * Use Clerk's API to build a custom flow for updating an Organization *** * [Manage Roles in an Organization](/docs/guides/development/custom-flows/organizations/manage-roles) * Use Clerk's API to build a custom flow for managing Roles in an Organization *** * [Manage an Organization's membership requests](/docs/guides/development/custom-flows/organizations/manage-membership-requests) * Use Clerk's API to build a custom flow for managing an Organization's membership requests *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: useSession() description: Access and manage the current user's session in your React application with Clerk's useSession() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-session.mdx --- The `useSession()` hook provides access to the current user's Session object, as well as helpers for setting the active session. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `session` | `undefined` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `session` | `null` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `boolean` | A boolean that indicates whether a user is currently signed in. | | `session` | SignedInSessionResource | The current session for the user. | ## Example ### Access the `Session` object The following example uses the `useSession()` hook to access the `Session` object, which has the `lastActiveAt` property. The `lastActiveAt` property is a `Date` object used to show the time the session was last active. ```tsx {{ filename: 'app/routes/index.tsx' }} import { useSession } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: HomePage, }) function HomePage() { const { isLoaded, session, isSignedIn } = useSession() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

This session has been active since {session.lastActiveAt.toLocaleString()}

) } ```
--- title: useSignIn() description: Access and manage the current user's sign-in state in your React application with Clerk's useSignIn() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-sign-in.mdx --- The `useSignIn()` hook provides access to the SignIn object, which allows you to check the current state of a sign-in attempt and manage the sign-in flow. You can use this to create a [custom sign-in flow](/docs/guides/development/custom-flows/overview#sign-in-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signIn` | `undefined` | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signIn` | SignInResource | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | ## Examples ### Check the current state of a sign-in The following example uses the `useSignIn()` hook to access the SignIn object, which contains the current sign-in attempt status and methods to create a new sign-in attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'app/routes/index.tsx' }} import { useSignIn } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: SignInPage, }) export default function SignInPage() { const { isLoaded, signIn } = useSignIn() // Handle loading state if (!isLoaded) return
Loading...
return
The current sign-in attempt status is {signIn?.status}.
} ```
### Create a custom sign-in flow with `useSignIn()` The `useSignIn()` hook can also be used to build fully custom sign-in flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-in flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignIn()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useUser() description: Access and manage the current user's data in your React application with Clerk's useUser() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-user.mdx --- The `useUser()` hook provides access to the current user's User object, which contains all the data for a single user in your application and provides methods to manage their account. This hook also allows you to check if the user is signed in and if Clerk has loaded and initialized. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that returns `true` if the user is signed in. | | `user` | `undefined` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that returns `true` if the user is signed in. | | `user` | `null` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that returns `true` if the user is signed in. | | `user` | UserResource | The `User` object for the current user. | ## Examples ### Get the current user The following example uses the `useUser()` hook to access the User object, which contains the current user's data such as their full name. The `isLoaded` and `isSignedIn` properties are used to handle the loading state and to check if the user is signed in, respectively. ```tsx {{ filename: 'app/routes/index.tsx' }} import { useUser } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) export default function Home() { const { isSignedIn, user, isLoaded } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return
Hello {user.firstName}!
} ```
### Update user data The following example uses the `useUser()` hook to access the User object, which calls the update() method to update the current user's information. ```tsx {{ filename: 'app/routes/index.tsx' }} import { useUser } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) export default function Home() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { await user.update({ firstName: 'John', lastName: 'Doe', }) } return ( <>

user.firstName: {user.firstName}

user.lastName: {user.lastName}

) } ```
### Reload user data The following example uses the `useUser()` hook to access the User object, which calls the reload() method to get the latest user's information. ```tsx {{ filename: 'app/routes/index.tsx' }} import { useUser } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) export default function Home() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { // Update data via an API endpoint const updateMetadata = await fetch('/api/updateMetadata', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role: 'admin', }), }) // Check if the update was successful if ((await updateMetadata.json()).message !== 'success') { throw new Error('Error updating') } // If the update was successful, reload the user data await user.reload() } return ( <>

user role: {user.publicMetadata.role}

) } ```
--- title: useSignUp() description: Access and manage the current user's sign-up state in your React application with Clerk's useSignUp() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-sign-up.mdx --- The `useSignUp()` hook provides access to the SignUp object, which allows you to check the current state of a sign-up attempt and manage the sign-up flow. You can use this to create a [custom sign-up flow](/docs/guides/development/custom-flows/overview#sign-up-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signUp` | `undefined` | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signUp` | SignUpResource | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | ## Examples ### Check the current state of a sign-up The following example uses the `useSignUp()` hook to access the SignUp object, which contains the current sign-up attempt status and methods to create a new sign-up attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'app/routes/index.tsx' }} import { useSignUp } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: SignUpPage, }) export default function SignUpPage() { const { isLoaded, signUp } = useSignUp() // Handle loading state if (!isLoaded) return Loading... return
The current sign-up attempt status is {signUp?.status}.
} ```
### Create a custom sign-up flow with `useSignUp()` The `useSignUp()` hook can also be used to build fully custom sign-up flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-up flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignUp()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useSessionList() description: Access and manage the current user's session list in your React application with Clerk's useSessionList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/hooks/use-session-list.mdx --- The `useSessionList()` hook returns an array of Session objects that have been registered on the client device. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | `undefined` | A list of sessions that have been registered on the client device. | | `setActive` | `undefined` | A function that sets the active session and/or organization. See the reference doc. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | SessionResource\[] | A list of sessions that have been registered on the client device. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. See the reference doc. | ## Example ### Get a list of sessions The following example uses `useSessionList()` to get a list of sessions that have been registered on the client device. The `sessions` property is used to show the number of times the user has visited the page. ```tsx {{ filename: 'app/routes/index.tsx' }} import { useSessionList } from '@clerk/tanstack-react-start' import { createFileRoute } from '@tanstack/react-router' export const Route = createFileRoute('/')({ component: Home, }) export default function Home() { const { isLoaded, sessions } = useSessionList() // Handle loading state if (!isLoaded) return
Loading...
return (

Welcome back. You've been here {sessions.length} times before.

) } ```
--- title: Remix Quickstart description: Learn how to use Clerk to quickly and easily add secure authentication and user management to your Remix application. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: remix sourceFile: /docs/getting-started/quickstart.remix.mdx --- > \[!WARNING] > The Remix SDK is in maintenance mode and will only receive security updates. Please migrate to the React Router SDK for continued development and new features. Learn how to use Clerk to quickly and easily add secure authentication and user management to your Remix app. This guide assumes that you are using Remix v2 or later. > \[!NOTE] > If you are using Remix SPA mode, follow the [Remix SPA mode guide](/docs/guides/development/spa-mode). ## Install `@clerk/remix` The [Clerk Remix SDK](/docs/reference/remix/overview) gives you access to prebuilt components, hooks, and helpers to make user authentication easier. Run the following command to install the SDK: ```npm npm install @clerk/remix ``` ## Set your Clerk API keys Add the following keys to your `.env` file. These keys can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, copy your Clerk Publishable and Secret Keys. 3. Paste your keys into your `.env` file. The final result should resemble the following: ```env {{ filename: '.env' }} CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} ``` ## Configure `rootAuthLoader()` The [`rootAuthLoader()`](/docs/reference/remix/root-auth-loader) function is a helper function that provides the authentication state to your Remix application. You must export `rootAuthLoader()` as the root `loader()` function. Update your `root.tsx` file with the following code: ```tsx {{ filename: 'app/root.tsx', mark: [1, [4, 5], [15, 16]] }} import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' // Import `rootAuthLoader()` import { rootAuthLoader } from '@clerk/remix/ssr.server' export const meta: MetaFunction = () => [ { charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }, ] // Export `rootAuthLoader()` as the root route `loader` export const loader: LoaderFunction = (args) => rootAuthLoader(args) export function Layout({ children }: { children: React.ReactNode }) { return ( {children} ) } export default function App() { return } ``` ## Configure `ClerkApp` Clerk provides a `ClerkApp` wrapper to provide the authentication state to your React tree. This helper works with Remix SSR out-of-the-box and follows the "higher-order component" paradigm. Update your `root.tsx` file with the following code: ```tsx {{ filename: 'app/root.tsx', mark: [[6, 7], [39, 40]] }} import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' // Import ClerkApp import { ClerkApp } from '@clerk/remix' export const meta: MetaFunction = () => [ { charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }, ] export const loader: LoaderFunction = (args) => rootAuthLoader(args) export function Layout({ children }: { children: React.ReactNode }) { return ( {children} ) } function App() { return } // Wrap your app with `ClerkApp` export default ClerkApp(App) ``` ## Protect your pages ### Client-side To protect your pages on the client-side, Clerk's prebuilt control components control the visibility of content based on the user's authentication state. The following example uses the following components: * \: Children of this component can only be seen while **signed in**. * \: Children of this component can only be seen while **signed out**. * \: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. * \: 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: 'routes/_index.tsx' }} import { SignInButton, SignOutButton, SignUpButton, SignedIn, SignedOut, UserButton, } from '@clerk/remix' export default function Index() { return (

Index Route

You are signed in!

You are signed out

) } ``` ### Server-side To protect your routes, use the getAuth() function in your loader. This function retrieves the authentication state from the request object, returning an Auth object that includes the `isAuthenticated`, allowing you to determine if the user is authenticated. ```tsx {{ filename: 'routes/_index.tsx' }} import { UserButton } from '@clerk/remix' import { getAuth } from '@clerk/remix/ssr.server' import { LoaderFunction, redirect } from '@remix-run/node' export const loader: LoaderFunction = async (args) => { const { isAuthenticated } = await getAuth(args) if (!isAuthenticated) { return redirect('/sign-in') } return {} } export default function Index() { return (

Index route

You are signed in!

) } ``` ## Create your first user Run your project with the following command: ```npm npm run dev ``` Visit your app's homepage at [`http://localhost:5173`](http://localhost:5173). Sign up to create your first user.
## Next steps * [Create a custom sign-in-or-up page](/docs/remix/guides/development/custom-sign-in-or-up-page) * Learn how add custom sign-in-or-up page with Clerk components. *** * [Protect content and read user data](/docs/remix/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your Remix app. *** * [Customization & localization](/docs/guides/customizing-clerk/appearance-prop/overview) * Learn how to customize and localize the Clerk components. *** * [Clerk components](/docs/reference/components/overview) * Learn more about the prebuilt components. --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: remix sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'app/routes/pricing.tsx' }} import { PricingTable } from '@clerk/remix' export default function PricingPage() { return (
) } ```
## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```tsx {{ filename: 'app/routes/bronze-content.tsx' }} import { getAuth } from '@clerk/remix/ssr.server' import { useLoaderData } from '@remix-run/react' import type { LoaderFunctionArgs } from '@remix-run/node' export const loader = async (args: LoaderFunctionArgs) => { const { has } = await getAuth(args) return { hasBronzePlan: has({ plan: 'bronze' }) } } export default function BronzeContentPage() { const { hasBronzePlan } = useLoaderData() if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```tsx {{ filename: 'app/routes/premium-content.tsx' }} import { getAuth } from '@clerk/remix/ssr.server' import { useLoaderData } from '@remix-run/react' import type { LoaderFunctionArgs } from '@remix-run/node' export const loader = async (args: LoaderFunctionArgs) => { const { has } = await getAuth(args) return { hasPremiumAccess: has({ feature: 'premium_access' }) } } export default function PremiumContentPage() { const { hasPremiumAccess } = useLoaderData() if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```tsx {{ filename: 'app/routes/manage-premium-content.tsx' }} import { getAuth } from '@clerk/remix/ssr.server' import { useLoaderData } from '@remix-run/react' import type { LoaderFunctionArgs } from '@remix-run/node' export const loader = async (args: LoaderFunctionArgs) => { const { has } = await getAuth(args) return { hasPremiumAccessManage: has({ permission: 'org:premium_access:manage' }) } } export default function ManagePremiumContentPage() { const { hasPremiumAccessManage } = useLoaderData() if (!hasPremiumAccessManage) return (

Only subscribers with the Premium Access Manage permission can access this content.

) return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. ```tsx {{ filename: 'app/routes/protected-content.tsx' }} import { Protect } from '@clerk/remix' export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. ```tsx {{ filename: 'app/routes/protected-premium-content.tsx' }} import { Protect } from '@clerk/remix' export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. ```tsx {{ filename: 'app/routes/protected-manage-content.tsx' }} import { Protect } from '@clerk/remix' export default function ProtectedManageContentPage() { return ( Only subscribers with the Premium Access Manage permission can access this content.

} >

Exclusive Management Content

This content is only visible to users with Premium Access Manage permission.

) } ```
--- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: remix sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'app/routes/pricing.tsx' }} import { PricingTable } from '@clerk/remix' export default function PricingPage() { return (
) } ```
## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```tsx {{ filename: 'app/routes/bronze-content.tsx' }} import { getAuth } from '@clerk/remix/ssr.server' import { useLoaderData } from '@remix-run/react' import type { LoaderFunctionArgs } from '@remix-run/node' export const loader = async (args: LoaderFunctionArgs) => { const { has } = await getAuth(args) return { hasBronzePlan: has({ plan: 'bronze' }) } } export default function BronzeContentPage() { const { hasBronzePlan } = useLoaderData() if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if a user has a Feature. ```tsx {{ filename: 'app/routes/premium-content.tsx' }} import { getAuth } from '@clerk/remix/ssr.server' import { useLoaderData } from '@remix-run/react' import type { LoaderFunctionArgs } from '@remix-run/node' export const loader = async (args: LoaderFunctionArgs) => { const { has } = await getAuth(args) return { hasPremiumAccess: has({ feature: 'premium_access' }) } } export default function PremiumContentPage() { const { hasPremiumAccess } = useLoaderData() if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. ```tsx {{ filename: 'app/routes/protected-content.tsx' }} import { Protect } from '@clerk/remix' export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. ```tsx {{ filename: 'app/routes/protected-premium-content.tsx' }} import { Protect } from '@clerk/remix' export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
--- title: Build your own sign-in-or-up page for your Remix app with Clerk description: Learn how to add a custom sign-in-or-up page to your Remix app with Clerk's prebuilt components. sdk: nextjs, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/custom-sign-in-or-up-page lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,remix,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/guides/development/custom-sign-in-or-up-page.remix.mdx --- > \[!WARNING] > The Remix SDK is in maintenance mode and will only receive security updates. Please migrate to the React Router SDK for continued development and new features. This guide shows you how to use the \ component to build a custom page **that allows users to sign in or sign up within a single flow**. To set up separate sign-in and sign-up pages, follow this guide, and then follow the [custom sign-up page guide](/docs/remix/guides/development/custom-sign-up-page). > \[!NOTE] > Just getting started with Clerk and Remix? See the [quickstart tutorial](/docs/remix/getting-started/quickstart)! ## Build a sign-in-or-up page The following example demonstrates how to render the \ component on a dedicated page using the [Remix optional route](https://reactrouter.com/en/main/route/route#optional-segments). ```tsx {{ filename: 'app/routes/sign-in.$.tsx' }} import { SignIn } from '@clerk/remix' export default function Page() { return } ``` ## Configure your sign-in-or-up page * Set the `CLERK_SIGN_IN_URL` environment variable to tell Clerk where the `` component is being hosted. * Set `CLERK_SIGN_IN_FALLBACK_REDIRECT_URL` as a fallback URL incase users visit the `/sign-in` route directly. * Set `CLERK_SIGN_UP_FALLBACK_REDIRECT_URL` as a fallback URL incase users select the 'Don't have an account? Sign up' link at the bottom of the component. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```env {{ filename: '.env' }} CLERK_SIGN_IN_URL=/sign-in CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/ CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/ ``` * Set the `signInUrl` property to your `ClerkApp` options to tell Clerk where the `` component is being hosted. * Set the `signInFallbackRedirectUrl` property to a fallback URL incase users visit the `/sign-in` route directly. * Set the `signUpFallbackRedirectUrl` property to a fallback URL incase users select the 'Don't have an account? Sign up' link at the bottom of the component. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```ts {{ filename: 'app/root.tsx', mark: [[3, 4]] }} export default ClerkApp(App, { publishableKey: PUBLISHABLE_KEY, signInUrl: '/sign-in', signInFallbackRedirectUrl: '/', signUpFallbackRedirectUrl: '/', }) ``` ## Visit your new page Run your project with the following terminal command from the root directory of your project: ```npm npm run dev ``` Visit your new custom page locally at [localhost:3000/sign-in](http://localhost:3000/sign-in). ## Next steps * [Custom sign-up page](/docs/remix/guides/development/custom-sign-up-page) * Learn how to add a custom sign-up page to your Remix app with Clerk's prebuilt components. *** * [Protect content and read user data](/docs/remix/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your Remix application. --- title: Build your own sign-up page for your Remix app with Clerk description: Learn how to add a custom sign-up page to your Remix app with Clerk's prebuilt components. sdk: nextjs, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/custom-sign-up-page lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,remix,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/guides/development/custom-sign-up-page.remix.mdx --- > \[!WARNING] > The Remix SDK is in maintenance mode and will only receive security updates. Please migrate to the React Router SDK for continued development and new features. By default, the \ component handles signing in and signing up, but if you'd like to have a dedicated sign-up page, this guide shows you how to use the \ component to build a custom sign-up page. To set up a single sign-in-or-up page, follow the [custom sign-in-or-up page guide](/docs/remix/guides/development/custom-sign-in-or-up-page). > \[!NOTE] > Just getting started with Clerk and Remix? See the [quickstart tutorial](/docs/remix/getting-started/quickstart)! ## Build a sign-up page The following example demonstrates how to render the \ component on a dedicated sign-up page using the [Remix optional route](https://reactrouter.com/en/main/route/route#optional-segments). ```tsx {{ filename: 'app/routes/sign-up.$.tsx' }} import { SignUp } from '@clerk/remix' export default function Page() { return } ``` ## Configure your sign-up page * Set the `CLERK_SIGN_UP_URL` environment variable to tell Clerk where the `` component is being hosted. * Set `CLERK_SIGN_UP_FALLBACK_REDIRECT_URL` as a fallback URL incase users visit the `/sign-up` route directly. * Set `CLERK_SIGN_IN_FALLBACK_REDIRECT_URL` as a fallback URL incase users select the 'Already have an account? Sign in' link at the bottom of the component. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```env {{ filename: '.env' }} CLERK_SIGN_UP_URL=/sign-up CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/ CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/ ``` * Set the `signUpUrl` property to your `ClerkApp` options to tell Clerk where the `` component is being hosted. * Set the `signUpFallbackRedirectUrl` property to a fallback URL incase users visit the `/sign-up` route directly. * Set the `signInFallbackRedirectUrl` property to a fallback URL incase users select the 'Already have an account? Sign in' link at the bottom of the component. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```ts {{ filename: 'app/root.tsx' }} export default ClerkApp(App, { publishableKey: PUBLISHABLE_KEY, signUpUrl: '/sign-up', signUpFallbackRedirectUrl: '/', signInFallbackRedirectUrl: '/', }) ``` ## Visit your new page Run your project with the following command: ```npm npm run dev ``` Visit your new custom page locally at [localhost:3000/sign-up](http://localhost:3000/sign-up). ## Next steps * [Protect content and read user data](/docs/remix/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your Remix application. --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: remix sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: Protect content and read user data description: Learn how to use Clerk's hooks and helpers to protect content and read user data in your Remix application. metadata: title: Read session and user data in your Remix app with Clerk sdk: nextjs, expo, react-router, remix, tanstack-react-start, astro, nuxt sdkScoped: "true" canonical: /docs/:sdk:/guides/users/reading lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,expo,react-router,remix,tanstack-react-start,astro,nuxt notAvailableSdks: react,js-frontend,chrome-extension,android,ios,expressjs,fastify,go,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/guides/users/reading.remix.mdx --- > \[!WARNING] > The Remix SDK is in maintenance mode and will only receive security updates. Please migrate to the React Router SDK for continued development and new features. Clerk provides a set of [hooks and helpers](/docs/reference/remix/overview) that you can use to protect content and read user data in your Remix application. Here are examples of how to use these helpers in both the client and server-side to get you started. ## Server-side ### `getAuth()` The [`getAuth()`](/docs/reference/remix/overview#get-auth) helper allows you to access the Auth object, which includes the current user's `userId` and the `isAuthenticated` property, which can be used to protect your routes. In the following example, the `userId` is passed to the JS Backend SDK's getUser() method to get the user's full `User` object. For information on how to use the JS Backend SDK, see the reference documentation. ```tsx {{ filename: 'routes/profile.tsx' }} import { LoaderFunction, redirect } from '@remix-run/node' import { getAuth } from '@clerk/remix/ssr.server' import { createClerkClient } from '@clerk/remix/api.server' export const loader: LoaderFunction = async (args) => { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = await getAuth(args) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } // Initialize 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, ) // Return the retrieved user data return { serialisedUser: JSON.stringify(user) } } ``` ```tsx {{ filename: 'routes/profile.tsx' }} import { ActionFunction, redirect } from '@remix-run/node' import { getAuth } from '@clerk/remix/ssr.server' import { createClerkClient } from '@clerk/remix/api.server' export const action: ActionFunction = async (args) => { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = await getAuth(args) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } // Initialize the JS Backend SDK and get the user's full `Backend User` object const updatedUser = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY, }).users.getUser(userId) // Return the retrieved user data return { serialisedUser: JSON.stringify(updatedUser) } } ``` ## Client Side ### `useAuth()` {/* TODO: Keep in sync with /tanstack-react-start/read-session-data and /expo/read-session-user-data */} The following example uses the useAuth() hook to access the current auth state, as well as helper methods to manage the current session. ```tsx {{ filename: 'example.tsx' }} export default function Example() { const { isLoaded, isSignedIn, userId, sessionId, getToken } = useAuth() const fetchExternalData = async () => { // Use `getToken()` to get the current user's session token const token = await getToken() // Use `token` to fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return
Loading...
} // Use `isSignedIn` to check if the user is signed in if (!isSignedIn) { // You could also add a redirect to the sign-in page here return
Sign in to view this page
} return (
Hello, {userId}! Your current active session is {sessionId}.
) } ``` ### `useUser()` {/* TODO: Keep in sync with /reference/tanstack-react-start/read-session-data and /reference/expo/read-session-user-data */} The following example uses the useUser() hook to access the User object, which contains the current user's data such as their full name. The following example demonstrates how to use `useUser()` to check if the user is signed in and display their first name. ```tsx {{ filename: 'src/Example.tsx' }} export default function Example() { const { isSignedIn, user, isLoaded } = useUser() // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return
Loading...
} // Use `isSignedIn` to protect the content if (!isSignedIn) { return
Sign in to view this page
} // Use `user` to access the current user's data return
Hello {user.firstName}!
} ``` --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: remix sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`` component" description: Clerk's component renders a UI for authenticating users with Google's One Tap API. sdk: astro, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/google-one-tap lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: chrome-extension,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/authentication/google-one-tap.mdx --- > \[!IMPORTANT] > To use Google One Tap with Clerk, you must [enable Google as a social connection in the Clerk Dashboard](/docs/guides/configure/auth-strategies/social-connections/google#configure-for-your-production-instance) and make sure to use custom credentials. The `` component renders the [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) UI so that users can use a single button to sign-up or sign-in to your Clerk application with their Google accounts. By default, this component will redirect users back to the page where the authentication flow started. However, you can override this with force redirect URL props or [force redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). > \[!TIP] > `` does not render if the user is already signed into your Clerk application, so there's no need to manually check if a user is signed in yourself before rendering it. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/sign-in.tsx' }} import { GoogleOneTap } from '@clerk/remix' export default function Page() { return } ``` ## Properties * `cancelOnTapOutside?` * `boolean` If `true`, the One Tap prompt closes automatically if the user clicks outside of the prompt. Defaults to `true`. *** * `itpSupport?` * `boolean` If `true`, enables the [ITP-specific UX](https://developers.google.com/identity/gsi/web/guides/itp) when One Tap is rendered on ITP browsers such as Chrome on iOS, Safari, and FireFox. Defaults to `true`. *** * `fedCmSupport?` * `boolean` If `true`, enables Google One Tap to use [the FedCM API](https://developers.google.com/privacy-sandbox/3pcd/fedcm) to sign users in. See Google's docs on [best practices when disabling FedCM support](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap#do_not_cover_google_one_tap). Defaults to `true` *** * `signInForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs in, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). *** * `signUpForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs up, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). ## Limitations * If your application will use the Google API on behalf of your users, the `` component is not recommended, as Google does not provide Clerk with an access or refresh token that you can use. * Users with the 1Password browser extension may not be able to render the Google One Tap UI. They must disable this extension. * When testing in development, if you select the `X` button to close the Google One Tap UI, you may encounter [a cooldown](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown) that prevents you from rendering it again for a period of time. To bypass the cooldown, remove the `g_state` cookie. --- title: "`` component" description: Clerk's component renders a UI for signing in users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/authentication/sign-in.mdx --- ![The \ component renders a UI for signing in users.](/docs/images/ui-components/sign-in.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI to allow users to sign in or sign up by default. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. If you would like to create a dedicated `/sign-in` page in your Remix application, there are a few requirements you must follow. See the [dedicated guide](/docs/remix/guides/development/custom-sign-in-or-up-page) for more information. ```tsx {{ filename: 'app/routes/sign-in.$.tsx' }} import { SignIn } from '@clerk/remix' export default function SignInPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `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. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-in`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signUpFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Used for the 'Don't have an account? Sign up' link that's rendered. Defaults to `/`. 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 used as the redirect destination after the user signs up. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signUpUrl` * `string` The full URL or path to the sign-up page. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `transferable` * `boolean` Indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `waitlistUrl` * `string` Full URL or path to the waitlist page. Use this property to provide the target of the 'Waitlist' link that's rendered. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). If you've passed the `waitlistUrl` prop to the \ component, it will infer from that, and you can omit this prop. *** * `withSignUp` * `boolean` Opt into sign-in-or-up flow by setting this prop to `true`. When `true`, if a user does not exist, they will be prompted to sign up. If a user exists, they will be prompted to sign in. Defaults to `true` if the `CLERK_SIGN_IN_URL` environment variable is set. Otherwise, defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for signing up users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/authentication/sign-up.mdx --- ![The \ component renders a UI for signing up users.](/docs/images/ui-components/sign-up.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. If you would like to create a dedicated `/sign-up` page in your Remix application, there are a few requirements you must follow. See the [dedicated guide](/docs/remix/guides/development/custom-sign-up-page) for more information. ```tsx {{ filename: 'app/routes/sign-up.$.tsx' }} import { SignUp } from '@clerk/remix' export default function SignUpPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `string` If provided, this URL will always be used as the redirect destination 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. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-up`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signInFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Used for the 'Already have an account? Sign in' link that's rendered. 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. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signInUrl` * `string` The full URL or path to the sign-in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for resolving the `choose-organization` task. sdk: js-frontend, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/task-choose-organization lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/authentication/task-choose-organization.mdx --- ![The \ component renders a UI for resolving the choose-organization session task.](/docs/images/ui-components/task-choose-organization.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for resolving the `choose-organization` session task. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/overview). You can further customize your `` component by passing additional properties at the time of rendering. > \[!IMPORTANT] > The `` component cannot render when a user doesn't have current session tasks. ## Example The following example demonstrates how to host the `` component on a custom page. ```tsx {{ filename: 'app/root.tsx', fold: [[1, 37]], mark: [39] }} import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' import { ClerkApp } from '@clerk/remix' export const meta: MetaFunction = () => [ { charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }, ] export const loader: LoaderFunction = (args) => rootAuthLoader(args) export function Layout({ children }: { children: React.ReactNode }) { return ( {children} ) } function App() { return } export default ClerkApp(App, { taskUrls: { 'choose-organization': '/onboarding/choose-organization' }, }) ``` The `` component must be used in conjunction with the `` component. See the [dedicated guide on how to self-host the `` component](/docs/remix/guides/development/custom-sign-in-or-up-page). ```tsx {{ filename: 'app/routes/onboarding.choose-organization.tsx' }} import { TaskChooseOrganization } from '@clerk/remix' export default function ChooseOrganizationPage() { return } ``` ## Properties All props are optional. * `redirectUrlComplete` * `string` The full URL or path to navigate to after successfully completing all tasks. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: The component renders a waitlist form that allows users to join for early access to your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/waitlist lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/authentication/waitlist.mdx --- ![The \ component renders a form that allows users to join for early access to your app.](/docs/images/ui-components/waitlist.png){{ style: { maxWidth: '460px' } }} In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. [Learn more about additional features available in **Waitlist** mode](/docs/guides/secure/restricting-access#waitlist). The `` component renders a form that allows users to join for early access to your app. ## Enable Waitlist mode Before using the `` component, you must enable **Waitlist** mode in the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. ## Example > \[!WARNING] > Before using the `` component, you must provide the `waitlistUrl` prop either in the \ or \ component to ensure proper functionality. The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/waitlist.tsx' }} import { Waitlist } from '@clerk/remix' export default function WaitlistPage() { return } ``` ## Properties All props are optional. * `afterJoinWaitlistUrl` * `string` The full URL or path to navigate to after joining the waitlist. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `signInUrl` * `string` The full URL or path to the sign in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. ## Customization To learn about how to customize Clerk components, see the [customization guide](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "``" description: Clerk's component displays a table of Plans and Features that users can subscribe to. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/pricing-table lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/billing/pricing-table.mdx --- ![The \ component displays a table of Plans and Features that users can subscribe to.](/docs/images/ui-components/pricing-table.png) The `` component displays a table of Plans and Features that users can subscribe to. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/pricing.tsx' }} import { PricingTable } from '@clerk/remix' export default function PricingPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `checkoutProps` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `collapseFeatures` * `boolean` A boolean that indicates whether the Features are collapsed. **Requires `layout` to be set to `'default'`**. Defaults to `false`. *** * `ctaPosition` * `'top' | 'bottom'` The placement of the CTA button. **Requires `layout` to be set to `'default'`**. Defaults to `'bottom'`. *** * `fallback` * `JSX` An optional UI to show when the pricing table is loading. *** * `for` * `'user' | 'organization'` A string that indicates whether the pricing table is for users or [Organizations](/docs/guides/organizations/overview). If `'user'`, the pricing table will display a list of Plans and Features that **users** can subscribe to. If `'organization'`, the pricing table will display a list of Plans and Features that **Organizations** can subscribe to. Defaults to `'user'`. *** * `newSubscriptionRedirectUrl` * `string` The URL to navigate to after the user completes the checkout and selects the "Continue" button. --- title: \RedirectCallback /> description: Clerk's `` component is used to implement custom OAuth flows. It handles the OAuth callback and completes the authentication process. sdk: astro, chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/authenticate-with-redirect-callback lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: expo,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/authenticate-with-redirect-callback.mdx --- The `` component is a crucial part of implementing custom OAuth flows in your application. It serves as the callback handler for the authentication process initiated by the `authenticateWithRedirect()` method. Render it on the route specified as the `redirectUrl` in your `authenticateWithRedirect()` call. This component automatically handles the OAuth callback, completing the authentication process and managing the user's session. It uses the handleRedirectCallback() method under the hood. ## Example For an example of how to use the `` component, see the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) guide. ## Properties All props are optional. * `continueSignUpUrl?` * `string | undefined | null` The full URL or path to navigate to if the sign up requires additional information. *** * `signInUrl?` * `string` The full URL or path where the `` component is mounted. *** * `signUpUrl?` * `string` The full URL or path where the `` component is mounted. *** * `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. *** * `firstFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if first factor verification is required. *** * `secondFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) is enabled. *** * `resetPasswordUrl?` * `string` The full URL or path to navigate to during sign in, if the user is required to reset their password. *** * `transferable?` * `boolean` A boolean that indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `verifyEmailAddressUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting email verification. *** * `verifyPhoneNumberUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting phone verification. --- title: "``" description: The component indicates that Clerk is partially operational. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-degraded lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/clerk-degraded.mdx --- The `` component indicates that Clerk is partially operational. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/remix' export default function Index() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The component indicates that the Clerk object has failed to load. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-failed lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/clerk-failed.mdx --- The `` component indicates that the Clerk object has failed to load. This is useful for displaying an error message to the user. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/remix' export default function Index() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the Clerk object without the need to check it exists. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loaded lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/clerk-loaded.mdx --- The `` component guarantees that the Clerk object has loaded (the `status` is `'ready'` or `'degraded'`) and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/remix' export default function Index() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loading lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/clerk-loading.mdx --- The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/remix' export default function Index() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The Protect component protects content or even entire routes based on authentication, and optionally, authorization. It only renders its children when the current user is signed-in, and if performing authorization checks, if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/protect lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/protect.mdx --- The \ component protects content or even entire routes based on: * authentication: whether the user is signed-in or not. * authorization: whether the user has been granted a specific type of access control (Role, Permission, Feature, or Plan) `` **always** performs authentication checks. To perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., you can pass different props, like `role`, `permission`, `feature`, or `plan`. `` accepts a `fallback` prop that will be rendered if the user fails the authentication or authorization checks. `` can be used both client-side and server-side (in Server Components). > \[!CAUTION] > This component only **visually hides** its children when the current user is not authorized. The contents of its children remain accessible via the browser's source code even if the user fails the authorization check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Usage ### Authentication checks `` always performs authentication checks. It will render its children if the user is signed-in, and its `fallback` prop if the user is signed-out. ```tsx {{ filename: 'app/routes/dashboard.tsx' }} import { Protect } from '@clerk/remix' export default function DashboardPage() { return ( Users that are signed-out can see this.

}>

Users that are signed-in can see this.

) } ```
### Authorization checks To limit who is able to see the content that `` renders, you can pass **one** of the access control props: `permission`, `role`, `feature`, or `plan`. It's recommended to use **Permission-based** authorization over **Role-based** authorization, and **Feature-based** authorization over **Plan-based** authorization, as they are more flexible, easier to manage, and more secure. If you do not pass any of the access control props, `` will render its children if the user is signed in, regardless of their Role or its Permissions. For more complex authorization logic, pass conditional logic to the `condition` prop. ### Render content by Permissions The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:invoices:create` Permission. ```tsx {{ filename: 'app/routes/invoices.tsx' }} import { Protect } from '@clerk/remix' export default function InvoicesPage() { return ( You do not have the Permissions to create an invoice.

} >

Users with Permission org:invoices:create can see this.

) } ```
### Render content by Role While authorization by `permission` is **recommended**, for convenience, `` allows a `role` prop to be passed. The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:billing` Role. ```tsx {{ filename: 'app/routes/billing.tsx' }} import { Protect } from '@clerk/remix' export default function BillingPage() { return ( Only a member of the Billing department can access this content.

} >

Users with Role org:billing can see this.

) } ```
### Render content by Plan The following example demonstrates how to use `` to protect content by checking if the user has a Plan. ```tsx {{ filename: 'app/routes/bronze.tsx' }} import { Protect } from '@clerk/remix' export default function BronzePage() { return ( Sorry, only subscribers to the Bronze plan can access this content.

} >

Welcome, Bronze subscriber!

) } ```
### Render content by Feature The following example demonstrates how to use `` to protect content by checking if the user has a Feature. ```tsx {{ filename: 'app/routes/premium-access.tsx' }} import { Protect } from '@clerk/remix' export default function PremiumAccessPage() { return ( Sorry, only subscribers with the Premium Access feature can access this content.

} >

Congratulations! You have access to the Premium Access feature.

) } ```
### Render content conditionally The following example uses ``'s `condition` prop to conditionally render its children if the user has the correct Role. ```tsx {{ filename: 'app/routes/settings.tsx' }} import { Protect } from '@clerk/remix' export default function SettingsPage() { return ( has({ role: 'org:admin' }) || has({ role: 'org:billing_manager' })} fallback={

Only an Admin or Billing Manager can access this content.

} >

The settings page.

) } ```
## Properties * `condition?` * `has => boolean` Optional conditional logic that renders the children if it returns `true`. *** * `fallback?` * `JSX` Optional UI to show when a user doesn't have the correct type of access control to access the protected content. *** * `feature?` * `string` Optional string corresponding to a [Feature](/docs/guides/billing/overview). *** * `plan?` * `string` Optional string corresponding to a [Plan](/docs/guides/billing/overview). *** * `permission?` * `string` Optional string corresponding to a [Permission](/docs/guides/organizations/roles-and-permissions) in the format `org::` *** * `role?` * `string` Optional string corresponding to a [Role](/docs/guides/organizations/roles-and-permissions) in the format `org:` *** * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` (deprecated)" description: The component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/redirect-to-create-organization.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToCreateOrganization() method instead. The `` component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignedIn, SignedOut, RedirectToCreateOrganization } from '@clerk/remix' export default function Index() { return (

You need to sign in to create an Organization.

) } ```
--- title: "`` (deprecated)" description: The component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/redirect-to-organization-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToOrganizationProfile() method instead. The `` component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignedIn, SignedOut, RedirectToOrganizationProfile } from '@clerk/remix' export default function Index() { return (

You need to sign in to view your Organization profile.

) } ```
--- title: "``" description: The component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/redirect-to-sign-in.mdx --- The `` component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignedIn, SignedOut, RedirectToSignIn, UserButton } from '@clerk/remix' export default function Index() { return (
) } ```
--- title: "`` (deprecated)" description: The component will navigate to the user profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/redirect-to-user-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToUserProfile() method instead. The `` component will navigate to the Account Portal User Profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. To find your User Profile URL: 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Under **User profile**, select the **Visit** icon. ## Example ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignedIn, SignedOut, RedirectToUserProfile } from '@clerk/remix' export default function Index() { return (

You need to sign in to view your user profile.

) } ```
--- title: "``" description: The component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/redirect-to-sign-up.mdx --- The `` component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignedIn, SignedOut, RedirectToSignUp, UserButton } from '@clerk/remix' export default function Index() { return (
) } ```
--- title: "``" description: Conditionally render content only when a user is signed in. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/signed-in.mdx --- ## Overview The `` component offers authentication checks as a cross-cutting concern. Any children components wrapped by a `` component will be rendered only if there's a user with an active session signed in your application. > \[!CAUTION] > This component only **visually hides** its children when the current user is not authenticated. The contents of its children remain accessible via the browser's source code even if the user fails the authentication check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Example ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignedIn } from '@clerk/remix' export default function Index() { return (

You are signed in.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: Conditionally render content only when a user is signed out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-out lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/control/signed-out.mdx --- The `` component offers authentication checks as a cross-cutting concern. Any child nodes wrapped by a `` component will be rendered only if there's no User signed in to your application. ## Example ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignedOut } from '@clerk/remix' export default function Index() { return (

You are signed out.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` component" description: Clerk's component is used to render an Organization creation UI that allows users to create brand new Organizations within your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/organization/create-organization.mdx --- ![The \ component renders an Organization creation UI that allows users to create brand new organizations within your application.](/docs/images/ui-components/create-organization.png){{ style: { maxWidth: '492px' } }} The `` component is used to render an Organization creation UI that allows users to create brand new Organizations in your application. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/create-organization.tsx' }} import { CreateOrganization } from '@clerk/remix' export default function CreateOrganizationPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterCreateOrganizationUrl` * `string` Full URL or path to navigate to after creating a new organization. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/create-organization`. *** * `skipInvitationScreen` * `boolean` Hides the screen for sending invitations after an Organization is created. When left undefined, Clerk will automatically hide the screen if the number of max allowed members is equal to 1 *** * `hideSlug` * `boolean` Hides the optional slug field in the Organization creation screen. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to display Organization related memberships, invitations, and suggestions for the user. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/organization/organization-list.mdx --- ![The \ component displays Organization-related memberships and automatic invitations and suggestions for the user.](/docs/images/ui-components/organization-list.png){{ style: { maxWidth: '460px' } }} The `` component displays Organization-related memberships and automatic [invitations](/docs/guides/organizations/verified-domains#automatic-invitations) and [suggestions](/docs/guides/organizations/verified-domains#automatic-suggestions) for the user. ## Example ```tsx {{ filename: 'app/routes/organizations.tsx' }} import { OrganizationList } from '@clerk/remix' export default function OrganizationListPage() { return ( `/organization/${org.slug}`} afterSelectPersonalUrl={(user) => `/user/${user.id}`} afterSelectOrganizationUrl={(org) => `/organization/${org.slug}`} /> ) } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after creating a new Organization. *** * `afterSelectOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting an Organization. Defaults to `undefined`. *** * `afterSelectPersonalUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting the [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts). Defaults to `undefined`. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. Defaults to `false`. *** * `skipInvitationScreen` * `boolean | undefined` A boolean that controls whether the screen for sending invitations after an Organization is created is hidden. When `undefined`, Clerk will automatically hide the screen if the number of max allowed members is equal to 1. Defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [org-ref]: /docs/reference/javascript/organization --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured Organization management UI that allows users to manage their Organization profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/organization/organization-profile.mdx --- ![The \ component allows users to manage their Organization membership and security settings.](/docs/images/ui-components/organization-profile.png) The `` component allows users to manage their Organization membership, security, and billing settings. This component's **General** tab displays the Organization's information and the **Leave organization** button. Admins will be able to see the **Update profile** button, **Verified domains** section, and **Delete organization** button. The **Members** tab shows the Organization's members along with their join dates and Roles. Admins will have the ability to invite a member, change a member's Role, or remove them from the Organization. Admins will have tabs within the **Members** tab to view the Organization's [invitations](/docs/guides/organizations/overview#organization-invitations) and [requests](/docs/guides/organizations/verified-domains#membership-requests). The **Billing** tab displays the Plans and Features that are available to the Organization, as well as the user's billing information, such as their invoices and payment methods. ## Example ```tsx {{ filename: 'app/routes/organization-profile.tsx' }} import { OrganizationProfile } from '@clerk/remix' export default function OrganizationProfilePage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after leaving an Organization. *** * `customPages` * `CustomPages[]` An array of custom pages to add to the Organization profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/organization-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash- and virtual-based routing.
For example: `/organization-profile`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages.
Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React.
## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages](/docs/guides/customizing-clerk/adding-items/organization-profile) documentation. --- title: "`` component" description: Clerk's component is used to enable the ability to switch between available Organizations the user may be part of in your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-switcher lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/organization/organization-switcher.mdx --- ![The \ component allows a user to switch between their account types - their Personal Account and their joined Organizations.](/docs/images/ui-components/organization-switcher.png){{ style: { maxWidth: '436px' } }} The `` component allows a user to switch between their joined Organizations. If [Personal Accounts are enabled](/docs/guides/organizations/overview#allow-personal-accounts), users can also switch to their Personal Account. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple Organizations. It handles all Organization-related flows, including full Organization management for admins. Learn more about [Organizations](/docs/guides/organizations/overview). ## Example ```tsx {{ filename: 'app/routes/organization-switcher.tsx' }} import { OrganizationSwitcher } from '@clerk/remix' export default function OrganizationSwitcherPage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * `string` The full URL or path to navigate to after creating a new Organization. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after the user leaves the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `afterSelectOrganizationUrl` * `string` The full URL or path to navigate to after a successful Organization switch. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `createOrganizationMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the "Create organization" button will cause the \ component to open as a modal, or if the browser will navigate to the `createOrganizationUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `createOrganizationUrl` * `string` The full URL or path where the ``]createorg-ref component is mounted. *** * `defaultOpen` * `boolean` A boolean that controls the default state of the `` component. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. *** * `organizationProfileMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the **Manage organization** button will cause the \ component to open as a modal, or if the browser will navigate to the `organizationProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `organizationProfileProps` * `object` Specify options for the underlying \ component. For example: `{appearance: {...}}` *** * `organizationProfileUrl` * `string` The full URL or path where the \ component is mounted. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [createorg-ref]: /docs/reference/components/organization/create-organization [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "``" description: The component is a button that links to the sign-in page or displays the sign-in modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/unstyled/sign-in-button.mdx --- The `` component is a button that, by default, links to your app's sign-in page. Your sign-in page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-in page. ## Usage ### Basic usage ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignInButton } from '@clerk/remix' export default function Home() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignInButton } from '@clerk/remix' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-in route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'`. *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. --- title: "``" description: The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. sdk: expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-with-metamask lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/unstyled/sign-in-with-metamask.mdx --- The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. ## Usage ### Basic usage ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignInWithMetamaskButton } from '@clerk/remix' export default function Home() { return } ``` ### Custom usage In some cases, you will want to use your own button, or button text. You can do that by wrapping your button in the `` component. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignInWithMetamaskButton } from '@clerk/remix' export default function Home() { return ( ) } ``` --- title: "``" description: The component is a button that links to the sign-up page or displays the sign-up modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-up-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/unstyled/sign-up-button.mdx --- The `` component is a button that, by default, links to your app's sign-up page. Your sign-up page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-up page. ## Usage ### Basic usage ```jsx {{ filename: 'src/routes/_index.tsx' }} import { SignUpButton } from '@clerk/remix' export default function Home() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignUpButton } from '@clerk/remix' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-up route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'` *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). --- title: "``" description: The `` component is a button that signs a user out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-out-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/unstyled/sign-out-button.mdx --- The `` component is a button that signs a user out. By default, it is a ` ) } ``` ### Multi-session usage #### Sign out of all sessions Clicking the `` component signs the user out of all sessions. This is the default behavior. #### Sign out of a specific session You can sign out of a specific session by passing in a `sessionId` to the `sessionId` prop. This is useful for signing a single account out of a [multi-session application](/docs/guides/secure/session-options#multi-session-applications). In the following example, the `sessionId` is retrieved from the useAuth() hook. If the user is not signed in, the `sessionId` will be `null`, and the user is shown the \ component. If the user is signed in, the user is shown the `` component, which when clicked, signs the user out of that specific session. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignInButton, SignOutButton, useAuth } from '@clerk/remix' export default function Home() { const { sessionId } = useAuth() if (!sessionId) { return } return } ``` ## Properties * `redirectUrl?` * `string` The full URL or path to navigate after successful sign-out. *** * `sessionId?` * `string` The ID of a specific session to sign out of. Useful for [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. --- title: "`` component" description: Clerk's component is used to render the familiar user button UI popularized by Google. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/user/user-button.mdx --- ![The \ component renders the familiar user button UI popularized by Google.](/docs/images/ui-components/user-button.png){{ style: { maxWidth: '436px' } }} The `` component renders the familiar user button UI popularized by Google. When selected, it opens a dropdown menu with options to manage account settings and sign out. The "Manage account" option launches the \ component, providing access to profile and security settings. For users that have [multi-session](/docs/guides/secure/session-options#multi-session-applications) enabled, the `` also allows users to sign into multiple accounts at once and instantly switch between them without the need for a full page reload. Learn more [here](/docs/guides/secure/session-options#multi-session-applications). ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar and be able to open the popup menu. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignedIn, UserButton, SignInButton, SignedOut } from '@clerk/remix' export default function Index() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `afterMultiSessionSingleSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterMultiSessionSingleSignOutUrl` to \.** The full URL or path to navigate to after signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterSignOutUrl` to \.** The full URL or path to navigate to after a successful sign-out. *** * `afterSwitchSessionUrl` * `string` The full URL or path to navigate to after a successful account change in a multi-session app. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `defaultOpen` * `boolean` Controls whether the `` should open by default during the first render. *** * `showName` * `boolean` Controls if the user name is displayed next to the user image button. *** * `signInUrl` * `string` The full URL or path to navigate to when the **Add another account** button is clicked. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `userProfileMode` * `'modal' | 'navigation'` Controls whether selecting the **Manage your account** button will cause the \ component to open as a modal, or if the browser will navigate to the `userProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `userProfileProps` * `object` Specify options for the underlying \ component. For example: `{additionalOAuthScopes: {google: ['foo', 'bar'], github: ['qux']}}`. *** * `userProfileUrl` * `string` The full URL or path leading to the user management interface. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). You can also [add custom actions and links to the `` menu](/docs/guides/customizing-clerk/adding-items/user-button). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/user/user-profile.mdx --- ![The \ component renders a full-featured account management UI that allows users to manage their profile and security settings.](/docs/images/ui-components/user-profile.png){{ style: { maxWidth: '100%' } }} The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile, security, and billing settings. ## Example The `` component must be embedded using the [Remix optional route](https://reactrouter.com/en/main/route/route#optional-segments) in order for the routing to work. ```tsx {{ filename: 'app/routes/user.$.tsx' }} import { UserProfile } from '@clerk/remix' export default function UserProfilePage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/user-profile`. *** * `additionalOAuthScopes` * `object` Specify additional scopes per OAuth provider that your users would like to provide if not already approved. For example: `{google: ['foo', 'bar'], github: ['qux']}`. *** * `customPages` * CustomPage\[] An array of custom pages to add to the user profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/user-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages documentation](/docs/guides/customizing-clerk/adding-items/user-profile). --- title: "`` component" description: Clerk's component is used to render the familiar user avatar on its own. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-avatar lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/components/user/user-avatar.mdx --- ![The \ component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications.](/docs/images/ui-components/user-avatar.png) The `` component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications. ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar. ```tsx {{ filename: 'app/routes/_index.tsx' }} import { SignedIn, UserAvatar, SignInButton, SignedOut } from '@clerk/remix' export default function Index() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `rounded?` * `boolean` Determines whether the user avatar is displayed with rounded corners. *** * `appearance?` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` Optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: Hooks Reference description: A list of Clerk's comprehensive suite of hooks for managing authentication, sessions, sign-in and sign-up flows, Organizations, and reverification. sdk: astro, chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/hooks/overview.mdx --- Clerk offers a comprehensive suite of hooks that expose low-level access to authentication, session management, and multi-tenancy. With Clerk hooks, you can access and manage user data, handle sign-in and sign-up flows, control session management, and implement advanced flows like session reverification for sensitive actions. By using these hooks, you can extend or replace Clerk's built-in components and customize how authentication behaves in your application. ## Hooks * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`useOrganizationList()`" description: Access and manage the current user's Organization list in your React application with Clerk's useOrganizationList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/hooks/use-organization-list.mdx --- The `useOrganizationList()` hook provides access to the current user's Organization memberships, invitations, and suggestions. It also includes methods for creating new Organizations and managing the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganizationList()` accepts a single object with the following properties: | Property | Type | Description | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`userInvitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`userMemberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & object & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • Any of the properties described in Shared properties.
| |
`userSuggestions?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "pending" \| "accepted" \| ("pending" \| "accepted")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the suggestions by the provided status.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `userMemberships`, `userInvitations`, and `userSuggestions` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | ## Returns | Property | Type | Description | | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createOrganization` | undefined \| (CreateOrganizationParams: CreateOrganizationParams) => Promise\<OrganizationResource\> | A function that returns a `Promise` which resolves to the newly created `Organization`. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization and there is an authenticated user. Initially `false`, becomes `true` once Clerk loads with a user. | | `setActive` | undefined \| (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. | | `userInvitations` | PaginatedResourcesWithDefault\<UserOrganizationInvitationResource\> \| PaginatedResources\<UserOrganizationInvitationResource, T\["userInvitations"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization invitations. | | `userMemberships` | PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["userMemberships"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization memberships. | | `userSuggestions` | PaginatedResourcesWithDefault\<OrganizationSuggestionResource\> \| PaginatedResources\<OrganizationSuggestionResource, T\["userSuggestions"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of suggestions for organizations that the user can join. | ### `CreateOrganizationParams` | Property | Type | Description | | ------------------------- | -------- | ----------------------------- | | `name` | `string` | The name of the organization. | | `slug?` | `string` | The slug of the organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expanding and paginating attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. So by default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // userMemberships.data will never be populated const { userMemberships } = useOrganizationList() // Use default values to fetch userMemberships, such as initialPage = 1 and pageSize = 10 const { userMemberships } = useOrganizationList({ userMemberships: true, }) // Pass your own values to fetch userMemberships const { userMemberships } = useOrganizationList({ userMemberships: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `userMemberships` attribute will be populated with the first page of the user's Organization memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `userInvitations` attribute will be populated with the first page of invitations. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of invitations. Notice the difference between this example's pagination and the infinite pagination example above. ## Related guides * [Build a custom Organization switcher](/docs/guides/development/custom-flows/organizations/organization-switcher) * Use Clerk's API to build a custom flow for switching between Organizations *** * [Create Organizations](/docs/guides/development/custom-flows/organizations/create-organizations) * Use Clerk's API to build a custom flow for creating Organizations *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: useOrganization() description: Access and manage the currently active Organization in your React application with Clerk's useOrganization() hook. search: rank: 1 sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/hooks/use-organization.mdx --- The `useOrganization()` hook retrieves attributes of the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganization()` accepts a single object with the following optional properties: | Property | Type | Description | | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `domains?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ enrollmentMode?: "manual\_invitation" \| "automatic\_invitation" \| "automatic\_suggestion"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `enrollmentMode`: A string that filters the domains by the provided [enrollment mode](/docs/guides/organizations/verified-domains#enrollment-mode).
  • Any of the properties described in Shared properties.
| |
`invitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: ("expired" \| "pending" \| "accepted" \| "revoked")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`membershipRequests?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the membership requests by the provided status.
  • Any of the properties described in Shared properties.
| |
`memberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ query?: string; role?: string\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `role`: An array of OrganizationCustomRoleKey.
  • `query`: A string that filters the memberships by the provided string.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes aren't populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `invitations`, `membershipRequests`, `memberships`, and `domains` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | > \[!NOTE] > These attributes are updating automatically and will re-render their respective components whenever you set a different Organization using the setActive(\{ organization }) method or update any of the memberships or invitations. No need for you to manage updating anything manually. ## Returns | Property | Type | Description | | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `domains` | null \| PaginatedResourcesWithDefault\<OrganizationDomainResource\> \| PaginatedResources\<OrganizationDomainResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's domains. | | `invitations` | null \| PaginatedResourcesWithDefault\<OrganizationInvitationResource\> \| PaginatedResources\<OrganizationInvitationResource, T\["invitations"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's invitations. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `membership` | undefined \| null \| OrganizationMembershipResource | The current organization membership. | | `membershipRequests` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipRequestResource\> \| PaginatedResources\<OrganizationMembershipRequestResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's membership requests. | | `memberships` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["memberships"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's memberships. | | `organization` | undefined \| null \| OrganizationResource | The currently active organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expand and paginate attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // invitations.data will never be populated. const { invitations } = useOrganization() // Use default values to fetch invitations, such as initialPage = 1 and pageSize = 10 const { invitations } = useOrganization({ invitations: true, }) // Pass your own values to fetch invitations const { invitations } = useOrganization({ invitations: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { invitations } = useOrganization({ invitations: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of memberships. Notice the difference between this example's pagination and the infinite pagination example above. ## Related guides * [Update an Organization](/docs/guides/development/custom-flows/organizations/update-organizations) * Use Clerk's API to build a custom flow for updating an Organization *** * [Manage Roles in an Organization](/docs/guides/development/custom-flows/organizations/manage-roles) * Use Clerk's API to build a custom flow for managing Roles in an Organization *** * [Manage an Organization's membership requests](/docs/guides/development/custom-flows/organizations/manage-membership-requests) * Use Clerk's API to build a custom flow for managing an Organization's membership requests *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: useReverification() description: Clerk's useReverification() hook enhances a fetcher function to handle a session's reverification flow. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-reverification lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/hooks/use-reverification.mdx --- > \[!WARNING] > > Depending on the SDK you're using, this feature requires `@clerk/nextjs@6.12.7` or later, `@clerk/clerk-react@5.25.1` or later, `@clerk/clerk-js@5.57.1` or later and `@clerk/clerk-sdk-ruby@3.3.0` or later. Reverification allows you to prompt a user to verify their credentials before performing sensitive actions, even if they're already authenticated. For example, in a banking application, transferring money is considered a "sensitive action." Reverification can be used to confirm the user's identity. The `useReverification()` hook is used to handle a session's reverification flow. If a request requires reverification, a modal will display, prompting the user to verify their credentials. Upon successful verification, the original request will automatically retry. If you'd like to build a custom UI, you can use the onNeedsReverification option. When using reverification, a user's credentials are valid for 10 minutes. Once stale, a user will need to reverify their credentials. This time duration can be customized by using the `has()` helper on the server-side. See the [guide on reverification](/docs/guides/secure/reverification) for more information. ## Parameters | Parameter | Type | Description | | ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `fetcher` | `Fetcher extends (...args: any[]) => Promise` | A function that returns a promise. | | `options?` | `Options` | Optional configuration object extending UseReverificationOptions. | ### `UseReverificationOptions` The optional options object. | Property | Type | Description | | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | `onNeedsReverification?` | (properties: NeedsReverificationParameters) => void | Handler for the reverification process. Opts out of using the default UI. Use this to build a custom UI. | ### `NeedsReverificationParameters` | Property | Type | Description | | -------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `cancel` | () => void | Marks the reverification process as cancelled and rejects the original request. | | `complete` | () => void | Marks the reverification process as complete and retries the original request. | | `level` | undefined \| "first\_factor" \| "second\_factor" \| "multi\_factor" | The verification level required for the reverification process. | ## Examples The `useReverification()` hook displays a prebuilt UI when the user needs to reverify their credentials. You can also build a custom UI to handle the reverification process yourself. Use the following tabs to see examples of either option. ### Handle reverification for an action The following example demonstrates how to use the `useReverification()` hook to require a user to reverify their credentials before being able to update their primary email address. It also demonstrates how to handle the cancellation of the reverification process. ### Handle reverification for a fetcher function The following example demonstrates how to use the `useReverification()` hook to enhance a fetcher function that fetches data from a route that requires reverification. For examples on how to set up a route that requires reverification, see the [guide on reverification](/docs/guides/secure/reverification). ```tsx {{ filename: 'components/AccountBalance.tsx' }} import { useReverification } from '@clerk/remix' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' export function AccountBalance() { const [balance, setBalance] = useState(null) const accountBalance = useReverification(async () => { const response = await fetch('/api/balance') return await response.json() }) const handleClick = async () => { try { const accountBalanceResponse = await accountBalance() setBalance(accountBalanceResponse.amount) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your account balance is {balance ? `$${balance}` : '$******'}
) } ```
The following example demonstrates how to build a custom UI when using the `useReverification()` hook. In the example, the `useReverification()` hook is used to require a user to reverify their credentials before being able to update their primary email address. It requires two components: the `` component displays the list of email addresses to choose from and it renders the second component, ``, which handles the reverification process. The example handles first factor verification using an email code, so you will need to have the [**Email verification code**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) setting enabled for your application. But you can adapt this example to handle any type of verification level or strategy. The `` component uses `useReverification()` to enhance the `update()` method, requiring the user to reverify their credentials before being able to update their primary email address. The `useReverification()` hook provides the `onNeedsReverification` option, which is a handler for building a custom UI. It provides four properties: `level`, `complete`, `cancel`, and `inProgress`. The example tracks these using the `verificationState` state variable. * The `level` property determines the verification level required for the reverification process. This example only handles first factor verification, which is done in the `` component. * The `complete` and `cancel` properties are the steps of the reverification process, which is also done in the `` component. * The `inProgress` property is used to track the state of the reverification process. When the user selects the "Make primary" button, it triggers the reverification process and sets the `inProgress` property is `true`, which displays the `` component. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/remix' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' import { SessionVerificationLevel } from '@clerk/types' import { VerificationComponent } from './VerificationComponent' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // TODO: Update to use exported type once available const [verificationState, setVerificationState] = useState< | { complete: () => void cancel: () => void level: SessionVerificationLevel | undefined inProgress: boolean } | undefined >(undefined) // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification( (emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), { onNeedsReverification: ({ complete, cancel, level }) => { setVerificationState({ complete, cancel, level, inProgress: true, }) }, }, ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {user?.primaryEmailAddressId !== email.id && ( )}
  • ))}
{verificationState?.inProgress && ( { verificationState.complete() setVerificationState(undefined) }} onCancel={() => { verificationState.cancel() setVerificationState(undefined) }} /> )}
) } ```
The `` component handles the reverification process. It uses the `level` property to determine the verification level, which is set to `first_factor`. First, it finds the determined starting first factor from the supported first factors. Then, it prepares the first factor verification using the `strategy` (`email_code` in this case) and `emailAddressId` properties. Finally, it attempts to verify the session with email code provided by the user. If the verification is successful, the `onComplete()` handler is called to complete the reverification process. ```tsx {{ filename: 'components/VerificationComponent.tsx', collapsible: true }} import { useEffect, useRef, useState } from 'react' import { useSession } from '@clerk/remix' import { EmailCodeFactor, SessionVerificationLevel, SessionVerificationResource, } from '@clerk/types' export function VerificationComponent({ level = 'first_factor', onComplete, onCancel, }: { level: SessionVerificationLevel | undefined onComplete: () => void onCancel: () => void }) { const { session } = useSession() const [code, setCode] = useState('') const reverificationRef = useRef(undefined) const [determinedStartingFirstFactor, setDeterminedStartingFirstFactor] = useState< EmailCodeFactor | undefined >() useEffect(() => { if (reverificationRef.current) { return } session?.startVerification({ level }).then(async (response) => { reverificationRef.current = response await prepareEmailVerification(response) }) }, []) const prepareEmailVerification = async (verificationResource: SessionVerificationResource) => { // To simplify the example we will only handle the first factor verification if (verificationResource.status === 'needs_first_factor') { // Determine the starting first factor from the supported first factors const determinedStartingFirstFactor = verificationResource.supportedFirstFactors?.filter( (factor) => factor.strategy === 'email_code', )[0] if (determinedStartingFirstFactor) { setDeterminedStartingFirstFactor(determinedStartingFirstFactor) // Prepare the first factor verification with the determined starting first factor await session?.prepareFirstFactorVerification({ strategy: determinedStartingFirstFactor.strategy, emailAddressId: determinedStartingFirstFactor?.emailAddressId, }) } } } const handleVerificationAttempt = async () => { try { // Attempt to verify the session with the provided code await session?.attemptFirstFactorVerification({ strategy: 'email_code', code, }) onComplete() } catch (e) { // Any error from the attempt to verify the session can be handled here console.error('Error verifying session', e) } } if (!determinedStartingFirstFactor) { return null } return (

Enter verification code sent to {determinedStartingFirstFactor.safeIdentifier || ''}

setCode(e.target.value)} />
) } ```
## Related guides See the custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). guides for examples of how to use the `useReverification()` hook, such as the [Add a phone number to a user's account](/docs/guides/development/custom-flows/account-updates/add-phone) guide. --- title: React Router Quickstart description: Learn how to use Clerk to quickly and easily add secure authentication and user management to your React Router application. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: react-router sourceFile: /docs/getting-started/quickstart.react-router.mdx --- 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/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: ```npm npm install @clerk/react-router ``` ## Set your Clerk API keys Add the following keys to your `.env` file. These keys can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, copy your Clerk Publishable and Secret Key. 3. Paste your keys into your `.env` file. The final result should resemble the following: ```env {{ filename: '.env' }} VITE_CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} ``` ## Add `clerkMiddleware()` and `rootAuthLoader()` to your app `clerkMiddleware()` grants you access to user authentication state throughout your app. 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 ``` 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 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} ) } export default function App() { return } 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}
          
)}
) } ``` ## Add `` and Clerk components to your app The \ component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with `` to make authentication globally accessible. See the reference docs for other configuration options. It's required to pass `loaderData` to the `` component. This data is provided by the `rootAuthLoader()` function. The following example adds `` and creates a header using the following Clerk components: * \: Children of this component can only be seen while **signed in**. * \: Children of this component can only be seen while **signed out**. * \: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. * \: 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', mark: [44, [46, 58], 60], 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 */}
) } 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 Run your project with the following command: ```npm npm run dev ``` Visit your app's homepage at [`http://localhost:5173`](http://localhost:5173). Sign up to create your first user.
## Next steps * [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. *** * [Protect content and read user data](/docs/react-router/guides/users/reading) * Learn how to use Clerk's hooks and helpers to protect content and read user data in your React Router app. *** * [Declarative mode](/docs/guides/development/declarative-mode) * Learn how to use Clerk with React Router in declarative mode to add authentication to your application. --- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: react-router sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'app/routes/pricing.tsx' }} import type { Route } from './+types/pricing' import { PricingTable } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Pricing' }] } export default function PricingPage() { return (
) } ```
## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```tsx {{ filename: 'app/routes/bronze-content.tsx' }} import type { Route } from './+types/bronze-content' import { useAuth } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Bronze Content' }] } export default function BronzeContentPage() { const { has, isLoaded } = useAuth() if (!isLoaded) return
Loading...
const hasBronzePlan = has({ plan: 'bronze' }) if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if a user has a Feature. ```tsx {{ filename: 'app/routes/premium-content.tsx' }} import type { Route } from './+types/premium-content' import { useAuth } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Page' }] } export default function PremiumContentPage() { const { isLoaded, has } = useAuth() if (!isLoaded) return
Loading...
const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. ```tsx {{ filename: 'app/routes/protected-content.tsx' }} import type { Route } from './+types/protected-content' import { Protect } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Protected Content' }] } export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. ```tsx {{ filename: 'app/routes/protected-premium-content.tsx' }} import type { Route } from './+types/protected-premium-content' import { Protect } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Protected Premium Content' }] } export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
--- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: react-router sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'app/routes/pricing.tsx' }} import type { Route } from './+types/pricing' import { PricingTable } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Pricing' }] } export default function PricingPage() { return (
) } ```
## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```tsx {{ filename: 'app/routes/bronze-content.tsx' }} import type { Route } from './+types/bronze-content' import { useAuth } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Bronze Content' }] } export default function BronzeContentPage() { const { has, isLoaded } = useAuth() if (!isLoaded) return
Loading...
const hasBronzePlan = has({ plan: 'bronze' }) if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```tsx {{ filename: 'app/routes/premium-content.tsx' }} import type { Route } from './+types/premium-content' import { useAuth } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Page' }] } export default function PremiumContentPage() { const { isLoaded, has } = useAuth() if (!isLoaded) return
Loading...
const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```tsx {{ filename: 'app/routes/manage-premium-content.tsx' }} import type { Route } from './+types/manage-premium-content' import { useAuth } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Manage Premium Content' }] } export default function ManagePremiumContentPage() { const { has, isLoaded } = useAuth() if (!isLoaded) return
Loading...
const hasPremiumAccessManage = has({ permission: 'org:premium_access:manage' }) if (!hasPremiumAccessManage) return (

Only subscribers with the Premium Access Manage permission can access this content.

) return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. ```tsx {{ filename: 'app/routes/protected-content.tsx' }} import type { Route } from './+types/protected-content' import { Protect } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Protected Content' }] } export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. ```tsx {{ filename: 'app/routes/protected-premium-content.tsx' }} import type { Route } from './+types/protected-premium-content' import { Protect } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Protected Premium Content' }] } export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. ```tsx {{ filename: 'app/routes/protected-manage-content.tsx' }} import type { Route } from './+types/protected-manage-content' import { Protect } from '@clerk/react-router' export function meta({}: Route.MetaArgs) { return [{ title: 'Protected Manage Content' }] } export default function ProtectedManageContentPage() { return ( Only subscribers with the Premium Access Manage permission can access this content.

} >

Exclusive Management Content

This content is only visible to users with Premium Access Manage permission.

) } ```
--- title: Build your own sign-up page for your React Router app with Clerk description: Learn how to add a custom sign-up page to your React Router app with Clerk's prebuilt components. sdk: nextjs, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/custom-sign-up-page lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,remix,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/guides/development/custom-sign-up-page.react-router.mdx --- By default, the \ component handles signing in and signing up, but if you'd like to have a dedicated sign-up page, this guide shows you how to use the \ component to build a custom sign-up page. To set up a single sign-in-or-up page, follow the [custom sign-in-or-up page guide](/docs/react-router/guides/development/custom-sign-in-or-up-page). > \[!NOTE] > Just getting started with Clerk and React Router? See the [quickstart tutorial](/docs/react-router/getting-started/quickstart)! ## Build a sign-up page The following example demonstrates how to render the \ component on a dedicated sign-up page using the [React Router Splat route](https://reactrouter.com/start/framework/routing#splats). ```tsx {{ filename: 'app/routes/sign-up.tsx' }} import { SignUp } from '@clerk/react-router' export default function SignUpPage() { return (

Sign up route

) } ``` ## Configure routes React Router expects you to define routes in [`app/routes.ts`](https://reactrouter.com/start/framework/routing). Add the previously created sign-up page to your route configuration. ```tsx {{ filename: 'app/routes.ts', mark: [6] }} import { type RouteConfig, index, route } from '@react-router/dev/routes' export default [ index('routes/home.tsx'), route('sign-in/*', 'routes/sign-in.tsx'), route('sign-up/*', 'routes/sign-up.tsx'), ] satisfies RouteConfig ``` ## Configure redirect behavior * Set the `CLERK_SIGN_UP_URL` environment variable to tell Clerk where the `` component is being hosted. * Set `CLERK_SIGN_UP_FALLBACK_REDIRECT_URL` as a fallback URL incase users visit the `/sign-up` route directly. * Set `CLERK_SIGN_IN_FALLBACK_REDIRECT_URL` as a fallback URL incase users select the 'Already have an account? Sign in' link at the bottom of the component. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```env {{ filename: '.env' }} CLERK_SIGN_UP_URL=/sign-up CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/ CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/ ``` These values control the behavior of the `` and `` components and when you visit the respective links at the bottom of each component. ## Visit your new page Run your project with the following command: ```npm npm run dev ``` Visit your new custom page locally at [localhost:5173/sign-up](http://localhost:5173/sign-up).
--- title: Build your own sign-in-or-up page for your React Router app with Clerk description: Learn how to add a custom sign-in-or-up page to your React Router app with Clerk's prebuilt components. sdk: nextjs, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/custom-sign-in-or-up-page lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,remix,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/guides/development/custom-sign-in-or-up-page.react-router.mdx --- This guide shows you how to use the \ component to build a custom page **that allows users to sign in or sign up within a single flow**. To set up separate sign-in and sign-up pages, follow this guide, and then follow the [custom sign-up page guide](/docs/react-router/guides/development/custom-sign-up-page). ## Build a sign-in-or-up page The following example demonstrates how to render the \ component on a dedicated page using the [React Router Splat route](https://reactrouter.com/start/framework/routing#splats). ```tsx {{ filename: 'app/routes/sign-in.tsx' }} import { SignIn } from '@clerk/react-router' export default function SignInPage() { return (

Sign in or up route

) } ``` ## Configure routes React Router expects you to define routes in [`app/routes.ts`](https://reactrouter.com/start/framework/routing). Add the previously created sign-in-or-up page to your route configuration. ```tsx {{ filename: 'app/routes.ts', mark: [5] }} import { type RouteConfig, index, route } from '@react-router/dev/routes' export default [ index('routes/home.tsx'), route('sign-in/*', 'routes/sign-in.tsx'), ] satisfies RouteConfig ``` ## Configure redirect behavior * Set the `CLERK_SIGN_IN_URL` environment variable to tell Clerk where the `` component is being hosted. * Set `CLERK_SIGN_IN_FALLBACK_REDIRECT_URL` as a fallback URL incase users visit the `/sign-in` route directly. * Set `CLERK_SIGN_UP_FALLBACK_REDIRECT_URL` as a fallback URL incase users select the 'Don't have an account? Sign up' link at the bottom of the component. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```env {{ filename: '.env' }} CLERK_SIGN_IN_URL=/sign-in CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/ CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/ ``` ## Visit your new page Run your project with the following command: ```npm npm run dev ``` Visit your new custom page locally at [localhost:5173/sign-in](http://localhost:5173/sign-in).
## Next steps * [Custom sign-up page](/docs/react-router/guides/development/custom-sign-up-page) * Learn how to add a custom sign-up page to your React Router app with Clerk's prebuilt components. --- title: Verify OAuth access tokens in your React Router application with Clerk description: Learn how to use Clerk's helpers to verify OAuth access tokens in your React Router application. sdk: nextjs, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/verifying-oauth-access-tokens lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/guides/development/verifying-oauth-access-tokens.react-router.mdx --- When building a resource server that needs to accept and verify OAuth access tokens issued by Clerk, it's crucial to verify these tokens on your backend to ensure the request is coming from an authenticated client. > \[!NOTE] > OAuth tokens are machine tokens. Machine token usage is free during our public beta period but will be subject to pricing once generally available. Pricing is expected to be competitive and below market averages. Clerk provides a built-in [`getAuth()`](/docs/reference/react-router/get-auth) function that supports token validation via the `acceptsToken` parameter. This lets you specify which type(s) of token your API route should accept in your React Router app. By default, `acceptsToken` is set to `session_token`, which means OAuth tokens will **not** be accepted unless explicitly configured. You can pass either a **single token type** or an **array of token types** to `acceptsToken`. To learn more about the supported token types, see the [`getAuth()` parameters documentation](/docs/reference/react-router/get-auth#parameters). ## Example 1: Accepting a single token type In the following example, the `acceptsToken` parameter is set to only accept `oauth_token`s. * If the token is invalid or missing, `auth()` will return `null` for `subject` and other properties, and the request will be rejected with a `401` response. * 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/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { const { subject, scopes } = await getAuth(args, { acceptsToken: 'oauth_token' }) // If getAuth() returns null, the token is invalid if (!subject) { throw new Response('OAuth access token is invalid', { status: 401 }) } return { subject, scopes } } ``` ## Example 2: Accepting any token type In the following example, the `acceptsToken` parameter is set to accept any token type. * If the token is a `session_token`, it logs that the request is from a user session. * Otherwise, it logs that the request uses a machine token and specifies its type. ```tsx import { getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { const { tokenType } = await getAuth(args, { acceptsToken: 'any' }) if (tokenType === 'session_token') { console.log('This is a session token from a user') } else { console.log(`This is a ${tokenType} token`) } return { tokenType } } ``` --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: react-router sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: Protect content and read user data description: Learn how to use Clerk's hooks and helpers to protect content and read user data in your React Router application. metadata: title: Read session and user data in your React Router app with Clerk sdk: nextjs, expo, react-router, remix, tanstack-react-start, astro, nuxt sdkScoped: "true" canonical: /docs/:sdk:/guides/users/reading lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,expo,react-router,remix,tanstack-react-start,astro,nuxt notAvailableSdks: react,js-frontend,chrome-extension,android,ios,expressjs,fastify,go,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/guides/users/reading.react-router.mdx --- Clerk provides a set of [hooks and helpers](/docs/reference/react-router/overview#client-side-helpers) that you can use to protect content and read user data in your React Router application. This guide demonstrates how to use these helpers in both the client and server-side to get you started. ## Server-side To access active session and user data on the server-side, use the [`getAuth()`](/docs/reference/react-router/get-auth) helper. ### Server data loading The [`getAuth()`](/docs/reference/react-router/get-auth) helper returns the Auth object of the currently active user, which contains important information like the current user's session ID, user ID, and Organization ID, and the `isAuthenticated` property, which can be used to protect your API routes. In some cases, you may need the full Backend User object of the currently active user. This is helpful if you want to render information, like their first and last name, directly from the server. The `clerkClient()` helper returns an instance of the JS Backend SDK, which exposes Clerk's Backend API resources through methods such as the getUser(){{ target: '_blank' }} method. This method returns the full `Backend User` object. In the following example, the `userId` is passed to the JS Backend SDK's `getUser()` method to get the user's full `Backend User` object. ```tsx {{ filename: 'app/routes/profile.tsx' }} import { redirect } from 'react-router' 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 const { isAuthenticated, userId } = await getAuth(args) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } // Get the user's full `Backend User` object const user = await clerkClient(args).users.getUser(userId) return { user: JSON.stringify(user), } } export default function Profile({ loaderData }: Route.ComponentProps) { return (

Profile Data

        {JSON.stringify(loaderData, null, 2)}
      
) } ``` ### Server action Unlike the previous example that loads data when the page loads, the following example uses `getAuth()` to only fetch user data after submitting the form. The helper runs on form submission, authenticates the user, and processes the form data. ```tsx {{ filename: 'app/routes/profile-form.tsx' }} import { redirect, Form } from 'react-router' import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile-form' export async function action(args: Route.ActionArgs) { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = await getAuth(args) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } // Get the form data const formData = await args.request.formData() const name = formData.get('name')?.toString() // Get the user's full `Backend User` object const user = await clerkClient(args).users.getUser(userId) return { name, user: JSON.stringify(user), } } export default function ProfileForm({ actionData }: Route.ComponentProps) { return (

Profile Data

{actionData ? (
          {JSON.stringify(actionData, null, 2)}
        
) : null}
) } ``` ## Client-side To access session and user data on the client-side, you can use the `useAuth()` and `useUser()` hooks. ### `useAuth()` {/* TODO: Keep in sync with /tanstack-react-start/read-session-data and /expo/read-session-user-data */} The following example uses the useAuth() hook to access the current auth state, as well as helper methods to manage the current session. ```tsx {{ filename: 'example.tsx' }} export default function Example() { const { isLoaded, isSignedIn, userId, sessionId, getToken } = useAuth() const fetchExternalData = async () => { // Use `getToken()` to get the current user's session token const token = await getToken() // Use `token` to fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return
Loading...
} // Use `isSignedIn` to check if the user is signed in if (!isSignedIn) { // You could also add a redirect to the sign-in page here return
Sign in to view this page
} return (
Hello, {userId}! Your current active session is {sessionId}.
) } ``` ### `useUser()` {/* TODO: Keep in sync with /reference/tanstack-react-start/read-session-data and /reference/expo/read-session-user-data */} The following example uses the useUser() hook to access the User object, which contains the current user's data such as their full name. The following example demonstrates how to use `useUser()` to check if the user is signed in and display their first name. ```tsx {{ filename: 'src/Example.tsx' }} export default function Example() { const { isSignedIn, user, isLoaded } = useUser() // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return
Loading...
} // Use `isSignedIn` to protect the content if (!isSignedIn) { return
Sign in to view this page
} // Use `user` to access the current user's data return
Hello {user.firstName}!
} ``` --- title: "``" description: The component provides session and user context to Clerk's hooks and components. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/clerk-provider lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/clerk-provider.mdx --- The `` component is required to integrate Clerk into your React application, providing session and user context to Clerk's hooks and components. The recommended approach is to wrap your entire app with `` at the entry point to make authentication globally accessible. If you only need authentication for specific routes or pieces of your application, render `` deeper in the component tree. This allows you to implement Clerk's functionality precisely where required without impacting the rest of your app. ## Example ```tsx {{ filename: 'app/root.tsx' }} // Other imports import { ClerkProvider, SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/react-router' export default function App({ loaderData }: Route.ComponentProps) { return (
) } // Rest of the root.tsx code ```
## Properties | Property | Type | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`afterMultiSessionSingleSignOutUrl?` | null \| string | The full URL or path to navigate to after signing out the current user is complete. This option applies to [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). | | ~~`afterSignInUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl` or `signInForceRedirectUrl` instead. | | `afterSignOutUrl?` | null \| string | Full URL or path to navigate to after successful sign out. | | ~~`afterSignUpUrl?`~~ | null \| string | **Deprecated.** Use `signUpFallbackRedirectUrl` or `signUpForceRedirectUrl` instead. | | `allowedRedirectOrigins?` | (string \| RegExp)\[] | An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `allowedRedirectProtocols?` | string\[] | An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `appearance?` | [`Appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) | Optional object to style your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `clerkJSUrl?` | `string` | The URL that `@clerk/clerk-js` should be hot-loaded from. | | `clerkJSVariant?` | "" \| "headless" | If your web application only uses Control Components, you can set this value to `'headless'` and load a minimal ClerkJS bundle for optimal page performance. | | `clerkJSVersion?` | `string` | The npm version for `@clerk/clerk-js`. | | `domain?` | string \| (url: URL) => string | **Required if your application is a satellite application**. Sets the domain of the satellite application. | | `experimental?` | `Autocomplete`\<\{ commerce: boolean; persistClient: boolean; rethrowOfflineNetworkErrors: boolean; \}, `Record`\<`string`, `any`\>\> | Enable experimental flags to gain access to new features. These flags are not guaranteed to be stable and may change drastically in between patch or minor versions. | | `initialState?` | `Serializable`\<\{ actor: undefined \| \{ \[x: string]: unknown; sub: string; \}; factorVerificationAge: \[number, number]; organization: undefined \| OrganizationResource; orgId: undefined \| string; orgPermissions: undefined \| string\[]; orgRole: undefined \| string; orgSlug: undefined \| string; session: undefined \| SessionResource; sessionClaims: JwtPayload; sessionId: undefined \| string; sessionStatus: SessionStatusClaim; user: undefined \| UserResource; userId: undefined \| string; \}\> | Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `isSatellite?` | boolean \| (url: URL) => boolean | A boolean that indicates whether the application is a satellite application. | | `localization?` | [`LocalizationResource`](/docs/guides/customizing-clerk/localization) | Optional object to localize your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `newSubscriptionRedirectUrl?` | null \| string | The URL to navigate to after the user completes the checkout and clicks the "Continue" button. | | `nonce?` | `string` | This nonce value will be passed through to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. | | `proxyUrl?` | string \| (url: URL) => string \| (url: URL) => string | **Required for applications that run behind a reverse proxy**. The URL that Clerk will proxy requests to. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). | | `publishableKey` | `string` | The Clerk Publishable 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. | | ~~`redirectUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl`, `signInForceRedirectUrl`, `signUpFallbackRedirectUrl`, or `signUpForceRedirectUrl` instead. | | `routerPush?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "push" navigation. | | `routerReplace?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "replace" navigation. | | `sdkMetadata?` | \{ environment?: string; name: string; version: string; \} | Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `sdkMetadata.environment?` | `string` | Typically this will be the `NODE_ENV` that the SDK is currently running in. | | `sdkMetadata.name` | `string` | The npm package name of the SDK. | | `sdkMetadata.version` | `string` | The npm package version of the SDK. | | `selectInitialSession?` | (client: ClientResource) => null \| SignedInSessionResource | By default, the last signed-in session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. | | `signInFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signInForceRedirectUrl?` | null \| string | 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. | | `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. | | `signUpFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signUpForceRedirectUrl?` | null \| string | 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. | | `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. | | `standardBrowser?` | `boolean` | By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. | | `supportEmail?` | `string` | Optional support email for display in authentication screens. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `taskUrls?` | `Record`\<`"choose-organization"`, `string`\> | Customize the URL paths users are redirected to after sign-in or sign-up when specific session tasks need to be completed. When `undefined`, it uses Clerk's default task flow URLs. Defaults to `undefined`. | | `telemetry?` | false \| \{ debug?: boolean; disabled?: boolean; perEventSampling?: boolean; \} | Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. | | `touchSession?` | `boolean` | By default, the [Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/Sessions#operation/touchSession) is called during page focus to keep the last active session alive. This option allows you to disable this behavior. | | `waitlistUrl?` | `string` | The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). | ## SDK-specific properties ### Next.js * `dynamic` * `boolean` Indicates whether or not Clerk should make dynamic auth data available based on the current request. Defaults to `false`. Opts the application into dynamic rendering when `true`. For more information, see Next.js rendering modes and Clerk. ### Chrome Extension * `syncHost` * `string` To enable, pass the URL of the web application that the extension will sync the authentication state from. See the dedicated guide for more information. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: react-router sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`` component" description: Clerk's component renders a UI for authenticating users with Google's One Tap API. sdk: astro, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/google-one-tap lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: chrome-extension,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/authentication/google-one-tap.mdx --- > \[!IMPORTANT] > To use Google One Tap with Clerk, you must [enable Google as a social connection in the Clerk Dashboard](/docs/guides/configure/auth-strategies/social-connections/google#configure-for-your-production-instance) and make sure to use custom credentials. The `` component renders the [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) UI so that users can use a single button to sign-up or sign-in to your Clerk application with their Google accounts. By default, this component will redirect users back to the page where the authentication flow started. However, you can override this with force redirect URL props or [force redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). > \[!TIP] > `` does not render if the user is already signed into your Clerk application, so there's no need to manually check if a user is signed in yourself before rendering it. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/sign-in.tsx' }} import { GoogleOneTap } from '@clerk/react-router' export default function Page() { return } ``` ## Properties * `cancelOnTapOutside?` * `boolean` If `true`, the One Tap prompt closes automatically if the user clicks outside of the prompt. Defaults to `true`. *** * `itpSupport?` * `boolean` If `true`, enables the [ITP-specific UX](https://developers.google.com/identity/gsi/web/guides/itp) when One Tap is rendered on ITP browsers such as Chrome on iOS, Safari, and FireFox. Defaults to `true`. *** * `fedCmSupport?` * `boolean` If `true`, enables Google One Tap to use [the FedCM API](https://developers.google.com/privacy-sandbox/3pcd/fedcm) to sign users in. See Google's docs on [best practices when disabling FedCM support](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap#do_not_cover_google_one_tap). Defaults to `true` *** * `signInForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs in, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). *** * `signUpForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs up, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). ## Limitations * If your application will use the Google API on behalf of your users, the `` component is not recommended, as Google does not provide Clerk with an access or refresh token that you can use. * Users with the 1Password browser extension may not be able to render the Google One Tap UI. They must disable this extension. * When testing in development, if you select the `X` button to close the Google One Tap UI, you may encounter [a cooldown](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown) that prevents you from rendering it again for a period of time. To bypass the cooldown, remove the `g_state` cookie. --- title: "`` component" description: Clerk's component renders a UI for resolving the `choose-organization` task. sdk: js-frontend, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/task-choose-organization lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/authentication/task-choose-organization.mdx --- ![The \ component renders a UI for resolving the choose-organization session task.](/docs/images/ui-components/task-choose-organization.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for resolving the `choose-organization` session task. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/overview). You can further customize your `` component by passing additional properties at the time of rendering. > \[!IMPORTANT] > The `` component cannot render when a user doesn't have current session tasks. ## Example The following example demonstrates how to host the `` component on a custom page. > \[!NOTE] > To see the full `root.tsx` setup you need for Clerk with React Router, see the [React Router quickstart](/docs/react-router/getting-started/quickstart). ```tsx {{ filename: 'app/root.tsx', mark: [6] }} import { ClerkProvider } from '@clerk/react-router' import { Outlet } from 'react-router' export default function App() { return ( ) } ``` The `` component must be used in conjunction with the `` component. See the [dedicated guide on how to self-host the `` component](/docs/react-router/guides/development/custom-sign-in-or-up-page). ```tsx {{ filename: 'app/routes/onboarding/choose-organization.tsx' }} import { TaskChooseOrganization } from '@clerk/react-router' export default function ChooseOrganizationPage() { return } ``` ## Properties All props are optional. * `redirectUrlComplete` * `string` The full URL or path to navigate to after successfully completing all tasks. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for signing up users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/authentication/sign-up.mdx --- ![The \ component renders a UI for signing up users.](/docs/images/ui-components/sign-up.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. If you would like to create a dedicated `/sign-up` page in your React Router application, there are a few requirements you must follow. See the [dedicated guide](/docs/react-router/guides/development/custom-sign-up-page) for more information. ```tsx {{ filename: 'app/routes/sign-up.tsx' }} import { SignUp } from '@clerk/react-router' export default function SignUpPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `string` If provided, this URL will always be used as the redirect destination 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. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-up`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signInFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Used for the 'Already have an account? Sign in' link that's rendered. 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. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signInUrl` * `string` The full URL or path to the sign-in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: The component renders a waitlist form that allows users to join for early access to your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/waitlist lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/authentication/waitlist.mdx --- ![The \ component renders a form that allows users to join for early access to your app.](/docs/images/ui-components/waitlist.png){{ style: { maxWidth: '460px' } }} In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. [Learn more about additional features available in **Waitlist** mode](/docs/guides/secure/restricting-access#waitlist). The `` component renders a form that allows users to join for early access to your app. ## Enable Waitlist mode Before using the `` component, you must enable **Waitlist** mode in the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. ## Example > \[!WARNING] > Before using the `` component, you must provide the `waitlistUrl` prop either in the \ or \ component to ensure proper functionality. The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/waitlist.tsx' }} import { Waitlist } from '@clerk/react-router' export default function WaitlistPage() { return } ``` ## Properties All props are optional. * `afterJoinWaitlistUrl` * `string` The full URL or path to navigate to after joining the waitlist. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `signInUrl` * `string` The full URL or path to the sign in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. ## Customization To learn about how to customize Clerk components, see the [customization guide](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component renders a UI for signing in users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/authentication/sign-in.mdx --- ![The \ component renders a UI for signing in users.](/docs/images/ui-components/sign-in.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI to allow users to sign in or sign up by default. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. If you would like to create a dedicated `/sign-in` page in your React Router application, there are a few requirements you must follow. See the [dedicated guide](/docs/react-router/guides/development/custom-sign-in-or-up-page) for more information. ```tsx {{ filename: 'app/routes/sign-in.tsx' }} import { SignIn } from '@clerk/react-router' export default function SignInPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `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. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-in`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signUpFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Used for the 'Don't have an account? Sign up' link that's rendered. Defaults to `/`. 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 used as the redirect destination after the user signs up. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signUpUrl` * `string` The full URL or path to the sign-up page. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `transferable` * `boolean` Indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `waitlistUrl` * `string` Full URL or path to the waitlist page. Use this property to provide the target of the 'Waitlist' link that's rendered. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). If you've passed the `waitlistUrl` prop to the \ component, it will infer from that, and you can omit this prop. *** * `withSignUp` * `boolean` Opt into sign-in-or-up flow by setting this prop to `true`. When `true`, if a user does not exist, they will be prompted to sign up. If a user exists, they will be prompted to sign in. Defaults to `true` if the `CLERK_SIGN_IN_URL` environment variable is set. Otherwise, defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "``" description: Clerk's component displays a table of Plans and Features that users can subscribe to. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/pricing-table lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/billing/pricing-table.mdx --- ![The \ component displays a table of Plans and Features that users can subscribe to.](/docs/images/ui-components/pricing-table.png) The `` component displays a table of Plans and Features that users can subscribe to. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/pricing.tsx' }} import { PricingTable } from '@clerk/react-router' export default function PricingPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `checkoutProps` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `collapseFeatures` * `boolean` A boolean that indicates whether the Features are collapsed. **Requires `layout` to be set to `'default'`**. Defaults to `false`. *** * `ctaPosition` * `'top' | 'bottom'` The placement of the CTA button. **Requires `layout` to be set to `'default'`**. Defaults to `'bottom'`. *** * `fallback` * `JSX` An optional UI to show when the pricing table is loading. *** * `for` * `'user' | 'organization'` A string that indicates whether the pricing table is for users or [Organizations](/docs/guides/organizations/overview). If `'user'`, the pricing table will display a list of Plans and Features that **users** can subscribe to. If `'organization'`, the pricing table will display a list of Plans and Features that **Organizations** can subscribe to. Defaults to `'user'`. *** * `newSubscriptionRedirectUrl` * `string` The URL to navigate to after the user completes the checkout and selects the "Continue" button. --- title: "``" description: The component indicates that Clerk is partially operational. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-degraded lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/clerk-degraded.mdx --- The `` component indicates that Clerk is partially operational. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'app/routes/example.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/react-router' export default function Example() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The component indicates that the Clerk object has failed to load. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-failed lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/clerk-failed.mdx --- The `` component indicates that the Clerk object has failed to load. This is useful for displaying an error message to the user. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'app/routes/example.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/react-router' export default function Example() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the Clerk object without the need to check it exists. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loaded lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/clerk-loaded.mdx --- The `` component guarantees that the Clerk object has loaded (the `status` is `'ready'` or `'degraded'`) and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/routes/example.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/react-router' export default function Example() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: \RedirectCallback /> description: Clerk's `` component is used to implement custom OAuth flows. It handles the OAuth callback and completes the authentication process. sdk: astro, chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/authenticate-with-redirect-callback lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: expo,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/authenticate-with-redirect-callback.mdx --- The `` component is a crucial part of implementing custom OAuth flows in your application. It serves as the callback handler for the authentication process initiated by the `authenticateWithRedirect()` method. Render it on the route specified as the `redirectUrl` in your `authenticateWithRedirect()` call. This component automatically handles the OAuth callback, completing the authentication process and managing the user's session. It uses the handleRedirectCallback() method under the hood. ## Example For an example of how to use the `` component, see the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) guide. ## Properties All props are optional. * `continueSignUpUrl?` * `string | undefined | null` The full URL or path to navigate to if the sign up requires additional information. *** * `signInUrl?` * `string` The full URL or path where the `` component is mounted. *** * `signUpUrl?` * `string` The full URL or path where the `` component is mounted. *** * `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. *** * `firstFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if first factor verification is required. *** * `secondFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) is enabled. *** * `resetPasswordUrl?` * `string` The full URL or path to navigate to during sign in, if the user is required to reset their password. *** * `transferable?` * `boolean` A boolean that indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `verifyEmailAddressUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting email verification. *** * `verifyPhoneNumberUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting phone verification. --- title: "`` (deprecated)" description: The component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/redirect-to-organization-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToOrganizationProfile() method instead. The `` component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/Home.tsx' }} import { SignedIn, SignedOut, RedirectToOrganizationProfile } from '@clerk/react-router' export default function Home() { return ( <> You need to sign in to view your Organization profile. ) } ``` --- title: "``" description: The Protect component protects content or even entire routes based on authentication, and optionally, authorization. It only renders its children when the current user is signed-in, and if performing authorization checks, if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/protect lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/protect.mdx --- The \ component protects content or even entire routes based on: * authentication: whether the user is signed-in or not. * authorization: whether the user has been granted a specific type of access control (Role, Permission, Feature, or Plan) `` **always** performs authentication checks. To perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., you can pass different props, like `role`, `permission`, `feature`, or `plan`. `` accepts a `fallback` prop that will be rendered if the user fails the authentication or authorization checks. `` can be used both client-side and server-side (in Server Components). > \[!CAUTION] > This component only **visually hides** its children when the current user is not authorized. The contents of its children remain accessible via the browser's source code even if the user fails the authorization check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Usage ### Authentication checks `` always performs authentication checks. It will render its children if the user is signed-in, and its `fallback` prop if the user is signed-out. ```tsx {{ filename: 'app/routes/dashboard.tsx' }} import { Protect } from '@clerk/react-router' export default function DashboardPage() { return ( Users that are signed-out can see this.

}>

Users that are signed-in can see this.

) } ```
### Authorization checks To limit who is able to see the content that `` renders, you can pass **one** of the access control props: `permission`, `role`, `feature`, or `plan`. It's recommended to use **Permission-based** authorization over **Role-based** authorization, and **Feature-based** authorization over **Plan-based** authorization, as they are more flexible, easier to manage, and more secure. If you do not pass any of the access control props, `` will render its children if the user is signed in, regardless of their Role or its Permissions. For more complex authorization logic, pass conditional logic to the `condition` prop. ### Render content by Permissions The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:invoices:create` Permission. ```tsx {{ filename: 'app/routes/invoices.tsx' }} import { Protect } from '@clerk/react-router' export default function InvoicesPage() { return ( You do not have the Permissions to create an invoice.

} >

Users with Permission org:invoices:create can see this.

) } ```
### Render content by Role While authorization by `permission` is **recommended**, for convenience, `` allows a `role` prop to be passed. The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:billing` Role. ```tsx {{ filename: 'app/routes/billing.tsx' }} import { Protect } from '@clerk/react-router' export default function BillingPage() { return ( Only a member of the Billing department can access this content.

} >

Users with Role org:billing can see this.

) } ```
### Render content by Plan The following example demonstrates how to use `` to protect content by checking if the user has a Plan. ```tsx {{ filename: 'app/routes/bronze.tsx' }} import { Protect } from '@clerk/react-router' export default function BronzePage() { return ( Sorry, only subscribers to the Bronze plan can access this content.

} >

Welcome, Bronze subscriber!

) } ```
### Render content by Feature The following example demonstrates how to use `` to protect content by checking if the user has a Feature. ```tsx {{ filename: 'app/routes/premium-access.tsx' }} import { Protect } from '@clerk/react-router' export default function PremiumAccessPage() { return ( Sorry, only subscribers with the Premium Access feature can access this content.

} >

Congratulations! You have access to the Premium Access feature.

) } ```
### Render content conditionally The following example uses ``'s `condition` prop to conditionally render its children if the user has the correct Role. ```tsx {{ filename: 'app/routes/settings.tsx' }} import { Protect } from '@clerk/react-router' export default function SettingsPage() { return ( has({ role: 'org:admin' }) || has({ role: 'org:billing_manager' })} fallback={

Only an Admin or Billing Manager can access this content.

} >

The settings page.

) } ```
## Properties * `condition?` * `has => boolean` Optional conditional logic that renders the children if it returns `true`. *** * `fallback?` * `JSX` Optional UI to show when a user doesn't have the correct type of access control to access the protected content. *** * `feature?` * `string` Optional string corresponding to a [Feature](/docs/guides/billing/overview). *** * `plan?` * `string` Optional string corresponding to a [Plan](/docs/guides/billing/overview). *** * `permission?` * `string` Optional string corresponding to a [Permission](/docs/guides/organizations/roles-and-permissions) in the format `org::` *** * `role?` * `string` Optional string corresponding to a [Role](/docs/guides/organizations/roles-and-permissions) in the format `org:` *** * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: The component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/redirect-to-sign-in.mdx --- The `` component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignedIn, SignedOut, RedirectToSignIn, UserButton } from '@clerk/react-router' export default function Home() { return ( <> ) } ``` --- title: "``" description: The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loading lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/clerk-loading.mdx --- The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/routes/example.tsx' }} import { ClerkLoading, ClerkLoaded, ClerkDegraded, ClerkFailed } from '@clerk/react-router' export default function Example() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "`` (deprecated)" description: The component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/redirect-to-create-organization.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToCreateOrganization() method instead. The `` component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignedIn, SignedOut, RedirectToCreateOrganization } from '@clerk/react-router' export default function Home() { return ( <> You need to sign in to create an Organization. ) } ``` --- title: "``" description: The component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/redirect-to-sign-up.mdx --- The `` component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignedIn, SignedOut, RedirectToSignUp, UserButton } from '@clerk/react-router' export default function Home() { return ( <> ) } ``` --- title: "``" description: The component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-tasks lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,remix,go,astro,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/redirect-to-tasks.mdx --- The `` component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks**Session tasks** are requirements that users must fulfill in order to complete the authentication process, such as choosing an Organization.. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. The `` component is primarily intended for use in custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. If you're using prebuilt components, you typically won't need to use `` as these components manage task redirection internally. [See the guide on handling session tasks outside of prebuilt components](/docs/guides/configure/session-tasks#redirecting-to-tasks). ## Example ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignedOut, RedirectToTasks } from '@clerk/react-router' export default function Home() { return ( <> ) } ``` --- title: "``" description: Conditionally render content only when a user is signed in. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/signed-in.mdx --- ## Overview The `` component offers authentication checks as a cross-cutting concern. Any children components wrapped by a `` component will be rendered only if there's a user with an active session signed in your application. > \[!CAUTION] > This component only **visually hides** its children when the current user is not authenticated. The contents of its children remain accessible via the browser's source code even if the user fails the authentication check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Example ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignedIn } from '@clerk/react-router' export default function Home() { return ( <>
You are signed in.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` (deprecated)" description: The component will navigate to the user profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/redirect-to-user-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToUserProfile() method instead. The `` component will navigate to the Account Portal User Profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. To find your User Profile URL: 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Under **User profile**, select the **Visit** icon. ## Example ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignedIn, SignedOut, RedirectToUserProfile } from '@clerk/react-router' export default function Home() { return ( <>

You need to sign in to view your user profile.

) } ```
--- title: "``" description: Conditionally render content only when a user is signed out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-out lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/control/signed-out.mdx --- The `` component offers authentication checks as a cross-cutting concern. Any child nodes wrapped by a `` component will be rendered only if there's no User signed in to your application. ## Example ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignedOut } from '@clerk/react-router' export default function Home() { return ( <>

You are signed out.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured Organization management UI that allows users to manage their Organization profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/organization/organization-profile.mdx --- ![The \ component allows users to manage their Organization membership and security settings.](/docs/images/ui-components/organization-profile.png) The `` component allows users to manage their Organization membership, security, and billing settings. This component's **General** tab displays the Organization's information and the **Leave organization** button. Admins will be able to see the **Update profile** button, **Verified domains** section, and **Delete organization** button. The **Members** tab shows the Organization's members along with their join dates and Roles. Admins will have the ability to invite a member, change a member's Role, or remove them from the Organization. Admins will have tabs within the **Members** tab to view the Organization's [invitations](/docs/guides/organizations/overview#organization-invitations) and [requests](/docs/guides/organizations/verified-domains#membership-requests). The **Billing** tab displays the Plans and Features that are available to the Organization, as well as the user's billing information, such as their invoices and payment methods. ## Example The `` component must be embedded using the [React Router Splat route](https://reactrouter.com/start/framework/routing#splats) in order for the routing to work. ```tsx {{ filename: 'app/routes/organization-profile.$.tsx' }} import { OrganizationProfile } from '@clerk/react-router' export default function OrganizationProfilePage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after leaving an Organization. *** * `customPages` * `CustomPages[]` An array of custom pages to add to the Organization profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/organization-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash- and virtual-based routing.
For example: `/organization-profile`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages.
Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React.
## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages](/docs/guides/customizing-clerk/adding-items/organization-profile) documentation. --- title: "`` component" description: Clerk's component is used to display Organization related memberships, invitations, and suggestions for the user. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/organization/organization-list.mdx --- ![The \ component displays Organization-related memberships and automatic invitations and suggestions for the user.](/docs/images/ui-components/organization-list.png){{ style: { maxWidth: '460px' } }} The `` component displays Organization-related memberships and automatic [invitations](/docs/guides/organizations/verified-domains#automatic-invitations) and [suggestions](/docs/guides/organizations/verified-domains#automatic-suggestions) for the user. ## Example ```tsx {{ filename: 'app/routes/organizations.tsx' }} import { OrganizationList } from '@clerk/react-router' export default function OrganizationListPage() { return ( `/organization/${org.slug}`} afterSelectPersonalUrl={(user) => `/user/${user.id}`} afterSelectOrganizationUrl={(org) => `/organization/${org.slug}`} /> ) } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after creating a new Organization. *** * `afterSelectOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting an Organization. Defaults to `undefined`. *** * `afterSelectPersonalUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting the [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts). Defaults to `undefined`. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. Defaults to `false`. *** * `skipInvitationScreen` * `boolean | undefined` A boolean that controls whether the screen for sending invitations after an Organization is created is hidden. When `undefined`, Clerk will automatically hide the screen if the number of max allowed members is equal to 1. Defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [org-ref]: /docs/reference/javascript/organization --- title: "`` component" description: Clerk's component is used to render an Organization creation UI that allows users to create brand new Organizations within your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/organization/create-organization.mdx --- ![The \ component renders an Organization creation UI that allows users to create brand new organizations within your application.](/docs/images/ui-components/create-organization.png){{ style: { maxWidth: '492px' } }} The `` component is used to render an Organization creation UI that allows users to create brand new Organizations in your application. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/routes/create-organization.tsx' }} import { CreateOrganization } from '@clerk/react-router' export default function CreateOrganizationPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterCreateOrganizationUrl` * `string` Full URL or path to navigate to after creating a new organization. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/create-organization`. *** * `skipInvitationScreen` * `boolean` Hides the screen for sending invitations after an Organization is created. When left undefined, Clerk will automatically hide the screen if the number of max allowed members is equal to 1 *** * `hideSlug` * `boolean` Hides the optional slug field in the Organization creation screen. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to enable the ability to switch between available Organizations the user may be part of in your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-switcher lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/organization/organization-switcher.mdx --- ![The \ component allows a user to switch between their account types - their Personal Account and their joined Organizations.](/docs/images/ui-components/organization-switcher.png){{ style: { maxWidth: '436px' } }} The `` component allows a user to switch between their joined Organizations. If [Personal Accounts are enabled](/docs/guides/organizations/overview#allow-personal-accounts), users can also switch to their Personal Account. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple Organizations. It handles all Organization-related flows, including full Organization management for admins. Learn more about [Organizations](/docs/guides/organizations/overview). ## Example ```tsx {{ filename: 'app/routes/organization-switcher.tsx' }} import { OrganizationSwitcher } from '@clerk/react-router' export default function OrganizationSwitcherPage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * `string` The full URL or path to navigate to after creating a new Organization. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after the user leaves the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `afterSelectOrganizationUrl` * `string` The full URL or path to navigate to after a successful Organization switch. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `createOrganizationMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the "Create organization" button will cause the \ component to open as a modal, or if the browser will navigate to the `createOrganizationUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `createOrganizationUrl` * `string` The full URL or path where the ``]createorg-ref component is mounted. *** * `defaultOpen` * `boolean` A boolean that controls the default state of the `` component. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. *** * `organizationProfileMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the **Manage organization** button will cause the \ component to open as a modal, or if the browser will navigate to the `organizationProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `organizationProfileProps` * `object` Specify options for the underlying \ component. For example: `{appearance: {...}}` *** * `organizationProfileUrl` * `string` The full URL or path where the \ component is mounted. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [createorg-ref]: /docs/reference/components/organization/create-organization [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "``" description: The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. sdk: expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-with-metamask lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/unstyled/sign-in-with-metamask.mdx --- The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. ## Usage ### Basic usage ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignInWithMetamaskButton } from '@clerk/react-router' export default function Home() { return } ``` ### Custom usage In some cases, you will want to use your own button, or button text. You can do that by wrapping your button in the `` component. ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignInWithMetamaskButton } from '@clerk/react-router' export default function Home() { return ( ) } ``` --- title: "``" description: The `` component is a button that signs a user out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-out-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/unstyled/sign-out-button.mdx --- The `` component is a button that signs a user out. By default, it is a ` ) } ``` ### Multi-session usage #### Sign out of all sessions Clicking the `` component signs the user out of all sessions. This is the default behavior. #### Sign out of a specific session You can sign out of a specific session by passing in a `sessionId` to the `sessionId` prop. This is useful for signing a single account out of a [multi-session application](/docs/guides/secure/session-options#multi-session-applications). In the following example, the `sessionId` is retrieved from the useAuth() hook. If the user is not signed in, the `sessionId` will be `null`, and the user is shown the \ component. If the user is signed in, the user is shown the `` component, which when clicked, signs the user out of that specific session. ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignInButton, SignOutButton, useAuth } from '@clerk/react-router' export default function Home() { const { sessionId } = useAuth() if (!sessionId) { return } return } ``` ## Properties * `redirectUrl?` * `string` The full URL or path to navigate after successful sign-out. *** * `sessionId?` * `string` The ID of a specific session to sign out of. Useful for [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. --- title: "``" description: The component is a button that links to the sign-in page or displays the sign-in modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/unstyled/sign-in-button.mdx --- The `` component is a button that, by default, links to your app's sign-in page. Your sign-in page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-in page. ## Usage ### Basic usage ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignInButton } from '@clerk/react-router' export default function Home() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignInButton } from '@clerk/react-router' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-in route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'`. *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. --- title: "``" description: The component is a button that links to the sign-up page or displays the sign-up modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-up-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/unstyled/sign-up-button.mdx --- The `` component is a button that, by default, links to your app's sign-up page. Your sign-up page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-up page. ## Usage ### Basic usage ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignUpButton } from '@clerk/react-router' export default function Home() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignUpButton } from '@clerk/react-router' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-up route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'` *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). --- title: "`` component" description: Clerk's component is used to render the familiar user button UI popularized by Google. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/user/user-button.mdx --- ![The \ component renders the familiar user button UI popularized by Google.](/docs/images/ui-components/user-button.png){{ style: { maxWidth: '436px' } }} The `` component renders the familiar user button UI popularized by Google. When selected, it opens a dropdown menu with options to manage account settings and sign out. The "Manage account" option launches the \ component, providing access to profile and security settings. For users that have [multi-session](/docs/guides/secure/session-options#multi-session-applications) enabled, the `` also allows users to sign into multiple accounts at once and instantly switch between them without the need for a full page reload. Learn more [here](/docs/guides/secure/session-options#multi-session-applications). ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar and be able to open the popup menu. ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignedIn, UserButton, SignInButton, SignedOut } from '@clerk/react-router' export default function Home() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `afterMultiSessionSingleSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterMultiSessionSingleSignOutUrl` to \.** The full URL or path to navigate to after signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterSignOutUrl` to \.** The full URL or path to navigate to after a successful sign-out. *** * `afterSwitchSessionUrl` * `string` The full URL or path to navigate to after a successful account change in a multi-session app. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `defaultOpen` * `boolean` Controls whether the `` should open by default during the first render. *** * `showName` * `boolean` Controls if the user name is displayed next to the user image button. *** * `signInUrl` * `string` The full URL or path to navigate to when the **Add another account** button is clicked. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `userProfileMode` * `'modal' | 'navigation'` Controls whether selecting the **Manage your account** button will cause the \ component to open as a modal, or if the browser will navigate to the `userProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `userProfileProps` * `object` Specify options for the underlying \ component. For example: `{additionalOAuthScopes: {google: ['foo', 'bar'], github: ['qux']}}`. *** * `userProfileUrl` * `string` The full URL or path leading to the user management interface. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). You can also [add custom actions and links to the `` menu](/docs/guides/customizing-clerk/adding-items/user-button). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/user/user-profile.mdx --- ![The \ component renders a full-featured account management UI that allows users to manage their profile and security settings.](/docs/images/ui-components/user-profile.png){{ style: { maxWidth: '100%' } }} The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile, security, and billing settings. ## Example The `` component must be embedded using the [React Router Splat route](https://reactrouter.com/start/framework/routing#splats) in order for the routing to work. ```tsx {{ filename: 'app/routes/user-profile.$.tsx' }} import { UserProfile } from '@clerk/react-router' export default function UserProfilePage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/user-profile`. *** * `additionalOAuthScopes` * `object` Specify additional scopes per OAuth provider that your users would like to provide if not already approved. For example: `{google: ['foo', 'bar'], github: ['qux']}`. *** * `customPages` * CustomPage\[] An array of custom pages to add to the user profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/user-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages documentation](/docs/guides/customizing-clerk/adding-items/user-profile). --- title: "`` component" description: Clerk's component is used to render the familiar user avatar on its own. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-avatar lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/components/user/user-avatar.mdx --- ![The \ component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications.](/docs/images/ui-components/user-avatar.png) The `` component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications. ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar. ```tsx {{ filename: 'app/routes/home.tsx' }} import { SignedIn, UserAvatar, SignInButton, SignedOut } from '@clerk/react-router' export default function Home() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `rounded?` * `boolean` Determines whether the user avatar is displayed with rounded corners. *** * `appearance?` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` Optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: Hooks Reference description: A list of Clerk's comprehensive suite of hooks for managing authentication, sessions, sign-in and sign-up flows, Organizations, and reverification. sdk: astro, chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/overview.mdx --- Clerk offers a comprehensive suite of hooks that expose low-level access to authentication, session management, and multi-tenancy. With Clerk hooks, you can access and manage user data, handle sign-in and sign-up flows, control session management, and implement advanced flows like session reverification for sensitive actions. By using these hooks, you can extend or replace Clerk's built-in components and customize how authentication behaves in your application. ## Hooks * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: useAuth() description: Access and manage authentication state in your application with Clerk's useAuth() hook. sdk: astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-auth.mdx --- The `useAuth()` hook provides access to the current user's authentication state and methods to manage the active session. > \[!NOTE] > To access auth data server-side, see the Auth object reference doc. ## Parameters | Parameter | Type | Description | | ---------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `initialAuthStateOrOptions?` | null \| Record\ \| \{ treatPendingAsSignedOut?: boolean; \} | An object containing the initial authentication state or options for the `useAuth()` hook. If not provided, the hook will attempt to derive the state from the context. `treatPendingAsSignedOut` is a boolean that indicates whether pending sessions are considered as signed out or not. Defaults to `true`. | ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `undefined` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has` | `undefined` | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `undefined` | The ID of the user's active organization. | | `orgRole` | `undefined` | The current user's role in their active organization. | | `orgSlug` | `undefined` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `undefined` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `undefined` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `undefined` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `null` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (params: CheckAuthorizationParamsWithCustomPermissions) => false | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `null` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `null` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `null` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `string` | The ID of the user's active organization. | | `orgRole` | `string` | The current user's role in their active organization. | | `orgSlug` | null \| string | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | ## Example The following example demonstrates how to use the `useAuth()` hook to access the current auth state, like whether the user is signed in or not. It also includes a basic example for using the `getToken()` method to retrieve a session token for fetching data from an external resource. ```tsx {{ filename: 'app/routes/home.tsx' }} import { useAuth } from '@clerk/react-router' export default function Home() { const { userId, sessionId, getToken, isLoaded, isSignedIn } = useAuth() const fetchExternalData = async () => { const token = await getToken() // Fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

Hello, {userId}! Your current active session is {sessionId}.

) } ```
--- title: useClerk() description: Access and manage the Clerk object in your React application with Clerk's useClerk() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-clerk lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-clerk.mdx --- > \[!WARNING] > This hook should only be used for advanced use cases, such as building a completely custom OAuth flow or as an escape hatch to access to the `Clerk` object. The `useClerk()` hook provides access to the Clerk object, allowing you to build alternatives to any Clerk Component. ## Returns Clerk — The `useClerk()` hook returns the `Clerk` object, which includes all the methods and properties listed in the Clerk reference. ## Example The following example uses the `useClerk()` hook to access the `clerk` object. The `clerk` object is used to call the openSignIn() method to open the sign-in modal. ```tsx {{ filename: 'app/routes/home.tsx' }} import { useClerk } from '@clerk/react-router' export default function Home() { const clerk = useClerk() return } ``` --- title: useSessionList() description: Access and manage the current user's session list in your React application with Clerk's useSessionList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-session-list.mdx --- The `useSessionList()` hook returns an array of Session objects that have been registered on the client device. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | `undefined` | A list of sessions that have been registered on the client device. | | `setActive` | `undefined` | A function that sets the active session and/or organization. See the reference doc. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | SessionResource\[] | A list of sessions that have been registered on the client device. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. See the reference doc. | ## Example ### Get a list of sessions The following example uses `useSessionList()` to get a list of sessions that have been registered on the client device. The `sessions` property is used to show the number of times the user has visited the page. ```tsx {{ filename: 'app/routes/home.tsx' }} import { useSessionList } from '@clerk/react-router' export default function Home() { const { isLoaded, sessions } = useSessionList() // Handle loading state if (!isLoaded) return
Loading...
return (

Welcome back. You've been here {sessions.length} times before.

) } ```
--- title: useOrganization() description: Access and manage the currently active Organization in your React application with Clerk's useOrganization() hook. search: rank: 1 sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-organization.mdx --- The `useOrganization()` hook retrieves attributes of the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganization()` accepts a single object with the following optional properties: | Property | Type | Description | | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`domains?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ enrollmentMode?: "manual\_invitation" \| "automatic\_invitation" \| "automatic\_suggestion"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `enrollmentMode`: A string that filters the domains by the provided [enrollment mode](/docs/guides/organizations/verified-domains#enrollment-mode).
  • Any of the properties described in Shared properties.
| |
`invitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: ("expired" \| "pending" \| "accepted" \| "revoked")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`membershipRequests?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the membership requests by the provided status.
  • Any of the properties described in Shared properties.
| |
`memberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ query?: string; role?: string\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `role`: An array of OrganizationCustomRoleKey.
  • `query`: A string that filters the memberships by the provided string.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes aren't populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `invitations`, `membershipRequests`, `memberships`, and `domains` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | > \[!NOTE] > These attributes are updating automatically and will re-render their respective components whenever you set a different Organization using the setActive(\{ organization }) method or update any of the memberships or invitations. No need for you to manage updating anything manually. ## Returns | Property | Type | Description | | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `domains` | null \| PaginatedResourcesWithDefault\<OrganizationDomainResource\> \| PaginatedResources\<OrganizationDomainResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's domains. | | `invitations` | null \| PaginatedResourcesWithDefault\<OrganizationInvitationResource\> \| PaginatedResources\<OrganizationInvitationResource, T\["invitations"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's invitations. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `membership` | undefined \| null \| OrganizationMembershipResource | The current organization membership. | | `membershipRequests` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipRequestResource\> \| PaginatedResources\<OrganizationMembershipRequestResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's membership requests. | | `memberships` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["memberships"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's memberships. | | `organization` | undefined \| null \| OrganizationResource | The currently active organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expand and paginate attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // invitations.data will never be populated. const { invitations } = useOrganization() // Use default values to fetch invitations, such as initialPage = 1 and pageSize = 10 const { invitations } = useOrganization({ invitations: true, }) // Pass your own values to fetch invitations const { invitations } = useOrganization({ invitations: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { invitations } = useOrganization({ invitations: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```tsx {{ filename: 'app/routes/members.tsx' }} import { useOrganization } from '@clerk/react-router' export default function MemberListPage() { const { memberships } = useOrganization({ memberships: { infinite: true, // Append new data to the existing list keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of memberships. Notice the difference between this example's pagination and the infinite pagination example above. ```tsx {{ filename: 'app/routes/members-paginated.tsx' }} import { useOrganization } from '@clerk/react-router' export default function MemberListPage() { const { memberships } = useOrganization({ memberships: { keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
## Related guides * [Update an Organization](/docs/guides/development/custom-flows/organizations/update-organizations) * Use Clerk's API to build a custom flow for updating an Organization *** * [Manage Roles in an Organization](/docs/guides/development/custom-flows/organizations/manage-roles) * Use Clerk's API to build a custom flow for managing Roles in an Organization *** * [Manage an Organization's membership requests](/docs/guides/development/custom-flows/organizations/manage-membership-requests) * Use Clerk's API to build a custom flow for managing an Organization's membership requests *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: useReverification() description: Clerk's useReverification() hook enhances a fetcher function to handle a session's reverification flow. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-reverification lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-reverification.mdx --- > \[!WARNING] > > Depending on the SDK you're using, this feature requires `@clerk/nextjs@6.12.7` or later, `@clerk/clerk-react@5.25.1` or later, `@clerk/clerk-js@5.57.1` or later and `@clerk/clerk-sdk-ruby@3.3.0` or later. Reverification allows you to prompt a user to verify their credentials before performing sensitive actions, even if they're already authenticated. For example, in a banking application, transferring money is considered a "sensitive action." Reverification can be used to confirm the user's identity. The `useReverification()` hook is used to handle a session's reverification flow. If a request requires reverification, a modal will display, prompting the user to verify their credentials. Upon successful verification, the original request will automatically retry. If you'd like to build a custom UI, you can use the onNeedsReverification option. When using reverification, a user's credentials are valid for 10 minutes. Once stale, a user will need to reverify their credentials. This time duration can be customized by using the `has()` helper on the server-side. See the [guide on reverification](/docs/guides/secure/reverification) for more information. ## Parameters | Parameter | Type | Description | | ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `fetcher` | `Fetcher extends (...args: any[]) => Promise` | A function that returns a promise. | | `options?` | `Options` | Optional configuration object extending UseReverificationOptions. | ### `UseReverificationOptions` The optional options object. | Property | Type | Description | | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | |
`onNeedsReverification?` | (properties: NeedsReverificationParameters) => void | Handler for the reverification process. Opts out of using the default UI. Use this to build a custom UI. | ### `NeedsReverificationParameters` | Property | Type | Description | | -------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `cancel` | () => void | Marks the reverification process as cancelled and rejects the original request. | | `complete` | () => void | Marks the reverification process as complete and retries the original request. | | `level` | undefined \| "first\_factor" \| "second\_factor" \| "multi\_factor" | The verification level required for the reverification process. | ## Examples The `useReverification()` hook displays a prebuilt UI when the user needs to reverify their credentials. You can also build a custom UI to handle the reverification process yourself. Use the following tabs to see examples of either option. ### Handle reverification for an action The following example demonstrates how to use the `useReverification()` hook to require a user to reverify their credentials before being able to update their primary email address. It also demonstrates how to handle the cancellation of the reverification process. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/react-router' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification((emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {email.id !== user?.primaryEmailAddress?.id && ( )}
  • ))}
) } ```
### Handle reverification for a fetcher function The following example demonstrates how to use the `useReverification()` hook to enhance a fetcher function that fetches data from a route that requires reverification. For examples on how to set up a route that requires reverification, see the [guide on reverification](/docs/guides/secure/reverification). ```tsx {{ filename: 'components/AccountBalance.tsx' }} import { useReverification } from '@clerk/react-router' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' export function AccountBalance() { const [balance, setBalance] = useState(null) const accountBalance = useReverification(async () => { const response = await fetch('/api/balance') return await response.json() }) const handleClick = async () => { try { const accountBalanceResponse = await accountBalance() setBalance(accountBalanceResponse.amount) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your account balance is {balance ? `$${balance}` : '$******'}
) } ```
The following example demonstrates how to build a custom UI when using the `useReverification()` hook. In the example, the `useReverification()` hook is used to require a user to reverify their credentials before being able to update their primary email address. It requires two components: the `` component displays the list of email addresses to choose from and it renders the second component, ``, which handles the reverification process. The example handles first factor verification using an email code, so you will need to have the [**Email verification code**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) setting enabled for your application. But you can adapt this example to handle any type of verification level or strategy. The `` component uses `useReverification()` to enhance the `update()` method, requiring the user to reverify their credentials before being able to update their primary email address. The `useReverification()` hook provides the `onNeedsReverification` option, which is a handler for building a custom UI. It provides four properties: `level`, `complete`, `cancel`, and `inProgress`. The example tracks these using the `verificationState` state variable. * The `level` property determines the verification level required for the reverification process. This example only handles first factor verification, which is done in the `` component. * The `complete` and `cancel` properties are the steps of the reverification process, which is also done in the `` component. * The `inProgress` property is used to track the state of the reverification process. When the user selects the "Make primary" button, it triggers the reverification process and sets the `inProgress` property is `true`, which displays the `` component. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/react-router' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' import type { SessionVerificationLevel } from '@clerk/types' import { VerificationComponent } from './VerificationComponent' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // TODO: Update to use exported type once available const [verificationState, setVerificationState] = useState< | { complete: () => void cancel: () => void level: SessionVerificationLevel | undefined inProgress: boolean } | undefined >(undefined) // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification( (emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), { onNeedsReverification: ({ complete, cancel, level }) => { setVerificationState({ complete, cancel, level, inProgress: true, }) }, }, ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {user?.primaryEmailAddressId !== email.id && ( )}
  • ))}
{verificationState?.inProgress && ( { verificationState.complete() setVerificationState(undefined) }} onCancel={() => { verificationState.cancel() setVerificationState(undefined) }} /> )}
) } ```
The `` component handles the reverification process. It uses the `level` property to determine the verification level, which is set to `first_factor`. First, it finds the determined starting first factor from the supported first factors. Then, it prepares the first factor verification using the `strategy` (`email_code` in this case) and `emailAddressId` properties. Finally, it attempts to verify the session with email code provided by the user. If the verification is successful, the `onComplete()` handler is called to complete the reverification process. ```tsx {{ filename: 'components/VerificationComponent.tsx', collapsible: true }} import { useEffect, useRef, useState } from 'react' import { useSession } from '@clerk/react-router' import type { EmailCodeFactor, SessionVerificationLevel, SessionVerificationResource, } from '@clerk/types' export function VerificationComponent({ level = 'first_factor', onComplete, onCancel, }: { level: SessionVerificationLevel | undefined onComplete: () => void onCancel: () => void }) { const { session } = useSession() const [code, setCode] = useState('') const reverificationRef = useRef(undefined) const [determinedStartingFirstFactor, setDeterminedStartingFirstFactor] = useState< EmailCodeFactor | undefined >() useEffect(() => { if (reverificationRef.current) { return } session?.startVerification({ level }).then(async (response) => { reverificationRef.current = response await prepareEmailVerification(response) }) }, []) const prepareEmailVerification = async (verificationResource: SessionVerificationResource) => { // To simplify the example we will only handle the first factor verification if (verificationResource.status === 'needs_first_factor') { // Determine the starting first factor from the supported first factors const determinedStartingFirstFactor = verificationResource.supportedFirstFactors?.filter( (factor) => factor.strategy === 'email_code', )[0] if (determinedStartingFirstFactor) { setDeterminedStartingFirstFactor(determinedStartingFirstFactor) // Prepare the first factor verification with the determined starting first factor await session?.prepareFirstFactorVerification({ strategy: determinedStartingFirstFactor.strategy, emailAddressId: determinedStartingFirstFactor?.emailAddressId, }) } } } const handleVerificationAttempt = async () => { try { // Attempt to verify the session with the provided code await session?.attemptFirstFactorVerification({ strategy: 'email_code', code, }) onComplete() } catch (e) { // Any error from the attempt to verify the session can be handled here console.error('Error verifying session', e) } } if (!determinedStartingFirstFactor) { return null } return (

Enter verification code sent to {determinedStartingFirstFactor.safeIdentifier || ''}

setCode(e.target.value)} />
) } ```
## Related guides See the custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). guides for examples of how to use the `useReverification()` hook, such as the [Add a phone number to a user's account](/docs/guides/development/custom-flows/account-updates/add-phone) guide. --- title: "`useOrganizationList()`" description: Access and manage the current user's Organization list in your React application with Clerk's useOrganizationList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-organization-list.mdx --- The `useOrganizationList()` hook provides access to the current user's Organization memberships, invitations, and suggestions. It also includes methods for creating new Organizations and managing the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganizationList()` accepts a single object with the following properties: | Property | Type | Description | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`userInvitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`userMemberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & object & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • Any of the properties described in Shared properties.
| |
`userSuggestions?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "pending" \| "accepted" \| ("pending" \| "accepted")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the suggestions by the provided status.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `userMemberships`, `userInvitations`, and `userSuggestions` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | ## Returns | Property | Type | Description | | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createOrganization` | undefined \| (CreateOrganizationParams: CreateOrganizationParams) => Promise\<OrganizationResource\> | A function that returns a `Promise` which resolves to the newly created `Organization`. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization and there is an authenticated user. Initially `false`, becomes `true` once Clerk loads with a user. | | `setActive` | undefined \| (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. | | `userInvitations` | PaginatedResourcesWithDefault\<UserOrganizationInvitationResource\> \| PaginatedResources\<UserOrganizationInvitationResource, T\["userInvitations"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization invitations. | | `userMemberships` | PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["userMemberships"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization memberships. | | `userSuggestions` | PaginatedResourcesWithDefault\<OrganizationSuggestionResource\> \| PaginatedResources\<OrganizationSuggestionResource, T\["userSuggestions"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of suggestions for organizations that the user can join. | ### `CreateOrganizationParams` | Property | Type | Description | | ------------------------- | -------- | ----------------------------- | | `name` | `string` | The name of the organization. | | `slug?` | `string` | The slug of the organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expanding and paginating attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. So by default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // userMemberships.data will never be populated const { userMemberships } = useOrganizationList() // Use default values to fetch userMemberships, such as initialPage = 1 and pageSize = 10 const { userMemberships } = useOrganizationList({ userMemberships: true, }) // Pass your own values to fetch userMemberships const { userMemberships } = useOrganizationList({ userMemberships: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `userMemberships` attribute will be populated with the first page of the user's Organization memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```tsx {{ filename: 'components/JoinedOrganizations.tsx' }} import { useOrganizationList } from '@clerk/react-router' export function JoinedOrganizations() { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) // Handle loading state if (!isLoaded) return
Loading...
return ( <>
    {userMemberships.data?.map((mem) => (
  • {mem.organization.name}
  • ))}
) } ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `userInvitations` attribute will be populated with the first page of invitations. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of invitations. Notice the difference between this example's pagination and the infinite pagination example above. ```tsx {{ filename: 'components/UserInvitationsTable.tsx' }} import { useOrganizationList } from '@clerk/react-router' export function UserInvitationsTable() { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { infinite: true, keepPreviousData: true, }, }) // Handle loading state if (!isLoaded || userInvitations.isLoading) return
Loading...
return ( <> {userInvitations.data?.map((inv) => ( ))}
Email Org name
{inv.emailAddress} {inv.publicOrganizationData.name}
) } ```
## Related guides * [Build a custom Organization switcher](/docs/guides/development/custom-flows/organizations/organization-switcher) * Use Clerk's API to build a custom flow for switching between Organizations *** * [Create Organizations](/docs/guides/development/custom-flows/organizations/create-organizations) * Use Clerk's API to build a custom flow for creating Organizations *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: useSession() description: Access and manage the current user's session in your React application with Clerk's useSession() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-session.mdx --- The `useSession()` hook provides access to the current user's Session object, as well as helpers for setting the active session. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `session` | `undefined` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `session` | `null` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `boolean` | A boolean that indicates whether a user is currently signed in. | | `session` | SignedInSessionResource | The current session for the user. | ## Example ### Access the `Session` object The following example uses the `useSession()` hook to access the `Session` object, which has the `lastActiveAt` property. The `lastActiveAt` property is a `Date` object used to show the time the session was last active. ```tsx {{ filename: 'app/routes/home.tsx' }} import { useSession } from '@clerk/react-router' export default function Home() { const { isLoaded, session, isSignedIn } = useSession() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

This session has been active since {session.lastActiveAt.toLocaleString()}

) } ```
--- title: useSignIn() description: Access and manage the current user's sign-in state in your React application with Clerk's useSignIn() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-sign-in.mdx --- The `useSignIn()` hook provides access to the SignIn object, which allows you to check the current state of a sign-in attempt and manage the sign-in flow. You can use this to create a [custom sign-in flow](/docs/guides/development/custom-flows/overview#sign-in-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signIn` | `undefined` | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signIn` | SignInResource | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | ## Examples ### Check the current state of a sign-in The following example uses the `useSignIn()` hook to access the SignIn object, which contains the current sign-in attempt status and methods to create a new sign-in attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'app/routes/sign-in.tsx' }} import { useSignIn } from '@clerk/react-router' export default function SignInPage() { const { isLoaded, signIn } = useSignIn() // Handle loading state if (!isLoaded) return
Loading...
return
The current sign-in attempt status is {signIn?.status}.
} ```
### Create a custom sign-in flow with `useSignIn()` The `useSignIn()` hook can also be used to build fully custom sign-in flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-in flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignIn()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useSignUp() description: Access and manage the current user's sign-up state in your React application with Clerk's useSignUp() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-sign-up.mdx --- The `useSignUp()` hook provides access to the SignUp object, which allows you to check the current state of a sign-up attempt and manage the sign-up flow. You can use this to create a [custom sign-up flow](/docs/guides/development/custom-flows/overview#sign-up-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signUp` | `undefined` | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signUp` | SignUpResource | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | ## Examples ### Check the current state of a sign-up The following example uses the `useSignUp()` hook to access the SignUp object, which contains the current sign-up attempt status and methods to create a new sign-up attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'app/routes/sign-up.tsx' }} import { useSignUp } from '@clerk/react-router' export default function SignUpPage() { const { isLoaded, signUp } = useSignUp() // Handle loading state if (!isLoaded) return
Loading...
return
The current sign-up attempt status is {signUp?.status}.
} ```
### Create a custom sign-up flow with `useSignUp()` The `useSignUp()` hook can also be used to build fully custom sign-up flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-up flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignUp()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useUser() description: Access and manage the current user's data in your React application with Clerk's useUser() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/hooks/use-user.mdx --- The `useUser()` hook provides access to the current user's User object, which contains all the data for a single user in your application and provides methods to manage their account. This hook also allows you to check if the user is signed in and if Clerk has loaded and initialized. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that returns `true` if the user is signed in. | | `user` | `undefined` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that returns `true` if the user is signed in. | | `user` | `null` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that returns `true` if the user is signed in. | | `user` | UserResource | The `User` object for the current user. | ## Examples ### Get the current user The following example uses the `useUser()` hook to access the User object, which contains the current user's data such as their full name. The `isLoaded` and `isSignedIn` properties are used to handle the loading state and to check if the user is signed in, respectively. ```tsx {{ filename: 'app/routes/home.tsx' }} import { useUser } from '@clerk/react-router' export default function Home() { const { isSignedIn, user, isLoaded } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return
Hello {user.firstName}!
} ```
### Update user data The following example uses the `useUser()` hook to access the User object, which calls the update() method to update the current user's information. ```tsx {{ filename: 'app/routes/home.tsx' }} import { useUser } from '@clerk/react-router' export default function Home() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { await user.update({ firstName: 'John', lastName: 'Doe', }) } return ( <>

user.firstName: {user.firstName}

user.lastName: {user.lastName}

) } ```
### Reload user data The following example uses the `useUser()` hook to access the User object, which calls the reload() method to get the latest user's information. ```tsx {{ filename: 'app/routes/home.tsx' }} import { useUser } from '@clerk/react-router' export default function Home() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { // Update data via an API endpoint const updateMetadata = await fetch('/api/updateMetadata', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role: 'admin', }), }) // Check if the update was successful if ((await updateMetadata.json()).message !== 'success') { throw new Error('Error updating') } // If the update was successful, reload the user data await user.reload() } return ( <>

user role: {user.publicMetadata.role}

) } ```
--- title: Fastify Quickstart description: Learn how to integrate Clerk for secure authentication and user management into your application using a Fastify backend. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: fastify sourceFile: /docs/getting-started/quickstart.fastify.mdx --- Learn how to integrate Clerk into your Fastify backend for secure user authentication and management. This guide uses TypeScript and allows you to choose your frontend framework. > \[!IMPORTANT] > [Fastify is only compatible with Next.js versions 13.4 and below](https://github.com/fastify/fastify-nextjs). If you're using a newer version of Next.js, consider using a different backend framework that supports the latest Next.js features. > > This guide uses ECMAScript Modules (ESM). To use ESM in your project, you must include `"type": "module"` in your `package.json`. ## Install `@clerk/fastify` [Clerk's Fastify SDK](https://github.com/clerk/javascript/tree/main/packages/fastify) provides a range of backend utilities to simplify user authentication and management in your application. Run the following command to install the SDK: ```npm npm install @clerk/fastify ``` ## Set your Clerk API keys Add the following keys to your `.env` file. These keys can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, copy your Clerk Publishable and Secret Keys. 3. Paste your keys into your `.env` file. The final result should resemble the following: ```env {{ filename: '.env' }} CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} ``` ## Configure `clerkPlugin()` for all routes The `clerkPlugin()` function is a Fastify plugin provided by Clerk to integrate authentication into your Fastify application. To ensure that Clerk's authentication and user management features are applied across your Fastify application, configure the `clerkPlugin()` to handle all routes or limit it to specific ones. The following example registers the plugin for all routes. To register the plugin for specific routes, see the [reference docs](/docs/reference/fastify/overview). > \[!IMPORTANT] > The `dotenv/config` module must be imported before any Clerk modules. This order is important because Clerk instances are created during the import process and rely on environment variables, such as API keys, to be initialized correctly. For more information, refer to the [Fastify docs](https://fastify.dev/docs/latest/Guides/Getting-Started/#loading-order-of-your-plugins). ```ts {{ filename: 'index.ts' }} import 'dotenv/config' import Fastify from 'fastify' import { clerkPlugin } from '@clerk/fastify' const fastify = Fastify({ logger: true }) fastify.register(clerkPlugin) const start = async () => { try { await fastify.listen({ port: 8080 }) } catch (error) { fastify.log.error(error) process.exit(1) } } start() ``` ## Protect your routes using `getAuth()` The [`getAuth()`](/docs/reference/fastify/overview#get-auth) helper retrieves the current user's authentication state from the `request` object. It returns the Auth object{{ target: '_blank' }}. The following example uses `getAuth()` to protect a route and load the user's data. If the user is authenticated, their `userId` is passed to clerkClient.users.getUser(){{ target: '_blank' }} to get the current user's User{{ target: '_blank' }} object. If not authenticated, the request is rejected with a `401` status code. ```ts // dotenv must be imported before @clerk/fastify import 'dotenv/config' import Fastify from 'fastify' import { clerkClient, clerkPlugin, getAuth } from '@clerk/fastify' const fastify = Fastify({ logger: true }) fastify.register(clerkPlugin) // Use `getAuth()` to protect this route fastify.get('/protected', async (request, reply) => { try { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(request) // If user isn't authenticated, return a 401 error if (!isAuthenticated) { return reply.code(401).send({ error: 'User not authenticated' }) } // Use `clerkClient` to access Clerk's JS Backend SDK methods // and get the user's User object const user = await clerkClient.users.getUser(userId) return reply.send({ message: 'User retrieved successfully', user, }) } catch (error) { fastify.log.error(error) return reply.code(500).send({ error: 'Failed to retrieve user' }) } }) const start = async () => { try { await fastify.listen({ port: 8080 }) } catch (error) { fastify.log.error(error) process.exit(1) } } start() ``` --- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: fastify sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. > \[!NOTE] > To see an example of how to create a pricing table page, please select one of the frontend SDKs on the sidebar. ## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```tsx {{ filename: 'src/routes/bronze-content.ts' }} import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' import { getAuth } from '@clerk/fastify' export const bronzeContentRoutes = (fastify: FastifyInstance) => { fastify.get('/bronze-content', async (request: FastifyRequest, reply: FastifyReply) => { const { has } = getAuth(request) const hasBronzePlan = has({ plan: 'bronze' }) if (hasBronzePlan) { reply.send('For Bronze subscribers only') } else { reply.send('Only subscribers to the Bronze plan can access this content.') } }) } ``` The following example demonstrates how to use `has()` to check if a user has a Feature. ```ts {{ filename: 'src/routes/premium-content.ts' }} import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' import { getAuth } from '@clerk/fastify' export const premiumContentRoutes = (fastify: FastifyInstance) => { fastify.get('/premium-content', async (request: FastifyRequest, reply: FastifyReply) => { const { has } = getAuth(request) const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) { reply.send('Only subscribers with the Premium Access feature can access this content.') } else { reply.send('Our Exclusive Content') } }) } ``` ### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: fastify sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. > \[!NOTE] > To see an example of how to create a pricing table page, please select one of the frontend SDKs on the sidebar. ## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```tsx {{ filename: 'src/routes/bronze-content.ts' }} import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' import { getAuth } from '@clerk/fastify' export const bronzeContentRoutes = (fastify: FastifyInstance) => { fastify.get('/bronze-content', async (request: FastifyRequest, reply: FastifyReply) => { const { has } = getAuth(request) const hasBronzePlan = has({ plan: 'bronze' }) if (hasBronzePlan) { reply.send('For Bronze subscribers only') } else { reply.send('Only subscribers to the Bronze plan can access this content.') } }) } ``` The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```ts {{ filename: 'src/routes/premium-content.ts' }} import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' import { getAuth } from '@clerk/fastify' export const premiumContentRoutes = (fastify: FastifyInstance) => { fastify.get('/premium-content', async (request: FastifyRequest, reply: FastifyReply) => { const { has } = getAuth(request) const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) { reply.send('Only subscribers with the Premium Access feature can access this content.') } else { reply.send('Our Exclusive Content') } }) } ``` The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```tsx {{ filename: 'src/routes/manage-premium-content.ts' }} import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify' import { getAuth } from '@clerk/fastify' export const managePremiumContentRoutes = (fastify: FastifyInstance) => { fastify.get('/manage-premium-content', async (request: FastifyRequest, reply: FastifyReply) => { const { has } = getAuth(request) const hasPremiumAccessManage = has({ permission: 'org:premium_access:manage' }) if (hasPremiumAccessManage) { reply.send('Our Exclusive Content') } else { reply.send( 'Only subscribers with the Premium Access Manage permission can access this content.', ) } }) } ``` ### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: fastify sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: fastify sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: Express Quickstart description: Learn how to use Clerk to quickly and easily add secure authentication and user management to your Express server. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: expressjs sourceFile: /docs/getting-started/quickstart.expressjs.mdx --- Learn how to integrate Clerk into your Express backend for secure user authentication and management. This guide focuses on backend implementation and requires a Clerk frontend SDK to function correctly. ## Install `@clerk/express` The [Clerk Express SDK](/docs/reference/express/overview) provides a range of backend utilities to simplify user authentication and management in your application. Run the following command to install the SDK: ```npm npm install @clerk/express ``` ## Set your Clerk API keys Add the following keys to your `.env` file. These keys can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, copy your Clerk Publishable and Secret Keys. 3. Paste your keys into your `.env` file. The final result should resemble the following: ```sh {{ filename: '.env' }} CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} ``` This guide uses `dotenv` to load the environment variables. Run the following command to install it: ```npm npm install dotenv ``` ## Add `clerkMiddleware()` to your app The [`clerkMiddleware()`](/docs/reference/express/overview#clerk-middleware) function checks the request's cookies and headers for a session JWT and, if found, attaches the Auth{{ target: '_blank' }} object to the `request` object under the `auth` key. ```ts {{ filename: 'index.ts', mark: [3, 8] }} import 'dotenv/config' import express from 'express' import { clerkMiddleware } from '@clerk/express' const app = express() const PORT = 3000 app.use(clerkMiddleware()) // Start the server and listen on the specified port app.listen(PORT, () => { console.log(`Example app listening at http://localhost:${PORT}`) }) ``` ## Protect your routes using `requireAuth()` To protect your routes, use the [`requireAuth()`](/docs/reference/express/overview#require-auth) middleware. This middleware functions similarly to `clerkMiddleware()`, but also protects your routes by redirecting unauthenticated users to the sign-in page. In the following example, `requireAuth()` is used to protect the `/protected` route. If the user isn't authenticated, they're redirected to the homepage. If the user is authenticated, the [`getAuth()`](/docs/reference/express/overview#get-auth) function is used to get the `userId`, which is passed to clerkClient.users.getUser(){{ target: '_blank' }} to fetch the current user's `User` object. ```ts {{ filename: 'index.ts' }} import 'dotenv/config' import express from 'express' import { clerkClient, requireAuth, getAuth } from '@clerk/express' const app = express() const PORT = 3000 // Use requireAuth() to protect this route // If user isn't authenticated, requireAuth() will redirect back to the homepage app.get('/protected', requireAuth(), async (req, res) => { // Use `getAuth()` to get the user's `userId` const { userId } = getAuth(req) // Use Clerk's JS Backend SDK to get the user's User object const user = await clerkClient.users.getUser(userId) return res.json({ user }) }) // Start the server and listen on the specified port app.listen(PORT, () => { console.log(`Example app listening at http://localhost:${PORT}`) }) ``` ## Add global TypeScript type (optional) If you're using TypeScript, add a global type reference to your project to enable auto-completion and type checking for the `auth` object in Express request handlers. 1. In your application's root folder, create a `types/` directory. 2. Inside this directory, create a `globals.d.ts` file with the following code. ```ts {{ filename: 'types/globals.d.ts' }} /// ``` ## Next steps * [Use middleware to protect routes](/docs/reference/express/overview#require-auth) * Learn how to protect specific routes from unauthenticated users. *** * [Protect routes based on authorization status](/docs/reference/express/overview#get-auth) * Learn how to protect a route based on both authentication and authorization status. *** * [Express SDK reference](/docs/reference/express/overview) * Learn more about additional Express SDK methods. *** * [Deploy to Production](/docs/guides/development/deployment/production) * Learn how to deploy your Clerk app to production. --- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: expressjs sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. > \[!NOTE] > To see an example of how to create a pricing table page, please select one of the frontend SDKs on the sidebar. ## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```tsx {{ filename: 'src/routes/bronze-content.ts' }} import { getAuth, requireAuth } from '@clerk/express' import { Router } from 'express' const router = Router() router.get('/bronze-content', requireAuth(), async (req, res) => { const { has } = getAuth(req) const hasBronzePlan = has({ plan: 'bronze' }) if (hasBronzePlan) { res.send('For Bronze subscribers only') } else { res.send('Only subscribers to the Bronze plan can access this content.') } }) export default router ``` The following example demonstrates how to use `has()` to check if a user has a Feature. ```ts {{ filename: 'src/routes/premium-content.ts' }} import { getAuth, requireAuth } from '@clerk/express' import { Router } from 'express' const router = Router() router.get('/premium-content', requireAuth(), async (req, res) => { const { has } = getAuth(req) const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) { res.send('Only subscribers with the Premium Access feature can access this content.') } else { res.send('Our Exclusive Content') } }) export default router ``` ### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: expressjs sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. > \[!NOTE] > To see an example of how to create a pricing table page, please select one of the frontend SDKs on the sidebar. ## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```tsx {{ filename: 'src/routes/bronze-content.ts' }} import { getAuth, requireAuth } from '@clerk/express' import { Router } from 'express' const router = Router() router.get('/bronze-content', requireAuth(), async (req, res) => { const { has } = getAuth(req) const hasBronzePlan = has({ plan: 'bronze' }) if (hasBronzePlan) { res.send('For Bronze subscribers only') } else { res.send('Only subscribers to the Bronze plan can access this content.') } }) export default router ``` The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```ts {{ filename: 'src/routes/premium-content.ts' }} import { getAuth, requireAuth } from '@clerk/express' import { Router } from 'express' const router = Router() router.get('/premium-content', requireAuth(), async (req, res) => { const { has } = getAuth(req) const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) { res.send('Only subscribers with the Premium Access feature can access this content.') } else { res.send('Our Exclusive Content') } }) export default router ``` The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```tsx {{ filename: 'src/routes/manage-premium-content.ts' }} import { getAuth, requireAuth } from '@clerk/express' import { Router } from 'express' const router = Router() router.get('/manage-premium-content', requireAuth(), async (req, res) => { const { has } = getAuth(req) const hasPremiumAccessManage = has({ permission: 'org:premium_access:manage' }) if (hasPremiumAccessManage) { res.send('Our Exclusive Content') } else { res.send('Only subscribers with the Premium Access Manage permission can access this content.') } }) export default router ``` ### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. > \[!NOTE] > To see an example of how to use the `Protect` component, please select one of the frontend SDKs on the sidebar. --- title: Build an MCP server in your application with Clerk description: Learn how to build an MCP server using Clerk's OAuth server in your application. sdk: nextjs, expressjs sdkScoped: "true" canonical: /docs/:sdk:/guides/development/mcp/build-mcp-server lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,expressjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expressjs sourceFile: /docs/guides/development/mcp/build-mcp-server.mdx --- This guide demonstrates how to build an MCP server using Clerk's OAuth server in your Express app. It assumes that you have already integrated Clerk into your app by following the quickstart. > \[!IMPORTANT] > For most client implementations of MCP, [dynamic client registration](https://openid.net/specs/openid-connect-registration-1_0.html) is required. This allows MCP-compatible clients to automatically register themselves with your server during the OAuth flow. > Before proceeding, ensure you have toggled on the **Dynamic client registration** option in the [OAuth Applications](https://dashboard.clerk.com/~/oauth-applications) page in the Clerk Dashboard. ## Install dependencies To get started, this implementation requires the following packages to be installed in your project: * [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk): Provides the core SDK for building an MCP server, including utilities to define tools and handle LLM requests. * [`@clerk/mcp-tools`](https://github.com/clerk/mcp-tools): A helper library built on top of the [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) used to connect Clerk OAuth with MCP easily. * [`cors`](https://github.com/expressjs/cors): Express middleware for handling CORS requests, which is needed for public clients to access your MCP server. ```npm npm install @modelcontextprotocol/sdk @clerk/mcp-tools cors ``` ## Set up your app with Clerk and MCP imports The following code is the starting point for your MCP server. It includes the imports and setup needed to implement an MCP server with Clerk. ```ts {{ filename: 'index.ts' }} import 'dotenv/config' import { type MachineAuthObject, clerkClient, clerkMiddleware } from '@clerk/express' import { mcpAuthClerk, protectedResourceHandlerClerk, streamableHttpHandler, } from '@clerk/mcp-tools/express' import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' import express from 'express' import cors from 'cors' const app = express() // if you need to interface with a public client, this is required app.use(cors({ exposedHeaders: ['WWW-Authenticate'] })) app.use(clerkMiddleware()) app.use(express.json()) app.listen(3000) ``` ## Create your MCP server and define tools To let external LLM-powered tools securely interact with your app, you need to define an MCP server, and expose one or more [resources](https://modelcontextprotocol.io/docs/concepts/resources), [prompts](https://modelcontextprotocol.io/docs/concepts/prompts), and/or [tools](https://modelcontextprotocol.io/docs/concepts/tools). For this guide, you'll implement a single, example tool called `get_clerk_user_data` that retrieves information about the authenticated Clerk user. For more documentation on how to build MCP tools, see the [MCP documentation](https://modelcontextprotocol.io/docs/concepts/tools). The `McpServer()` function is used to create a new MCP server with a name and version. The `server.tool()` function is used to define tools that external LLM-based apps can invoke. Each tool includes: * A name (`get-clerk-user-data`). * A description of what the tool does. * Input parameters (none in this case). * A function that represents the implementation of the tool. In this case, it extracts the user ID, which is provided by Clerk's OAuth authentication, and then fetches the user's data using Clerk's getUser() method. The response is then returned in MCP's expected response format. ```ts {{ filename: 'index.ts', mark: [[15, 37]], collapsible: true }} import 'dotenv/config' import { type MachineAuthObject, clerkClient, clerkMiddleware } from '@clerk/express' import { mcpAuthClerk, protectedResourceHandlerClerk, streamableHttpHandler, } from '@clerk/mcp-tools/express' import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' import express from 'express' const app = express() app.use(clerkMiddleware()) app.use(express.json()) const server = new McpServer({ name: 'test-server', version: '0.0.1', }) server.tool( 'get_clerk_user_data', 'Gets data about the Clerk user that authorized this request', {}, async (_, { authInfo }) => { // non-null assertion is safe here, mcpAuthClerk ensures presence const userId = authInfo!.extra!.userId! as string const userData = await clerkClient.users.getUser(userId) return { content: [{ type: 'text', text: JSON.stringify(userData) }], } }, ) app.listen(3000) ``` ## Secure your MCP server & expose metadata endpoints Now that your MCP server and tools are defined, the next step is to secure your endpoints and expose them according to the MCP specification. To comply with the MCP specification, your server must expose [OAuth protected resource metadata](https://datatracker.ietf.org/doc/html/rfc9728#section-4.1) at a specific endpoint (`.well-known/oauth-protected-resource`). This metadata allows clients to discover where to authenticate, and some details about how the authentication service works. Older versions of the MCP spec required that you also expose [OAuth authorization server metadata](https://datatracker.ietf.org/doc/html/rfc8414) at a specific endpoint (`.well-known/oauth-authorization-server`). This is no longer required by the current MCP spec, but it may be necessary for some clients that only support older versions of the spec. Clerk provides prebuilt helpers via [`@clerk/mcp-tools`](https://github.com/clerk/mcp-tools) that handle this for you: * `mcpAuthClerk`: Authentication middleware that automatically verifies the `Authorization` header using Clerk-issued OAuth tokens. If unauthorized, it returns a `www-authenticate` header [in accordance with the MCP specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization#authorization-server-location). * `protectedResourceHandlerClerk`: Express handler that serves OAuth **protected resource metadata** in the format expected by MCP clients. This handler lets you define specific supported OAuth scopes to declare what access levels your resource requires. * `authServerMetadataHandlerClerk`: Express handler that serves OAuth **authorization server metadata** in the format expected by MCP clients. This is still often needed for clients that implement older mcp spec versions. * `streamableHttpHandler`: Express handler that connects your MCP server to incoming requests using the [streamable HTTP transport](https://modelcontextprotocol.io/docs/concepts/transports#streamable-http). > \[!NOTE] > For a more in-depth explanation of these helpers, see the [MCP Express reference](https://github.com/clerk/mcp-tools/tree/main/express). To secure your endpoints and expose your MCP server to a client, add the following code to your file: ```ts {{ filename: 'index.ts', mark: [[3, 4]] }} // The rest of your code... app.post('/mcp', mcpAuthClerk, streamableHttpHandler(server)) app.get( '/.well-known/oauth-protected-resource/mcp', // Specify the scopes that your MCP server needs here protectedResourceHandlerClerk({ scopes_supported: ['email', 'profile'] }), ) // This is still often needed for clients that implement the older mcp spec app.get('/.well-known/oauth-authorization-server', authServerMetadataHandlerClerk) app.listen(3000) ``` > \[!WARNING] > Your `.well-known` endpoints must be **publicly accessible** for MCP clients to discover OAuth metadata. When protecting routes, consider these paths and ensure they are not protected. ## Finished 🎉 Once this is complete, clients that support the latest MCP spec can now invoke the `get-clerk-user-data` tool to securely fetch user data from your app, assuming the request is authorized with a Clerk OAuth token. To test this out, [learn how to connect your client LLM to the MCP server](/docs/guides/development/mcp/connect-mcp-client). The next step is to replace the demo tool with your own tools, resources, and/or prompts that are relevant to your app. You can learn more about how to do this in the [MCP SDK documentation](https://modelcontextprotocol.io/docs/concepts/tools). --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: expressjs sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: expressjs sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: Sign in with Apple description: Learn how to use Clerk to natively Sign in with Apple. sdk: ios, expo sdkScoped: "true" canonical: /docs/:sdk:/guides/configure/auth-strategies/sign-in-with-apple lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: ios,expo notAvailableSdks: nextjs,react,js-frontend,chrome-extension,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: ios sourceFile: /docs/guides/configure/auth-strategies/sign-in-with-apple.mdx --- This guide will teach you how to add native [Sign in with Apple](https://developer.apple.com/sign-in-with-apple/) to your Clerk apps on Apple platforms. > \[!NOTE] > Apple Sign-In works on both iOS Simulators and physical devices. However, physical devices provide full functionality including biometric authentication (Face ID/Touch ID), while simulators have limited support. Always test on a physical device before releasing to production. ## Add your Native Application Add your iOS application to the [**Native Applications**](https://dashboard.clerk.com/~/native-applications) page in the Clerk dashboard. You will need your iOS app's **App ID Prefix** and **Bundle ID**. ## Enable Apple as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO Connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Apple**. 4. Ensure that **Enable for sign-up and sign-in** is toggled on. > \[!NOTE] > Apple provides a privacy feature called [Hide My Email](https://support.apple.com/en-us/HT210425#hideemail), allowing users to sign in to your app with Apple without disclosing their actual email addresses. Instead, your instance receives an app-specific email address that forwards any emails to the user's real address. To be able to send emails properly to users with hidden addresses, you must configure an additional setting in the Apple Developer portal. See [Configure Email Source for Apple Private Relay](/docs/guides/configure/auth-strategies/social-connections/apple#configure-email-source-for-apple-private-relay){{ target: '_blank' }} for more information. ## Add the Sign in with Apple capability to your app [Add the Sign in with Apple capability to your app](https://developer.apple.com/documentation/xcode/configuring-sign-in-with-apple#Add-the-Sign-in-with-Apple-capability-to-your-app). > \[!NOTE] > If you are using Clerk's prebuilt components, you don't need to do anything else and can stop here. The `SignInWithApple` button will appear in your `AuthView` automatically. > If you are building a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview)., continue to follow the steps below. ## Obtain an Apple ID Credential To authenticate with Apple and Clerk, you need to obtain an [Apple ID Credential](https://developer.apple.com/documentation/authenticationservices/asauthorizationappleidcredential). To obtain an Apple ID Credential, you can do one of the following: * Use one of [Apple's built-in Sign in with Apple buttons](https://developer.apple.com/documentation/signinwithapple/displaying-sign-in-with-apple-buttons-in-your-app). * Use Clerk's [`SignInWithAppleHelper`](https://swiftpackageindex.com/clerk/clerk-ios/main/documentation/clerk/signinwithapplehelper) class. * Obtain it manually by following [the Apple docs](https://developer.apple.com/documentation/signinwithapple). > \[!NOTE] > You must set the nonce property of the `ASAuthorizationAppleIDRequest` when requesting an Apple ID Credential in order to authenticate with Clerk. ## Build your sign-in flow Once you have obtained your [Apple ID Credential](https://developer.apple.com/documentation/authenticationservices/asauthorizationappleidcredential), you can use it to authenticate with Clerk by calling [`SignIn.authenticateWithIdToken(provider:idToken:)`](https://swiftpackageindex.com/clerk/clerk-ios/main/documentation/clerk/signin/authenticatewithidtoken\(provider:idtoken:\)) with a provider of `.apple` and the `idToken` you have obtained. The following example uses Apple's built-in `SignInWithAppleButton` to obtain an Apple ID Credential and calls `SignIn.authenticateWithIdToken(provider:idToken:)` to authenticate with Clerk. ```swift {{ filename: 'SignInWithAppleView.swift' }} import SwiftUI import Clerk import AuthenticationServices struct SignInWithAppleView: View { var body: some View { // Use Apple's built-in SignInWithAppleButton SignInWithAppleButton { request in request.requestedScopes = [.email, .fullName] request.nonce = UUID().uuidString // Setting the nonce is mandatory } onCompletion: { result in Task { // Access the Apple ID Credential guard let credential = try result.get().credential as? ASAuthorizationAppleIDCredential else { dump("Unable to get credential of type ASAuthorizationAppleIDCredential") return } // Access the necessary identity token on the Apple ID Credential guard let idToken = credential.identityToken.flatMap({ String(data: $0, encoding: .utf8) }) else { dump("Unable to get ID token from Apple ID Credential.") return } // Authenticate with Clerk let authResult = try await SignIn.authenticateWithIdToken(provider: .apple, idToken: idToken) } } } } ``` --- title: iOS Quickstart description: Add authentication and user management to your iOS app with Clerk. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: ios sourceFile: /docs/getting-started/quickstart.ios.mdx --- ## Enable Native API In the Clerk Dashboard, navigate to the [**Native Applications**](https://dashboard.clerk.com/~/native-applications) page and ensure that the Native API is enabled. This is required to integrate Clerk in your native application. ## Create an iOS Project To get started using Clerk with iOS, create a new project in Xcode. Select SwiftUI as your interface and Swift as your language. See the [Xcode documentation](https://developer.apple.com/documentation/xcode/creating-an-xcode-project-for-an-app) for more information. ## Install the Clerk iOS SDK Follow [the Swift Package Manager instructions](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app) to install Clerk as a dependency. When prompted for the package URL, enter `https://github.com/clerk/clerk-ios`. Be sure to add the package to your target. ## Add your Native Application Add your iOS application to the [**Native Applications**](https://dashboard.clerk.com/~/native-applications) page in the Clerk Dashboard. You will need your iOS app's **App ID Prefix** and **Bundle ID**. ## Add associated domain capability To enable seamless authentication flows, you need to add an associated domain capability to your iOS app. This allows your app to work with Clerk's authentication services. 1. In Xcode, select your project in the Project Navigator. 2. Select your app target. 3. Navigate to the **Signing & Capabilities** tab. 4. Select the **+ Capability** option. 5. Search for and add **Associated Domains**. It will be added as a dropdown to the **Signing & Capabilities** tab. 6. Under **Associated Domains**, add a new entry with the value: `webcredentials:{YOUR_FRONTEND_API_URL}` > \[!NOTE] > Replace `{YOUR_FRONTEND_API_URL}` with your Frontend API URL, which can be found on the [**Native Applications**](https://dashboard.clerk.com/~/native-applications) page in the Clerk Dashboard. ## Load Clerk To use Clerk in your app, you must first configure and load `Clerk`. 1. Inside your new project in Xcode, open your `@main` app file. 2. Import `Clerk`. 3. Create a reference to the shared `Clerk` instance. 4. Inject the `clerk` instance into the SwiftUI environment using `.environment(\.clerk, clerk)` so your views can access it. 5. Add a `.task` modifier that configures Clerk with your Clerk Publishable Key and loads it when the app starts.You can retrieve your Publishable Key from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ```swift {{ filename: 'ClerkQuickstartApp.swift', mark: [2, 6, [11, 15]] }} import SwiftUI import Clerk @main struct ClerkQuickstartApp: App { @State private var clerk = Clerk.shared var body: some Scene { WindowGroup { ContentView() .environment(\.clerk, clerk) .task { clerk.configure(publishableKey: "{{pub_key}}") try? await clerk.load() } } } } ``` ## Conditionally render content To render content based on whether a user is authenticated or not: 1. Open your `ContentView` file. 2. Import `Clerk` and access the shared `Clerk` instance that you injected into the environment in the previous step. 3. Replace the content of the view body with a conditional that checks for a `clerk.user`. ```swift {{ filename: 'ContentView.swift', mark: [2, 5, [8, 14]] }} import SwiftUI import Clerk struct ContentView: View { @Environment(\.clerk) private var clerk var body: some View { VStack { if let user = clerk.user { Text("Hello, \(user.firstName ?? "User")") } else { Text("You are signed out") } } } } ``` ## Use Clerk's prebuilt views Clerk provides prebuilt SwiftUI views that handle authentication flows and user management, eliminating the need to build custom forms and flows. Update your `ContentView` to use Clerk's prebuilt views. Replace the existing content with the following code: ```swift {{ filename: 'ContentView.swift', mark: [2, 5, 6, [9, 21]] }} import SwiftUI import Clerk struct ContentView: View { @Environment(\.clerk) private var clerk @State private var authIsPresented = false var body: some View { VStack { if clerk.user != nil { UserButton() .frame(width: 36, height: 36) } else { Button("Sign in") { authIsPresented = true } } } .sheet(isPresented: $authIsPresented) { AuthView() } } } ``` The updated `ContentView` uses two key Clerk views: * [`AuthView`](/docs/reference/views/authentication/auth-view): A comprehensive authentication view that handles sign-in and sign-up flows, including email verification, password reset, and multi-factor authentication. It's presented as a sheet when the user taps "Sign in". * [`UserButton`](/docs/reference/views/user/user-button): A circular button that displays the user's profile image. When tapped, it automatically presents the [`UserProfileView`](/docs/reference/views/user/user-profile-view) where users can manage their account, update their profile, and sign out. ## Create your first user Run your project. When you tap "Sign in", the `AuthView` will appear, allowing you to sign up or sign in. --- title: Android Quickstart description: Add authentication and user management to your Android app with Clerk. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: android sourceFile: /docs/getting-started/quickstart.android.mdx --- ## Enable Native API In the Clerk Dashboard, navigate to the [**Native Applications**](https://dashboard.clerk.com/~/native-applications) page and ensure that the Native API is enabled. This is required to integrate Clerk in your native application. ## Create an Android Project 1. Create a new Android project in Android Studio using the **Empty Activity** template. This tutorial uses `MyClerkApp` as the app name. If you choose a different name, be sure to update any code examples accordingly to match your app's name. 2. Open the `app/build.gradle.kts` file and ensure that your project's minimum SDK version is set to 24 or higher, and that your project's Java version is set to 17 or higher, as these are the minimum requirements for the Clerk Android SDK. 3. In `app/build.gradle.kts`, add the following libraries to your `dependencies` block: * The [Clerk Android SDK](/docs/reference/android/overview). Check the [GitHub release page](https://github.com/clerk/clerk-android/releases) for the latest version. * [Android's Lifecycle ViewModel Compose library](https://developer.android.com/reference/kotlin/androidx/lifecycle/viewmodel/compose/package-summary). ```gradle dependencies { ... implementation("com.clerk:clerk-android:") implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.9.2") ... } ``` 4. Sync your project to apply the changes after adding the dependencies. ## Initialize Clerk In `app/src/main/java/com/example/myclerkapp/`, create a Kotlin class named `MyClerkApp`. Add the following code to: 1. Create a subclass of `Application` named after your application (e.g., `MyClerkApp`). 2. In this subclass, override the `onCreate()` method and call `Clerk.initialize()` to initialize the Clerk Android SDK with your application context (`this`) and Clerk Publishable Key. Your Publishable Key can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. Create a subclass of `Application` named after your application (e.g., `MyClerkApp`). 2. In this subclass, override the `onCreate()` method and call `Clerk.initialize()` to initialize the Clerk Android SDK with your application context (`this`) and Clerk Publishable Key. To find your Publishable Key: 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. Copy your Clerk Publishable Key. It's prefixed with `pk_test_` for development instances and `pk_live_` for production instances. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/MyClerkApp.kt' }} package com.example.myclerkapp import android.app.Application import com.clerk.api.Clerk class MyClerkApp: Application() { override fun onCreate() { super.onCreate() Clerk.initialize( this, publishableKey = {{pub_key}} ) } } ``` ## Configure the `AndroidManifest.xml` In `app/src/main/AndroidManifest.xml`, add the following configuration: 1. Inside the root `` tag, add the following line to enable internet permission on your Android device. ```xml ... ``` 2. Inside the `` tag, add the following line to use the `MyClerkApp` class as the entry point for app-level configuration. ```xml ... ``` ## Listen for SDK initialization and authentication events Let's start building out your home page. In your `app/src/main/java/com/example/myclerkapp/` directory, create a Kotlin class named `MainViewModel` with the following code. `MainViewModel` is a `ViewModel` that sets the state as `Loading` when the Clerk SDK is initializing, `SignedIn` when the user is signed in, or `SignedOut` when the user is signed out. The Clerk SDK initialization is non-blocking. Therefore, it's recommended to listen for the SDK to emit a success from Clerk's `isInitialized` global object to know when it's ready to use. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/MainViewModel.kt', collapsible: true }} package com.example.myclerkapp import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.clerk.api.Clerk import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn class MainViewModel: ViewModel() { private val _uiState = MutableStateFlow(MainUiState.Loading) val uiState = _uiState.asStateFlow() init { combine(Clerk.isInitialized, Clerk.userFlow) { isInitialized, user -> _uiState.value = when { !isInitialized -> MainUiState.Loading user != null -> MainUiState.SignedIn else -> MainUiState.SignedOut } } .launchIn(viewModelScope) } } sealed interface MainUiState { data object Loading : MainUiState data object SignedIn : MainUiState data object SignedOut : MainUiState } ``` ## Conditionally render content Now that you're listening for initialization and authentication events, set up your UI to react to them. In your `MainActivity.kt`, add the following code. This will show a loading indicator while the Clerk SDK is initializing, and a signed in or signed out experience based on the user's authentication state. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/MainActivity.kt', collapsible: true }} package com.example.myclerkapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.runtime.getValue import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val viewModel: MainViewModel by viewModels() val state by viewModel.uiState.collectAsStateWithLifecycle() Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { when (state) { MainUiState.Loading -> CircularProgressIndicator() MainUiState.SignedOut -> Text("You're signed out") MainUiState.SignedIn -> Text("You're signed in") } } } } } ``` ## Create sign-up and sign-in views ### Sign-up view Create a Kotlin class named `SignUpViewModel` with the following code. It allows users to sign up using their email address and password, and sends an email verification code to confirm their email address. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/SignUpViewModel.kt', collapsible: true }} package com.example.myclerkapp import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.clerk.api.Clerk import com.clerk.api.network.serialization.longErrorMessageOrNull import com.clerk.api.network.serialization.onFailure import com.clerk.api.network.serialization.onSuccess import com.clerk.api.signup.SignUp import com.clerk.api.signup.attemptVerification import com.clerk.api.signup.prepareVerification import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch class SignUpViewModel : ViewModel() { private val _uiState = MutableStateFlow(SignUpUiState.SignedOut) val uiState = _uiState.asStateFlow() fun signUp(email: String, password: String) { viewModelScope.launch { SignUp.create(SignUp.CreateParams.Standard(emailAddress = email, password = password)) .onSuccess { if (it.status == SignUp.Status.COMPLETE) { _uiState.value = SignUpUiState.Success } else { _uiState.value = SignUpUiState.NeedsVerification it.prepareVerification(SignUp.PrepareVerificationParams.Strategy.EmailCode()) } } .onFailure { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling Log.e("SignUpViewModel", it.longErrorMessageOrNull, it.throwable) } } } fun verify(code: String) { val inProgressSignUp = Clerk.signUp ?: return viewModelScope.launch { inProgressSignUp.attemptVerification(SignUp.AttemptVerificationParams.EmailCode(code)) .onSuccess { _uiState.value = SignUpUiState.Success } .onFailure { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling Log.e("SignUpViewModel", it.longErrorMessageOrNull, it.throwable) } } } sealed interface SignUpUiState { data object SignedOut : SignUpUiState data object Success : SignUpUiState data object NeedsVerification : SignUpUiState } } ``` Then, create a `SignUpView` file with the following code to use the `SignUpViewModel`. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/SignUpView.kt', collapsible: true }} package com.example.myclerkapp import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun SignUpView(viewModel: SignUpViewModel = viewModel()) { val state by viewModel.uiState.collectAsState() Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(24.dp, Alignment.CenterVertically) ) { Text("Sign Up") if (state is SignUpViewModel.SignUpUiState.NeedsVerification) { var code by remember { mutableStateOf("") } TextField(value = code, onValueChange = { code = it }) Button(onClick = { viewModel.verify(code) }) { Text("Verify") } } else { var email by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } TextField(value = email, onValueChange = { email = it }, placeholder = { Text("Email") }) TextField( value = password, placeholder = { Text("Password") }, onValueChange = { password = it }, visualTransformation = PasswordVisualTransformation(), ) Button(onClick = { viewModel.signUp(email, password) }) { Text("Sign Up") } } } } ``` ### Sign-in view Create a Kotlin class named `SignInViewModel` with the following code. It allows users to sign in using their email address and password. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/SignInViewModel.kt', collapsible: true }} package com.example.myclerkapp import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.clerk.api.network.serialization.onFailure import com.clerk.api.network.serialization.onSuccess import com.clerk.api.signin.SignIn import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch class SignInViewModel : ViewModel() { private val _uiState = MutableStateFlow(SignInUiState.Idle) val uiState = _uiState.asStateFlow() fun signIn(email: String, password: String) { viewModelScope.launch { SignIn.create(SignIn.CreateParams.Strategy.Password(identifier = email, password = password)) .onSuccess { _uiState.value = SignInUiState.Success } .onFailure { _uiState.value = SignInUiState.Error } } } sealed interface SignInUiState { data object Idle : SignInUiState data object Error : SignInUiState data object Success : SignInUiState } } ``` Then, create a `SignInView` file with the following code to use the `SignInViewModel`. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/SignInView.kt', collapsible: true }} package com.example.myclerkapp import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun SignInView(viewModel: SignInViewModel = viewModel()) { var email by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(24.dp, Alignment.CenterVertically) ) { Text("Sign In") TextField(value = email, onValueChange = { email = it }, placeholder = { Text("Email") }) TextField( value = password, onValueChange = { password = it }, placeholder = { Text("password") }, visualTransformation = PasswordVisualTransformation(), ) Button(onClick = { viewModel.signIn(email, password) }) { Text("Sign In") } } } ``` ### Combine the views Commonly, authentication flows will allow users to switch between sign up and sign in, such as a "Already signed up? Sign in" button. To add this to your app, create a `SignInOrUpView` file with the following code. This container view combines the `SignUpView` and `SignInView`, and allows users to switch between them. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/SignInOrUpView.kt', collapsible: true }} package com.example.myclerkapp import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @Composable fun SignInOrUpView() { var isSignUp by remember { mutableStateOf(true) } Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(24.dp, Alignment.CenterVertically), ) { if (isSignUp) { SignUpView() } else { SignInView() } Button(onClick = { isSignUp = !isSignUp }) { if (isSignUp) { Text("Already have an account? Sign in") } else { Text("Don't have an account? Sign up") } } } } ``` Then, in your `MainActivity` file, render your newly created `SignInOrUpView` when the user isn't signed in. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/MainActivity.kt', mark: [31] }} package com.example.myclerkapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.runtime.getValue import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val viewModel: MainViewModel by viewModels() val state by viewModel.uiState.collectAsStateWithLifecycle() Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { when (state) { MainUiState.Loading -> CircularProgressIndicator() MainUiState.SignedOut -> SignInOrUpView() MainUiState.SignedIn -> Text("You're signed in") } } } } } ``` ## Allow users to sign out Finally, provide users with a way to sign out of your app. In your `MainViewModel`, add a `signOut` function that calls `Clerk.signOut()`. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/MainViewModel.kt', mark: [14, [7, 9], [31, 41]], collapsible: true }} package com.example.myclerkapp import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.clerk.api.Clerk import com.clerk.api.network.serialization.longErrorMessageOrNull import com.clerk.api.network.serialization.onFailure import com.clerk.api.network.serialization.onSuccess import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.launch class MainViewModel: ViewModel() { private val _uiState = MutableStateFlow(MainUiState.Loading) val uiState = _uiState.asStateFlow() init { combine(Clerk.isInitialized, Clerk.userFlow) { isInitialized, user -> _uiState.value = when { !isInitialized -> MainUiState.Loading user != null -> MainUiState.SignedIn else -> MainUiState.SignedOut } } .launchIn(viewModelScope) } fun signOut() { viewModelScope.launch() { Clerk.signOut() .onSuccess { _uiState.value = MainUiState.SignedOut } .onFailure { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling Log.e("MainViewModel", it.longErrorMessageOrNull, it.throwable) } } } } sealed interface MainUiState { data object Loading : MainUiState data object SignedIn : MainUiState data object SignedOut : MainUiState } ``` Then, in your `MainActivity`, add a button that calls the `signOut` function when clicked. ```kotlin {{ filename: 'app/src/main/java/com/example/myclerkapp/MainActivity.kt', mark: [10, 33], collapsible: true }} package com.example.myclerkapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.runtime.getValue import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val viewModel: MainViewModel by viewModels() val state by viewModel.uiState.collectAsStateWithLifecycle() Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { when (state) { MainUiState.Loading -> CircularProgressIndicator() MainUiState.SignedOut -> SignInOrUpView() MainUiState.SignedIn -> Button(onClick = { viewModel.signOut() }) { Text("Sign out") } } } } } } ``` ## Create your first user Run your project and sign up to create your first user. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: android sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: Expo Quickstart description: Add authentication and user management to your Expo app with Clerk. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: expo sourceFile: /docs/getting-started/quickstart.expo.mdx --- ## Enable Native API In the Clerk Dashboard, navigate to the [**Native Applications**](https://dashboard.clerk.com/~/native-applications) page and ensure that the Native API is enabled. This is required to integrate Clerk in your native application. ## Install `@clerk/clerk-expo` The [Clerk Expo SDK](/docs/reference/expo/overview) gives you access to prebuilt components, hooks, and helpers to make user authentication easier. Run the following command to install the SDK: ```npm npm install @clerk/clerk-expo ``` ## Set your Clerk API keys Add your Clerk Publishable Key to your `.env` file. It can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, copy your Clerk Publishable Key. 3. Paste your key into your `.env` file. The final result should resemble the following: ```env {{ filename: '.env' }} EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} ``` ## Add `` to your root layout The \ component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with `` to make authentication globally accessible. See the reference docs for other configuration options. Add the component to your root layout as shown in the following example: ```tsx {{ filename: 'app/_layout.tsx', mark: [1, 6, 8] }} import { ClerkProvider } from '@clerk/clerk-expo' import { Slot } from 'expo-router' export default function RootLayout() { return ( ) } ``` ## Configure the token cache Clerk stores the active user's session token in memory by default. In Expo apps, the recommended way to store sensitive data, such as tokens, is by using `expo-secure-store` which encrypts the data before storing it. To use `expo-secure-store` as your token cache: 1. Run the following command to install the library: ```npm npm install expo-secure-store ``` 2. Update your root layout to use the secure token cache: ```tsx {{ filename: 'app/_layout.tsx', mark: [2, 7] }} import { ClerkProvider } from '@clerk/clerk-expo' import { tokenCache } from '@clerk/clerk-expo/token-cache' import { Slot } from 'expo-router' export default function RootLayout() { return ( ) } ``` > \[!TIP] > When you sign a user out with signOut(), Clerk will remove the user's session JWT from the token cache. ## Add sign-up and sign-in pages Clerk currently only supports control components for Expo native. UI components are only available for Expo web. Instead, you must build custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). using Clerk's API. The following sections demonstrate how to build [custom email/password sign-up and sign-in flows](/docs/guides/development/custom-flows/authentication/email-password). If you want to use different authentication methods, such as passwordless or OAuth, see the dedicated custom flow guides. ### Layout page First, protect your sign-up and sign-in pages. 1. Create an `(auth)` [route group](https://docs.expo.dev/router/advanced/shared-routes/). This will group your sign-up and sign-in pages. 2. In the `(auth)` group, create a `_layout.tsx` file with the following code. The useAuth() hook is used to access the user's authentication state. If the user is already signed in, they will be redirected to the home page. ```tsx {{ filename: 'app/(auth)/_layout.tsx' }} import { Redirect, Stack } from 'expo-router' import { useAuth } from '@clerk/clerk-expo' export default function AuthRoutesLayout() { const { isSignedIn } = useAuth() if (isSignedIn) { return } return } ``` ### Sign-up page In the `(auth)` group, create a `sign-up.tsx` file with the following code. The useSignUp() hook is used to create a sign-up flow. The user can sign up using their email and password and will receive an email verification code to confirm their email. ```tsx {{ filename: 'app/(auth)/sign-up.tsx', collapsible: true }} import * as React from 'react' import { Text, TextInput, TouchableOpacity, View } from 'react-native' import { useSignUp } from '@clerk/clerk-expo' import { Link, useRouter } from 'expo-router' export default function SignUpScreen() { const { isLoaded, signUp, setActive } = useSignUp() const router = useRouter() const [emailAddress, setEmailAddress] = React.useState('') const [password, setPassword] = React.useState('') const [pendingVerification, setPendingVerification] = React.useState(false) const [code, setCode] = React.useState('') // Handle submission of sign-up form const onSignUpPress = async () => { if (!isLoaded) return console.log(emailAddress, password) // Start sign-up process using email and password provided try { await signUp.create({ emailAddress, password, }) // Send user an email with verification code await signUp.prepareEmailAddressVerification({ strategy: 'email_code' }) // Set 'pendingVerification' to true to display second form // and capture OTP code setPendingVerification(true) } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } // Handle submission of verification form const onVerifyPress = async () => { if (!isLoaded) return try { // Use the code the user provided to attempt verification const signUpAttempt = await signUp.attemptEmailAddressVerification({ code, }) // If verification was completed, set the session to active // and redirect the user if (signUpAttempt.status === 'complete') { await setActive({ session: signUpAttempt.createdSessionId }) router.replace('/') } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(JSON.stringify(signUpAttempt, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } if (pendingVerification) { return ( <> Verify your email setCode(code)} /> Verify ) } return ( <> Sign up setEmailAddress(email)} /> setPassword(password)} /> Continue Already have an account? Sign in ) } ``` ### Sign-in page In the `(auth)` group, create a `sign-in.tsx` file with the following code. The useSignIn() hook is used to create a sign-in flow. The user can sign in using email address and password, or navigate to the sign-up page. ```tsx {{ filename: 'app/(auth)/sign-in.tsx', collapsible: true }} import { useSignIn } from '@clerk/clerk-expo' import { Link, useRouter } from 'expo-router' import { Text, TextInput, TouchableOpacity, View } from 'react-native' import React from 'react' export default function Page() { const { signIn, setActive, isLoaded } = useSignIn() const router = useRouter() const [emailAddress, setEmailAddress] = React.useState('') const [password, setPassword] = React.useState('') // Handle the submission of the sign-in form const onSignInPress = async () => { if (!isLoaded) return // Start the sign-in process using the email and password provided try { const signInAttempt = await signIn.create({ identifier: emailAddress, password, }) // If sign-in process is complete, set the created session as active // and redirect the user if (signInAttempt.status === 'complete') { await setActive({ session: signInAttempt.createdSessionId }) router.replace('/') } else { // If the status isn't complete, check why. User might need to // complete further steps. console.error(JSON.stringify(signInAttempt, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } return ( Sign in setEmailAddress(emailAddress)} /> setPassword(password)} /> Continue Don't have an account? Sign up ) } ``` For more information about building these custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview)., including guided comments in the code examples, see the [Build a custom email/password authentication flow](/docs/guides/development/custom-flows/authentication/email-password) guide. ## Add a sign-out button At this point, your users can sign up or in, but they need a way to sign out. In the `components/` folder, create a `SignOutButton.tsx` file with the following code. The useClerk() hook is used to access the `signOut()` function, which is called when the user clicks the "Sign out" button. ```tsx {{ filename: 'app/components/SignOutButton.tsx', collapsible: true }} import { useClerk } from '@clerk/clerk-expo' import { useRouter } from 'expo-router' import { Text, TouchableOpacity } from 'react-native' export const SignOutButton = () => { // Use `useClerk()` to access the `signOut()` function const { signOut } = useClerk() const router = useRouter() const handleSignOut = async () => { try { await signOut() // Redirect to your desired page router.replace('/') } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } return ( Sign out ) } ``` ## Conditionally render content You can control which content signed-in and signed-out users can see with Clerk's prebuilt control components. For this quickstart, you'll use: * \: Children of this component can only be seen while **signed in**. * \: Children of this component can only be seen while **signed out**. To get started: 1. Create a `(home)` route group. 2. In the `(home)` group, create a `_layout.tsx` file with the following code. ```tsx {{ filename: 'app/(home)/_layout.tsx' }} import { Stack } from 'expo-router/stack' export default function Layout() { return } ``` Then, in the same folder, create an `index.tsx` file with the following code. If the user is signed in, it displays their email and a sign-out button. If they're not signed in, it displays sign-in and sign-up links. ```tsx {{ filename: 'app/(home)/index.tsx' }} import { SignedIn, SignedOut, useUser } from '@clerk/clerk-expo' import { Link } from 'expo-router' import { Text, View } from 'react-native' import { SignOutButton } from '@/app/components/SignOutButton' export default function Page() { const { user } = useUser() return ( Hello {user?.emailAddresses[0].emailAddress} Sign in Sign up ) } ``` ## Create your first user Run your project with the following command: ```bash {{ filename: 'terminal' }} npm start ``` ```bash {{ filename: 'terminal' }} yarn start ``` ```bash {{ filename: 'terminal' }} pnpm start ``` ```bash {{ filename: 'terminal' }} bun start ``` Now visit your app's homepage at [`http://localhost:8081`](http://localhost:8081). Sign up to create your first user. ## Enable OTA updates Though not required, it is recommended to implement over-the-air (OTA) updates in your Expo app. This enables you to easily roll out Clerk's feature updates and security patches as they're released without having to resubmit your app to mobile marketplaces. See the [`expo-updates`](https://docs.expo.dev/versions/latest/sdk/updates) library to learn how to get started. ## Next steps * [SSO with Expo](/docs/guides/development/custom-flows/authentication/oauth-connections) * Learn more how to build a custom OAuth flow with Expo. *** * [MFA with Expo](/docs/guides/development/custom-flows/authentication/email-password-mfa) * Learn more how to build a custom multi-factor authentication flow with Expo. *** * [Protect content and read user data](/docs/expo/guides/users/reading) * Learn how to use Clerk's hooks and helpers to protect content and read user data in your Expo app. *** * [Sign-up and sign-in flow](/docs/guides/development/custom-flows/authentication/email-password) * Learn how to build a custom sign-up and sign-in authentication flow. --- title: Sign in with Apple description: Learn how to use Clerk to natively Sign in with Apple in your Expo app. sdk: ios, expo sdkScoped: "true" canonical: /docs/:sdk:/guides/configure/auth-strategies/sign-in-with-apple lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: ios,expo notAvailableSdks: nextjs,react,js-frontend,chrome-extension,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/guides/configure/auth-strategies/sign-in-with-apple.expo.mdx --- This guide will teach you how to add native [Sign in with Apple](https://developer.apple.com/sign-in-with-apple/) to your Clerk Expo application. > \[!NOTE] > Apple Sign-In works on both iOS Simulators and physical devices. However, physical devices provide full functionality including biometric authentication (Face ID/Touch ID), while simulators have limited support. Always test on a physical device before releasing to production. ## Add your Native Application Add your iOS application to the [**Native Applications**](https://dashboard.clerk.com/last-active?path=native-applications) page in the Clerk Dashboard. You will need your iOS app's **App ID Prefix** (Team ID) and **Bundle ID**. ## Enable Apple as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO Connections**](https://dashboard.clerk.com/last-active?path=user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Apple**. 4. Ensure that **Enable for sign-up and sign-in** is toggled on. > \[!NOTE] > Apple provides a privacy feature called [Hide My Email](https://support.apple.com/en-us/HT210425#hideemail), allowing users to sign in to your app with Apple without disclosing their actual email addresses. Instead, your instance receives an app-specific email address that forwards any emails to the user's real address. To be able to send emails properly to users with hidden addresses, you must configure an additional setting in the Apple Developer portal. See [Configure Email Source for Apple Private Relay](/docs/guides/configure/auth-strategies/social-connections/apple#configure-email-source-for-apple-private-relay){{ target: '_blank' }} for more information. ## Install dependencies The [Expo Apple Authentication library](https://docs.expo.dev/versions/latest/sdk/apple-authentication/) provides access to Apple's native Sign in with Apple functionality from your Expo app. Run the following command to install the library: ```npm {{ filename: 'terminal' }} npx expo install expo-apple-authentication ``` ## Add `expo-apple-authentication` to your app config Add the `expo-apple-authentication` plugin to your `app.json` or `app.config.js`. ```json {{ filename: 'app.json' }} { "expo": { "plugins": ["expo-apple-authentication"] } } ``` ```js {{ filename: 'app.config.js' }} export default { expo: { plugins: ['expo-apple-authentication'], }, } ``` ## Build your authentication flow The following example demonstrates how to use the [`useSignInWithApple()`](/docs/reference/expo/use-sign-in-with-apple) hook to manage the Apple authentication flow. Because the `useSignInWithApple()` hook automatically manages the transfer flowA **transfer flow** allows a user to both sign in and sign up in the same process. If a user tries signing up, but already exists, the flow will transfer the user to the sign-in flow. If a user tries signing in, but doesn't exist, the flow will transfer the user to the sign-up flow. between sign-up and sign-in, you can use this component for both your sign-up and sign-in pages. ```tsx {{ filename: 'components/AppleSignInButton.tsx', collapsible: true }} import { useSignInWithApple } from '@clerk/clerk-expo' import { useRouter } from 'expo-router' import { Alert, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native' // Example props that you could pass to your button interface AppleSignInButtonProps { // Callback function that is called when the sign-in is complete onSignInComplete?: () => void // Whether to show a divider between the button and the text showDivider?: boolean } export function AppleSignInButton({ onSignInComplete, showDivider = true, }: AppleSignInButtonProps) { const { startAppleAuthenticationFlow } = useSignInWithApple() const router = useRouter() // Only render on iOS if (Platform.OS !== 'ios') { return null } const handleAppleSignIn = async () => { try { const { createdSessionId, setActive } = await startAppleAuthenticationFlow() if (createdSessionId && setActive) { // Set the created session as the active session await setActive({ session: createdSessionId }) // Once the session is set as active, // if a callback function is provided, call it. // Otherwise, redirect to the home page. onSignInComplete ? onSignInComplete() : router.replace('/') } } catch (err: any) { // User canceled the sign-in flow if (err.code === 'ERR_REQUEST_CANCELED') return Alert.alert('Error', err.message || 'An error occurred during Apple Sign-In') console.error('Apple Sign-In error:', JSON.stringify(err, null, 2)) } } return ( <> Sign in with Apple {showDivider && ( OR )} ) } const styles = StyleSheet.create({ appleButton: { backgroundColor: '#000', padding: 15, borderRadius: 8, alignItems: 'center', marginBottom: 10, }, appleButtonText: { color: '#fff', fontSize: 16, fontWeight: '600', }, divider: { flexDirection: 'row', alignItems: 'center', marginVertical: 20, }, dividerLine: { flex: 1, height: 1, backgroundColor: '#ccc', }, dividerText: { marginHorizontal: 10, color: '#666', }, }) ``` ## Create a native build Create a native build with EAS Build or a local prebuild, since Apple Authentication is not supported in Expo Go. ```bash {{ filename: 'terminal' }} # Using EAS Build eas build --platform ios # Or using local prebuild npx expo prebuild && npx expo run:ios --device ``` --- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: expo sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. > \[!NOTE] > Expo only supports the `` component on the **web**. ```tsx {{ filename: 'app/(home)/pricing.tsx' }} import { PricingTable } from '@clerk/clerk-expo/web' import { View } from 'react-native' export default function PricingPage() { return ( ) } ``` ## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```tsx {{ filename: 'app/(home)/bronze-content.tsx' }} import { useAuth } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function BronzeContentPage() { const { isLoaded, has } = useAuth() if (!isLoaded) return
Loading...
const hasBronzePlan = has({ plan: 'bronze' }) if (!hasBronzePlan) return Only subscribers to the Bronze plan can access this content. return For Bronze subscribers only } ```
The following example demonstrates how to use `has()` to check if a user has a Feature. ```tsx {{ filename: 'app/(home)/premium-content.tsx' }} import { useAuth } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function PremiumContentPage() { const { isLoaded, has } = useAuth() if (!isLoaded) return
Loading...
const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) return Only subscribers with the Premium Access feature can access this content. return Our Exclusive Content } ```
### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. ```tsx {{ filename: 'app/(home)/protected-content.tsx' }} import { Protect } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.} > Exclusive Bronze Content This content is only visible to Bronze subscribers. ) } ``` The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. ```tsx {{ filename: 'app/(home)/protected-premium-content.tsx' }} import { Protect } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content. } > Exclusive Premium Content This content is only visible to users with Premium Access feature. ) } ``` --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: expo sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. > \[!NOTE] > Expo only supports the `` component on the **web**. ```tsx {{ filename: 'app/(home)/pricing.tsx' }} import { PricingTable } from '@clerk/clerk-expo/web' import { View } from 'react-native' export default function PricingPage() { return ( ) } ``` ## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```tsx {{ filename: 'app/(home)/bronze-content.tsx' }} import { useAuth } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function BronzeContentPage() { const { isLoaded, has } = useAuth() if (!isLoaded) return
Loading...
const hasBronzePlan = has({ plan: 'bronze' }) if (!hasBronzePlan) return Only subscribers to the Bronze plan can access this content. return For Bronze subscribers only } ```
The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```tsx {{ filename: 'app/(home)/premium-content.tsx' }} import { useAuth } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function PremiumContentPage() { const { isLoaded, has } = useAuth() if (!isLoaded) return
Loading...
const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) return Only subscribers with the Premium Access feature can access this content. return Our Exclusive Content } ```
The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```tsx {{ filename: 'app/(home)/manage-premium-content.tsx' }} import { useAuth } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function ManagePremiumContentPage() { const { isLoaded, has } = useAuth() if (!isLoaded) return
Loading...
const hasPremiumAccessManage = has({ permission: 'org:premium_access:manage' }) if (!hasPremiumAccessManage) return ( Only subscribers with the Premium Access Manage permission can access this content. ) return Our Exclusive Content } ```
### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. ```tsx {{ filename: 'app/(home)/protected-content.tsx' }} import { Protect } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.} > Exclusive Bronze Content This content is only visible to Bronze subscribers. ) } ``` The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. ```tsx {{ filename: 'app/(home)/protected-premium-content.tsx' }} import { Protect } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content. } > Exclusive Premium Content This content is only visible to users with Premium Access feature. ) } ``` The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. ```tsx {{ filename: 'app/(home)/protected-manage-content.tsx' }} import { Protect } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function ProtectedManageContentPage() { return ( Only subscribers with the Premium Access Manage permission can access this content. } > Exclusive Management Content This content is only visible to users with Premium Access Manage permission. ) } ``` --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: expo sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: Protect content and read user data description: Learn how to use Clerk's hooks to protect content and read user data in your Expo application. metadata: title: Read session and user data in your Expo app with Clerk sdk: nextjs, expo, react-router, remix, tanstack-react-start, astro, nuxt sdkScoped: "true" canonical: /docs/:sdk:/guides/users/reading lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,expo,react-router,remix,tanstack-react-start,astro,nuxt notAvailableSdks: react,js-frontend,chrome-extension,android,ios,expressjs,fastify,go,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/guides/users/reading.expo.mdx --- Clerk offers a comprehensive suite of hooks that expose low-level access to authentication, session management, and multi-tenancy. With Clerk hooks, you can access and manage user data, handle sign-in and sign-up flows, control session management, and implement advanced flows like session reverification for sensitive actions. By using these hooks, you can extend or replace Clerk's built-in components and customize how authentication behaves in your application. This guide demonstrates how to use the `useAuth()` and `useUser()` hooks to protect content and read user data in your Expo application. ## Session data example {/* TODO: Keep in sync with _partials/hooks/use-auth */} The useAuth(){{ target: '_blank' }} hook provides information about the current auth state, as well as helper methods to manage the current session. The following example demonstrates how to use the available properties of the `useAuth()` hook. ```tsx {{ filename: 'components/UseAuthExample.tsx' }} import { useAuth } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity } from 'react-native' export default function UseAuthExample() { const { isLoaded, isSignedIn, userId, sessionId, getToken } = useAuth() const fetchExternalData = async () => { // Use `getToken()` to get the current user's session token const token = await getToken() // Use `token` to fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return Loading... } // Use `isSignedIn` to check if the user is signed in if (!isSignedIn) { // You could also add a redirect to the sign-in page here return Sign in to view this page } return ( Hello, {userId}! Your current active session is {sessionId}. Fetch Data ) } ``` ## User data example {/* TODO: Keep in sync with _partials/hooks/use-user */} The useUser(){{ target: '_blank' }} hook enables you to access the User object, which contains the current user's data such as their full name. The following example demonstrates how to use `useUser()` to check if the user is signed in and display their first name. ```tsx {{ filename: 'src/Example.tsx' }} import { useUser } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function Example() { const { isSignedIn, user, isLoaded } = useUser() // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return Loading... } // Use `isSignedIn` to protect the content if (!isSignedIn) { return Sign in to view this page } // Use `user` to access the current user's data return Hello {user.firstName}! } ``` --- title: "``" description: The component provides session and user context to Clerk's hooks and components. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/clerk-provider lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/clerk-provider.mdx --- The `` component is required to integrate Clerk into your React application, providing session and user context to Clerk's hooks and components. The recommended approach is to wrap your entire app with `` at the entry point to make authentication globally accessible. If you only need authentication for specific routes or pieces of your application, render `` deeper in the component tree. This allows you to implement Clerk's functionality precisely where required without impacting the rest of your app. ## Example ```tsx {{ filename: 'app/_layout.tsx' }} import { ClerkProvider } from '@clerk/clerk-expo' import { Slot } from 'expo-router' export default function Layout() { return ( ) } ``` ## Properties | Property | Type | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`afterMultiSessionSingleSignOutUrl?` | null \| string | The full URL or path to navigate to after signing out the current user is complete. This option applies to [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). | | ~~`afterSignInUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl` or `signInForceRedirectUrl` instead. | | `afterSignOutUrl?` | null \| string | Full URL or path to navigate to after successful sign out. | | ~~`afterSignUpUrl?`~~ | null \| string | **Deprecated.** Use `signUpFallbackRedirectUrl` or `signUpForceRedirectUrl` instead. | | `allowedRedirectOrigins?` | (string \| RegExp)\[] | An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `allowedRedirectProtocols?` | string\[] | An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `appearance?` | [`Appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) | Optional object to style your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `clerkJSUrl?` | `string` | The URL that `@clerk/clerk-js` should be hot-loaded from. | | `clerkJSVariant?` | "" \| "headless" | If your web application only uses Control Components, you can set this value to `'headless'` and load a minimal ClerkJS bundle for optimal page performance. | | `clerkJSVersion?` | `string` | The npm version for `@clerk/clerk-js`. | | `domain?` | string \| (url: URL) => string | **Required if your application is a satellite application**. Sets the domain of the satellite application. | | `experimental?` | `Autocomplete`\<\{ commerce: boolean; persistClient: boolean; rethrowOfflineNetworkErrors: boolean; \}, `Record`\<`string`, `any`\>\> | Enable experimental flags to gain access to new features. These flags are not guaranteed to be stable and may change drastically in between patch or minor versions. | | `initialState?` | `Serializable`\<\{ actor: undefined \| \{ \[x: string]: unknown; sub: string; \}; factorVerificationAge: \[number, number]; organization: undefined \| OrganizationResource; orgId: undefined \| string; orgPermissions: undefined \| string\[]; orgRole: undefined \| string; orgSlug: undefined \| string; session: undefined \| SessionResource; sessionClaims: JwtPayload; sessionId: undefined \| string; sessionStatus: SessionStatusClaim; user: undefined \| UserResource; userId: undefined \| string; \}\> | Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `isSatellite?` | boolean \| (url: URL) => boolean | A boolean that indicates whether the application is a satellite application. | | `localization?` | [`LocalizationResource`](/docs/guides/customizing-clerk/localization) | Optional object to localize your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `newSubscriptionRedirectUrl?` | null \| string | The URL to navigate to after the user completes the checkout and clicks the "Continue" button. | | `nonce?` | `string` | This nonce value will be passed through to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. | | `proxyUrl?` | string \| (url: URL) => string \| (url: URL) => string | **Required for applications that run behind a reverse proxy**. The URL that Clerk will proxy requests to. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). | | `publishableKey` | `string` | The Clerk Publishable 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. | | ~~`redirectUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl`, `signInForceRedirectUrl`, `signUpFallbackRedirectUrl`, or `signUpForceRedirectUrl` instead. | | `routerPush?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "push" navigation. | | `routerReplace?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "replace" navigation. | | `sdkMetadata?` | \{ environment?: string; name: string; version: string; \} | Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `sdkMetadata.environment?` | `string` | Typically this will be the `NODE_ENV` that the SDK is currently running in. | | `sdkMetadata.name` | `string` | The npm package name of the SDK. | | `sdkMetadata.version` | `string` | The npm package version of the SDK. | | `selectInitialSession?` | (client: ClientResource) => null \| SignedInSessionResource | By default, the last signed-in session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. | | `signInFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signInForceRedirectUrl?` | null \| string | 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. | | `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. | | `signUpFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signUpForceRedirectUrl?` | null \| string | 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. | | `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. | | `standardBrowser?` | `boolean` | By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. | | `supportEmail?` | `string` | Optional support email for display in authentication screens. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `taskUrls?` | `Record`\<`"choose-organization"`, `string`\> | Customize the URL paths users are redirected to after sign-in or sign-up when specific session tasks need to be completed. When `undefined`, it uses Clerk's default task flow URLs. Defaults to `undefined`. | | `telemetry?` | false \| \{ debug?: boolean; disabled?: boolean; perEventSampling?: boolean; \} | Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. | | `touchSession?` | `boolean` | By default, the [Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/Sessions#operation/touchSession) is called during page focus to keep the last active session alive. This option allows you to disable this behavior. | | `waitlistUrl?` | `string` | The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). | ## SDK-specific properties ### Next.js * `dynamic` * `boolean` Indicates whether or not Clerk should make dynamic auth data available based on the current request. Defaults to `false`. Opts the application into dynamic rendering when `true`. For more information, see Next.js rendering modes and Clerk. ### Chrome Extension * `syncHost` * `string` To enable, pass the URL of the web application that the extension will sync the authentication state from. See the dedicated guide for more information. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: expo sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`` component" description: Clerk's component renders a UI for signing in users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/authentication/sign-in.mdx --- ![The \ component renders a UI for signing in users.](/docs/images/ui-components/sign-in.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI to allow users to sign in or sign up by default. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. If you would like to create a dedicated `/sign-in` page in your Expo application, there are a few requirements you must follow. See the [dedicated guide](/docs/guides/development/web-support/custom-sign-in-or-up-page) for more information. ```tsx {{ filename: '/app/sign-in.web.tsx' }} import { SignIn } from '@clerk/clerk-expo/web' export default function SignInPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `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. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-in`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signUpFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Used for the 'Don't have an account? Sign up' link that's rendered. Defaults to `/`. 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 used as the redirect destination after the user signs up. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signUpUrl` * `string` The full URL or path to the sign-up page. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `transferable` * `boolean` Indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `waitlistUrl` * `string` Full URL or path to the waitlist page. Use this property to provide the target of the 'Waitlist' link that's rendered. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). If you've passed the `waitlistUrl` prop to the \ component, it will infer from that, and you can omit this prop. *** * `withSignUp` * `boolean` Opt into sign-in-or-up flow by setting this prop to `true`. When `true`, if a user does not exist, they will be prompted to sign up. If a user exists, they will be prompted to sign in. Defaults to `true` if the `CLERK_SIGN_IN_URL` environment variable is set. Otherwise, defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for signing up users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/authentication/sign-up.mdx --- ![The \ component renders a UI for signing up users.](/docs/images/ui-components/sign-up.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/sign-up.web.tsx' }} import { SignUp } from '@clerk/clerk-expo/web' export default function SignUpPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `string` If provided, this URL will always be used as the redirect destination 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. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-up`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signInFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Used for the 'Already have an account? Sign in' link that's rendered. 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. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signInUrl` * `string` The full URL or path to the sign-in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for authenticating users with Google's One Tap API. sdk: astro, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/google-one-tap lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: chrome-extension,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/authentication/google-one-tap.mdx --- > \[!IMPORTANT] > To use Google One Tap with Clerk, you must [enable Google as a social connection in the Clerk Dashboard](/docs/guides/configure/auth-strategies/social-connections/google#configure-for-your-production-instance) and make sure to use custom credentials. The `` component renders the [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) UI so that users can use a single button to sign-up or sign-in to your Clerk application with their Google accounts. By default, this component will redirect users back to the page where the authentication flow started. However, you can override this with force redirect URL props or [force redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). > \[!TIP] > `` does not render if the user is already signed into your Clerk application, so there's no need to manually check if a user is signed in yourself before rendering it. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/sign-in-google.web.tsx' }} import { GoogleOneTap } from '@clerk/clerk-expo/web' export default function Page() { return } ``` ## Properties * `cancelOnTapOutside?` * `boolean` If `true`, the One Tap prompt closes automatically if the user clicks outside of the prompt. Defaults to `true`. *** * `itpSupport?` * `boolean` If `true`, enables the [ITP-specific UX](https://developers.google.com/identity/gsi/web/guides/itp) when One Tap is rendered on ITP browsers such as Chrome on iOS, Safari, and FireFox. Defaults to `true`. *** * `fedCmSupport?` * `boolean` If `true`, enables Google One Tap to use [the FedCM API](https://developers.google.com/privacy-sandbox/3pcd/fedcm) to sign users in. See Google's docs on [best practices when disabling FedCM support](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap#do_not_cover_google_one_tap). Defaults to `true` *** * `signInForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs in, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). *** * `signUpForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs up, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). ## Limitations * If your application will use the Google API on behalf of your users, the `` component is not recommended, as Google does not provide Clerk with an access or refresh token that you can use. * Users with the 1Password browser extension may not be able to render the Google One Tap UI. They must disable this extension. * When testing in development, if you select the `X` button to close the Google One Tap UI, you may encounter [a cooldown](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown) that prevents you from rendering it again for a period of time. To bypass the cooldown, remove the `g_state` cookie. --- title: "`` component" description: The component renders a waitlist form that allows users to join for early access to your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/waitlist lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/authentication/waitlist.mdx --- ![The \ component renders a form that allows users to join for early access to your app.](/docs/images/ui-components/waitlist.png){{ style: { maxWidth: '460px' } }} In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. [Learn more about additional features available in **Waitlist** mode](/docs/guides/secure/restricting-access#waitlist). The `` component renders a form that allows users to join for early access to your app. ## Enable Waitlist mode Before using the `` component, you must enable **Waitlist** mode in the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. ## Example > \[!WARNING] > Before using the `` component, you must provide the `waitlistUrl` prop either in the \ or \ component to ensure proper functionality. The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/waitlist.web.tsx' }} import { Waitlist } from '@clerk/clerk-expo/web' export default function WaitlistPage() { return } ``` ## Properties All props are optional. * `afterJoinWaitlistUrl` * `string` The full URL or path to navigate to after joining the waitlist. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `signInUrl` * `string` The full URL or path to the sign in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. ## Customization To learn about how to customize Clerk components, see the [customization guide](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "``" description: Clerk's component displays a table of Plans and Features that users can subscribe to. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/pricing-table lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/billing/pricing-table.mdx --- ![The \ component displays a table of Plans and Features that users can subscribe to.](/docs/images/ui-components/pricing-table.png) The `` component displays a table of Plans and Features that users can subscribe to. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/pricing.web.tsx' }} import { PricingTable } from '@clerk/clerk-expo/web' export default function PricingPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `checkoutProps` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `collapseFeatures` * `boolean` A boolean that indicates whether the Features are collapsed. **Requires `layout` to be set to `'default'`**. Defaults to `false`. *** * `ctaPosition` * `'top' | 'bottom'` The placement of the CTA button. **Requires `layout` to be set to `'default'`**. Defaults to `'bottom'`. *** * `fallback` * `JSX` An optional UI to show when the pricing table is loading. *** * `for` * `'user' | 'organization'` A string that indicates whether the pricing table is for users or [Organizations](/docs/guides/organizations/overview). If `'user'`, the pricing table will display a list of Plans and Features that **users** can subscribe to. If `'organization'`, the pricing table will display a list of Plans and Features that **Organizations** can subscribe to. Defaults to `'user'`. *** * `newSubscriptionRedirectUrl` * `string` The URL to navigate to after the user completes the checkout and selects the "Continue" button. --- title: "``" description: The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the Clerk object without the need to check it exists. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loaded lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/control/clerk-loaded.mdx --- The `` component guarantees that the Clerk object has loaded (the `status` is `'ready'` or `'degraded'`) and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/index.tsx' }} import { ClerkLoaded } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function Screen() { return ( Clerk has loaded ) } ``` --- title: "``" description: Conditionally render content only when a user is signed in. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/control/signed-in.mdx --- ## Overview The `` component offers authentication checks as a cross-cutting concern. Any children components wrapped by a `` component will be rendered only if there's a user with an active session signed in your application. > \[!CAUTION] > This component only **visually hides** its children when the current user is not authenticated. The contents of its children remain accessible via the browser's source code even if the user fails the authentication check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Example ```tsx {{ filename: 'app/index.tsx' }} import { SignedIn } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function Screen() { return ( You are signed in. This content is always visible. ) } ``` ## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: The Protect component protects content or even entire routes based on authentication, and optionally, authorization. It only renders its children when the current user is signed-in, and if performing authorization checks, if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/protect lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/control/protect.mdx --- The \ component protects content or even entire routes based on: * authentication: whether the user is signed-in or not. * authorization: whether the user has been granted a specific type of access control (Role, Permission, Feature, or Plan) `` **always** performs authentication checks. To perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., you can pass different props, like `role`, `permission`, `feature`, or `plan`. `` accepts a `fallback` prop that will be rendered if the user fails the authentication or authorization checks. `` can be used both client-side and server-side (in Server Components). > \[!CAUTION] > This component only **visually hides** its children when the current user is not authorized. The contents of its children remain accessible via the browser's source code even if the user fails the authorization check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Usage ### Authentication checks `` always performs authentication checks. It will render its children if the user is signed-in, and its `fallback` prop if the user is signed-out. ```jsx import { Protect } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function Screen() { return ( Users that are signed-out can see this.}> Users that are signed-in can see this. ) } ``` ### Authorization checks To limit who is able to see the content that `` renders, you can pass **one** of the access control props: `permission`, `role`, `feature`, or `plan`. It's recommended to use **Permission-based** authorization over **Role-based** authorization, and **Feature-based** authorization over **Plan-based** authorization, as they are more flexible, easier to manage, and more secure. If you do not pass any of the access control props, `` will render its children if the user is signed in, regardless of their Role or its Permissions. For more complex authorization logic, pass conditional logic to the `condition` prop. ### Render content by Permissions The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:invoices:create` Permission. ```jsx import { Protect } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function Screen() { return ( You do not have the Permissions to create an invoice.} > Users with Permission org:invoices:create can see this. ) } ``` ### Render content by Role While authorization by `permission` is **recommended**, for convenience, `` allows a `role` prop to be passed. The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:billing` Role. ```jsx import { Protect } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function Screen() { return ( Only a member of the Billing department can access this content.} > Users with Role org:billing can see this. ) } ``` ### Render content by Plan The following example demonstrates how to use `` to protect content by checking if the user has a Plan. ```tsx {{ filename: 'app/(billing)/bronze.tsx' }} import { Protect } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function Page() { return ( Sorry, only subscribers to the Bronze plan can access this content.} > Welcome, Bronze subscriber! ) } ``` ### Render content by Feature The following example demonstrates how to use `` to protect content by checking if the user has a Feature. ```tsx {{ filename: 'app/(billing)/premium-access.tsx' }} import { Protect } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function Page() { return ( Sorry, only subscribers with the Premium Access feature can access this content. } > Congratulations! You have access to the Premium Access feature. ) } ``` ### Render content conditionally The following example uses ``'s `condition` prop to conditionally render its children if the user has the correct Role. ```tsx {{ filename: 'app/dashboard/settings/page.tsx' }} import { Protect } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function Page() { return ( has({ role: 'org:admin' }) || has({ role: 'org:billing_manager' })} fallback={Only an Admin or Billing Manager can access this content.} > The settings page. ) } ``` ## Properties * `condition?` * `has => boolean` Optional conditional logic that renders the children if it returns `true`. *** * `fallback?` * `JSX` Optional UI to show when a user doesn't have the correct type of access control to access the protected content. *** * `feature?` * `string` Optional string corresponding to a [Feature](/docs/guides/billing/overview). *** * `plan?` * `string` Optional string corresponding to a [Plan](/docs/guides/billing/overview). *** * `permission?` * `string` Optional string corresponding to a [Permission](/docs/guides/organizations/roles-and-permissions) in the format `org::` *** * `role?` * `string` Optional string corresponding to a [Role](/docs/guides/organizations/roles-and-permissions) in the format `org:` *** * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loading lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/control/clerk-loading.mdx --- The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/index.tsx' }} import { ClerkLoading, ClerkLoaded } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function Screen() { return ( Clerk is loading Clerk has loaded ) } ``` --- title: "``" description: Conditionally render content only when a user is signed out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-out lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/control/signed-out.mdx --- The `` component offers authentication checks as a cross-cutting concern. Any child nodes wrapped by a `` component will be rendered only if there's no User signed in to your application. ## Example ```tsx {{ filename: 'app/index.tsx' }} import { SignedOut } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function Screen() { return ( You are signed out. This content is always visible. ) } ``` ## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` component" description: Clerk's component is used to display Organization related memberships, invitations, and suggestions for the user. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/organization/organization-list.mdx --- ![The \ component displays Organization-related memberships and automatic invitations and suggestions for the user.](/docs/images/ui-components/organization-list.png){{ style: { maxWidth: '460px' } }} The `` component displays Organization-related memberships and automatic [invitations](/docs/guides/organizations/verified-domains#automatic-invitations) and [suggestions](/docs/guides/organizations/verified-domains#automatic-suggestions) for the user. ## Example > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/organizations.web.tsx' }} import { OrganizationList } from '@clerk/clerk-expo/web' export default function OrganizationListPage() { return ( `/organization/${org.slug}`} afterSelectPersonalUrl={(user) => `/user/${user.id}`} afterSelectOrganizationUrl={(org) => `/organization/${org.slug}`} /> ) } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after creating a new Organization. *** * `afterSelectOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting an Organization. Defaults to `undefined`. *** * `afterSelectPersonalUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting the [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts). Defaults to `undefined`. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. Defaults to `false`. *** * `skipInvitationScreen` * `boolean | undefined` A boolean that controls whether the screen for sending invitations after an Organization is created is hidden. When `undefined`, Clerk will automatically hide the screen if the number of max allowed members is equal to 1. Defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [org-ref]: /docs/reference/javascript/organization --- title: "`` component" description: Clerk's component is used to render an Organization creation UI that allows users to create brand new Organizations within your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/organization/create-organization.mdx --- ![The \ component renders an Organization creation UI that allows users to create brand new organizations within your application.](/docs/images/ui-components/create-organization.png){{ style: { maxWidth: '492px' } }} The `` component is used to render an Organization creation UI that allows users to create brand new Organizations in your application. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/create-organization.web.tsx' }} import { CreateOrganization } from '@clerk/clerk-expo/web' export default function CreateOrganizationPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterCreateOrganizationUrl` * `string` Full URL or path to navigate to after creating a new organization. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/create-organization`. *** * `skipInvitationScreen` * `boolean` Hides the screen for sending invitations after an Organization is created. When left undefined, Clerk will automatically hide the screen if the number of max allowed members is equal to 1 *** * `hideSlug` * `boolean` Hides the optional slug field in the Organization creation screen. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to enable the ability to switch between available Organizations the user may be part of in your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-switcher lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/organization/organization-switcher.mdx --- ![The \ component allows a user to switch between their account types - their Personal Account and their joined Organizations.](/docs/images/ui-components/organization-switcher.png){{ style: { maxWidth: '436px' } }} The `` component allows a user to switch between their joined Organizations. If [Personal Accounts are enabled](/docs/guides/organizations/overview#allow-personal-accounts), users can also switch to their Personal Account. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple Organizations. It handles all Organization-related flows, including full Organization management for admins. Learn more about [Organizations](/docs/guides/organizations/overview). ## Example > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/organization-switcher.web.tsx' }} import { OrganizationSwitcher } from '@clerk/clerk-expo/web' export default function OrganizationSwitcherPage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * `string` The full URL or path to navigate to after creating a new Organization. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after the user leaves the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `afterSelectOrganizationUrl` * `string` The full URL or path to navigate to after a successful Organization switch. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `createOrganizationMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the "Create organization" button will cause the \ component to open as a modal, or if the browser will navigate to the `createOrganizationUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `createOrganizationUrl` * `string` The full URL or path where the ``]createorg-ref component is mounted. *** * `defaultOpen` * `boolean` A boolean that controls the default state of the `` component. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. *** * `organizationProfileMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the **Manage organization** button will cause the \ component to open as a modal, or if the browser will navigate to the `organizationProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `organizationProfileProps` * `object` Specify options for the underlying \ component. For example: `{appearance: {...}}` *** * `organizationProfileUrl` * `string` The full URL or path where the \ component is mounted. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [createorg-ref]: /docs/reference/components/organization/create-organization [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured Organization management UI that allows users to manage their Organization profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/organization/organization-profile.mdx --- ![The \ component allows users to manage their Organization membership and security settings.](/docs/images/ui-components/organization-profile.png) The `` component allows users to manage their Organization membership, security, and billing settings. This component's **General** tab displays the Organization's information and the **Leave organization** button. Admins will be able to see the **Update profile** button, **Verified domains** section, and **Delete organization** button. The **Members** tab shows the Organization's members along with their join dates and Roles. Admins will have the ability to invite a member, change a member's Role, or remove them from the Organization. Admins will have tabs within the **Members** tab to view the Organization's [invitations](/docs/guides/organizations/overview#organization-invitations) and [requests](/docs/guides/organizations/verified-domains#membership-requests). The **Billing** tab displays the Plans and Features that are available to the Organization, as well as the user's billing information, such as their invoices and payment methods. ## Example > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/organization-profile.web.tsx' }} import { OrganizationProfile } from '@clerk/clerk-expo/web' export default function OrganizationProfilePage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after leaving an Organization. *** * `customPages` * `CustomPages[]` An array of custom pages to add to the Organization profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/organization-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash- and virtual-based routing.
For example: `/organization-profile`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages.
Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React.
## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages](/docs/guides/customizing-clerk/adding-items/organization-profile) documentation. --- title: "``" description: The component is a button that links to the sign-in page or displays the sign-in modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/unstyled/sign-in-button.mdx --- The `` component is a button that, by default, links to your app's sign-in page. Your sign-in page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-in page. ## Usage ### Basic usage > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/sign-in.web.tsx' }} import { SignInButton } from '@clerk/clerk-expo/web' export default function SignInPage() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/index.tsx' }} import { SignInButton } from '@clerk/clerk-expo/web' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-in route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'`. *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. --- title: "``" description: The `` component is a button that signs a user out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-out-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/unstyled/sign-out-button.mdx --- The `` component is a button that signs a user out. By default, it is a ` ) } ``` ### Multi-session usage #### Sign out of all sessions Clicking the `` component signs the user out of all sessions. This is the default behavior. #### Sign out of a specific session You can sign out of a specific session by passing in a `sessionId` to the `sessionId` prop. This is useful for signing a single account out of a [multi-session application](/docs/guides/secure/session-options#multi-session-applications). In the following example, the `sessionId` is retrieved from the useAuth() hook. If the user is not signed in, the `sessionId` will be `null`, and the user is shown the \ component. If the user is signed in, the user is shown the `` component, which when clicked, signs the user out of that specific session. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/index.web.tsx' }} import { SignInButton, SignOutButton, useAuth } from '@clerk/clerk-expo/web' export default function Home() { const { sessionId } = useAuth() if (!sessionId) { return } return } ``` ## Properties * `redirectUrl?` * `string` The full URL or path to navigate after successful sign-out. *** * `sessionId?` * `string` The ID of a specific session to sign out of. Useful for [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. --- title: "``" description: The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. sdk: expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-with-metamask lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/unstyled/sign-in-with-metamask.mdx --- The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. ## Usage ### Basic usage > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/page.web.tsx' }} import { SignInWithMetamaskButton } from '@clerk/clerk-expo/web' export default function Home() { return } ``` ### Custom usage In some cases, you will want to use your own button, or button text. You can do that by wrapping your button in the `` component. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/page.web.tsx' }} import { SignInWithMetamaskButton } from '@clerk/clerk-expo/web' export default function Home() { return ( ) } ``` --- title: "``" description: The component is a button that links to the sign-up page or displays the sign-up modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-up-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/unstyled/sign-up-button.mdx --- The `` component is a button that, by default, links to your app's sign-up page. Your sign-up page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-up page. ## Usage ### Basic usage > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/sign-up.web.tsx' }} import { SignUpButton } from '@clerk/clerk-expo/web' export default function SignUpPage() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/index.tsx' }} import { SignUpButton } from '@clerk/clerk-expo/web' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-up route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'` *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). --- title: "`` component" description: Clerk's component is used to render the familiar user button UI popularized by Google. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/user/user-button.mdx --- ![The \ component renders the familiar user button UI popularized by Google.](/docs/images/ui-components/user-button.png){{ style: { maxWidth: '436px' } }} The `` component renders the familiar user button UI popularized by Google. When selected, it opens a dropdown menu with options to manage account settings and sign out. The "Manage account" option launches the \ component, providing access to profile and security settings. For users that have [multi-session](/docs/guides/secure/session-options#multi-session-applications) enabled, the `` also allows users to sign into multiple accounts at once and instantly switch between them without the need for a full page reload. Learn more [here](/docs/guides/secure/session-options#multi-session-applications). ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar and be able to open the popup menu. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/user-button.web.tsx' }} import { SignedIn, UserButton, SignInButton, SignedOut } from '@clerk/clerk-expo/web' export default function Header() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `afterMultiSessionSingleSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterMultiSessionSingleSignOutUrl` to \.** The full URL or path to navigate to after signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterSignOutUrl` to \.** The full URL or path to navigate to after a successful sign-out. *** * `afterSwitchSessionUrl` * `string` The full URL or path to navigate to after a successful account change in a multi-session app. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `defaultOpen` * `boolean` Controls whether the `` should open by default during the first render. *** * `showName` * `boolean` Controls if the user name is displayed next to the user image button. *** * `signInUrl` * `string` The full URL or path to navigate to when the **Add another account** button is clicked. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `userProfileMode` * `'modal' | 'navigation'` Controls whether selecting the **Manage your account** button will cause the \ component to open as a modal, or if the browser will navigate to the `userProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `userProfileProps` * `object` Specify options for the underlying \ component. For example: `{additionalOAuthScopes: {google: ['foo', 'bar'], github: ['qux']}}`. *** * `userProfileUrl` * `string` The full URL or path leading to the user management interface. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). You can also [add custom actions and links to the `` menu](/docs/guides/customizing-clerk/adding-items/user-button). --- title: "`` component" description: Clerk's component is used to render the familiar user avatar on its own. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-avatar lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/user/user-avatar.mdx --- ![The \ component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications.](/docs/images/ui-components/user-avatar.png) The `` component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications. ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar. > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/user-avatar.web.tsx' }} import { SignedIn, UserAvatar, SignInButton, SignedOut } from '@clerk/clerk-expo/web' export default function Header() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `rounded?` * `boolean` Determines whether the user avatar is displayed with rounded corners. *** * `appearance?` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` Optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/components/user/user-profile.mdx --- ![The \ component renders a full-featured account management UI that allows users to manage their profile and security settings.](/docs/images/ui-components/user-profile.png){{ style: { maxWidth: '100%' } }} The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile, security, and billing settings. ## Example > \[!NOTE] > This component can be used in Expo Web projects, but it isn't available in native environments (iOS or Android). For native apps, build a custom UI using Clerk hooks. See [custom flows guides](/docs/guides/development/custom-flows/overview) for details. ```jsx {{ filename: '/app/user-profile.web.tsx' }} import { UserProfile } from '@clerk/clerk-expo/web' export default function UserProfilePage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/user-profile`. *** * `additionalOAuthScopes` * `object` Specify additional scopes per OAuth provider that your users would like to provide if not already approved. For example: `{google: ['foo', 'bar'], github: ['qux']}`. *** * `customPages` * CustomPage\[] An array of custom pages to add to the user profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/user-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages documentation](/docs/guides/customizing-clerk/adding-items/user-profile). --- title: "`useOrganizationList()`" description: Access and manage the current user's Organization list in your React application with Clerk's useOrganizationList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-organization-list.mdx --- The `useOrganizationList()` hook provides access to the current user's Organization memberships, invitations, and suggestions. It also includes methods for creating new Organizations and managing the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganizationList()` accepts a single object with the following properties: | Property | Type | Description | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`userInvitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`userMemberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & object & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • Any of the properties described in Shared properties.
| |
`userSuggestions?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "pending" \| "accepted" \| ("pending" \| "accepted")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the suggestions by the provided status.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `userMemberships`, `userInvitations`, and `userSuggestions` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | ## Returns | Property | Type | Description | | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createOrganization` | undefined \| (CreateOrganizationParams: CreateOrganizationParams) => Promise\<OrganizationResource\> | A function that returns a `Promise` which resolves to the newly created `Organization`. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization and there is an authenticated user. Initially `false`, becomes `true` once Clerk loads with a user. | | `setActive` | undefined \| (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. | | `userInvitations` | PaginatedResourcesWithDefault\<UserOrganizationInvitationResource\> \| PaginatedResources\<UserOrganizationInvitationResource, T\["userInvitations"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization invitations. | | `userMemberships` | PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["userMemberships"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization memberships. | | `userSuggestions` | PaginatedResourcesWithDefault\<OrganizationSuggestionResource\> \| PaginatedResources\<OrganizationSuggestionResource, T\["userSuggestions"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of suggestions for organizations that the user can join. | ### `CreateOrganizationParams` | Property | Type | Description | | ------------------------- | -------- | ----------------------------- | | `name` | `string` | The name of the organization. | | `slug?` | `string` | The slug of the organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expanding and paginating attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. So by default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // userMemberships.data will never be populated const { userMemberships } = useOrganizationList() // Use default values to fetch userMemberships, such as initialPage = 1 and pageSize = 10 const { userMemberships } = useOrganizationList({ userMemberships: true, }) // Pass your own values to fetch userMemberships const { userMemberships } = useOrganizationList({ userMemberships: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `userMemberships` attribute will be populated with the first page of the user's Organization memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```tsx {{ filename: 'components/JoinedOrganizations.tsx' }} import { useOrganizationList } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity, ScrollView } from 'react-native' export function JoinedOrganizations() { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) // Handle loading state if (!isLoaded) return Loading... return ( {userMemberships.data?.map((mem) => ( {mem.organization.name} setActive({ organization: mem.organization.id })}> Select ))} userMemberships.fetchNext()} > Load more ) } ``` ### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `userInvitations` attribute will be populated with the first page of invitations. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of invitations. Notice the difference between this example's pagination and the infinite pagination example above. ```tsx {{ filename: 'components/UserInvitationsTable.tsx' }} import { useOrganizationList } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity, ScrollView } from 'react-native' export function UserInvitationsTable() { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { keepPreviousData: true, }, }) // Handle loading state if (!isLoaded || userInvitations.isLoading) return Loading... return ( Email Org name {userInvitations.data?.map((inv) => ( {inv.emailAddress} {inv.publicOrganizationData.name} ))} Prev Next ) } ``` ## Related guides * [Build a custom Organization switcher](/docs/guides/development/custom-flows/organizations/organization-switcher) * Use Clerk's API to build a custom flow for switching between Organizations *** * [Create Organizations](/docs/guides/development/custom-flows/organizations/create-organizations) * Use Clerk's API to build a custom flow for creating Organizations *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: useAuth() description: Access and manage authentication state in your application with Clerk's useAuth() hook. sdk: astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-auth.mdx --- The `useAuth()` hook provides access to the current user's authentication state and methods to manage the active session. > \[!NOTE] > To access auth data server-side, see the Auth object reference doc. ## Parameters | Parameter | Type | Description | | ---------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `initialAuthStateOrOptions?` | null \| Record\ \| \{ treatPendingAsSignedOut?: boolean; \} | An object containing the initial authentication state or options for the `useAuth()` hook. If not provided, the hook will attempt to derive the state from the context. `treatPendingAsSignedOut` is a boolean that indicates whether pending sessions are considered as signed out or not. Defaults to `true`. | ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `undefined` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has` | `undefined` | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `undefined` | The ID of the user's active organization. | | `orgRole` | `undefined` | The current user's role in their active organization. | | `orgSlug` | `undefined` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `undefined` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `undefined` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `undefined` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `null` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (params: CheckAuthorizationParamsWithCustomPermissions) => false | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `null` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `null` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `null` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `string` | The ID of the user's active organization. | | `orgRole` | `string` | The current user's role in their active organization. | | `orgSlug` | null \| string | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | ## Example The following example demonstrates how to use the `useAuth()` hook to access the current auth state, like whether the user is signed in or not. It also includes a basic example for using the `getToken()` method to retrieve a session token for fetching data from an external resource. ```tsx {{ filename: 'app/external-data.tsx' }} import { useAuth } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity } from 'react-native' export default function ExternalData() { const { userId, sessionId, getToken, isLoaded, isSignedIn } = useAuth() const fetchExternalData = async () => { const token = await getToken() // Fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Handle loading state if (!isLoaded) return Loading... // Protect the page from unauthenticated users if (!isSignedIn) return Sign in to view this page return ( Hello, {userId}! Your current active session is {sessionId}. Fetch Data ) } ``` --- title: useSessionList() description: Access and manage the current user's session list in your React application with Clerk's useSessionList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-session-list.mdx --- The `useSessionList()` hook returns an array of Session objects that have been registered on the client device. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | `undefined` | A list of sessions that have been registered on the client device. | | `setActive` | `undefined` | A function that sets the active session and/or organization. See the reference doc. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | SessionResource\[] | A list of sessions that have been registered on the client device. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. See the reference doc. | ## Example ### Get a list of sessions The following example uses `useSessionList()` to get a list of sessions that have been registered on the client device. The `sessions` property is used to show the number of times the user has visited the page. ```tsx {{ filename: 'app/(session-list)/page.tsx' }} import { useSessionList } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function Home() { const { isLoaded, sessions } = useSessionList() // Handle loading state if (!isLoaded) return Loading... return ( Welcome back. You've been here {sessions.length} times before. ) } ``` --- title: useSignIn() description: Access and manage the current user's sign-in state in your React application with Clerk's useSignIn() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-sign-in.mdx --- The `useSignIn()` hook provides access to the SignIn object, which allows you to check the current state of a sign-in attempt and manage the sign-in flow. You can use this to create a [custom sign-in flow](/docs/guides/development/custom-flows/overview#sign-in-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signIn` | `undefined` | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signIn` | SignInResource | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | ## Examples ### Check the current state of a sign-in The following example uses the `useSignIn()` hook to access the SignIn object, which contains the current sign-in attempt status and methods to create a new sign-in attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'app/(auth)/sign-in.tsx' }} import { useSignIn } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function SignInPage() { const { isLoaded, signIn } = useSignIn() // Handle loading state if (!isLoaded) return Loading... return ( The current sign-in attempt status is {signIn?.status}. ) } ``` ### Create a custom sign-in flow with `useSignIn()` The `useSignIn()` hook can also be used to build fully custom sign-in flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-in flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignIn()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useOrganization() description: Access and manage the currently active Organization in your React application with Clerk's useOrganization() hook. search: rank: 1 sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-organization.mdx --- The `useOrganization()` hook retrieves attributes of the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganization()` accepts a single object with the following optional properties: | Property | Type | Description | | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `domains?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ enrollmentMode?: "manual\_invitation" \| "automatic\_invitation" \| "automatic\_suggestion"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `enrollmentMode`: A string that filters the domains by the provided [enrollment mode](/docs/guides/organizations/verified-domains#enrollment-mode).
  • Any of the properties described in Shared properties.
| |
`invitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: ("expired" \| "pending" \| "accepted" \| "revoked")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`membershipRequests?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the membership requests by the provided status.
  • Any of the properties described in Shared properties.
| |
`memberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ query?: string; role?: string\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `role`: An array of OrganizationCustomRoleKey.
  • `query`: A string that filters the memberships by the provided string.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes aren't populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `invitations`, `membershipRequests`, `memberships`, and `domains` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | > \[!NOTE] > These attributes are updating automatically and will re-render their respective components whenever you set a different Organization using the setActive(\{ organization }) method or update any of the memberships or invitations. No need for you to manage updating anything manually. ## Returns | Property | Type | Description | | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `domains` | null \| PaginatedResourcesWithDefault\<OrganizationDomainResource\> \| PaginatedResources\<OrganizationDomainResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's domains. | | `invitations` | null \| PaginatedResourcesWithDefault\<OrganizationInvitationResource\> \| PaginatedResources\<OrganizationInvitationResource, T\["invitations"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's invitations. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `membership` | undefined \| null \| OrganizationMembershipResource | The current organization membership. | | `membershipRequests` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipRequestResource\> \| PaginatedResources\<OrganizationMembershipRequestResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's membership requests. | | `memberships` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["memberships"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's memberships. | | `organization` | undefined \| null \| OrganizationResource | The currently active organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expand and paginate attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // invitations.data will never be populated. const { invitations } = useOrganization() // Use default values to fetch invitations, such as initialPage = 1 and pageSize = 10 const { invitations } = useOrganization({ invitations: true, }) // Pass your own values to fetch invitations const { invitations } = useOrganization({ invitations: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { invitations } = useOrganization({ invitations: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```tsx {{ filename: 'screens/MemberList.tsx' }} import { useOrganization } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity, ScrollView } from 'react-native' export function MemberListScreen() { const { memberships } = useOrganization({ memberships: { infinite: true, // Append new data to the existing list keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return Loading... return ( Organization members {memberships.data?.map((membership) => ( {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role} ))} Load more ) } ``` ### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of memberships. Notice the difference between this example's pagination and the infinite pagination example above. ```tsx {{ filename: 'screens/MemberList.tsx' }} import { useOrganization } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity, ScrollView } from 'react-native' export function MemberListScreen() { const { memberships } = useOrganization({ memberships: { keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return Loading... return ( Organization members {memberships.data?.map((membership) => ( {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role} ))} Previous page Next page ) } ``` ## Related guides * [Update an Organization](/docs/guides/development/custom-flows/organizations/update-organizations) * Use Clerk's API to build a custom flow for updating an Organization *** * [Manage Roles in an Organization](/docs/guides/development/custom-flows/organizations/manage-roles) * Use Clerk's API to build a custom flow for managing Roles in an Organization *** * [Manage an Organization's membership requests](/docs/guides/development/custom-flows/organizations/manage-membership-requests) * Use Clerk's API to build a custom flow for managing an Organization's membership requests *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: Hooks Reference description: A list of Clerk's comprehensive suite of hooks for managing authentication, sessions, sign-in and sign-up flows, Organizations, and reverification. sdk: astro, chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/overview.mdx --- Clerk offers a comprehensive suite of hooks that expose low-level access to authentication, session management, and multi-tenancy. With Clerk hooks, you can access and manage user data, handle sign-in and sign-up flows, control session management, and implement advanced flows like session reverification for sensitive actions. By using these hooks, you can extend or replace Clerk's built-in components and customize how authentication behaves in your application. ## Hooks * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: useSession() description: Access and manage the current user's session in your React application with Clerk's useSession() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-session.mdx --- The `useSession()` hook provides access to the current user's Session object, as well as helpers for setting the active session. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `session` | `undefined` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `session` | `null` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `boolean` | A boolean that indicates whether a user is currently signed in. | | `session` | SignedInSessionResource | The current session for the user. | ## Example ### Access the `Session` object The following example uses the `useSession()` hook to access the `Session` object, which has the `lastActiveAt` property. The `lastActiveAt` property is a `Date` object used to show the time the session was last active. ```tsx {{ filename: 'app/(session)/page.tsx' }} import { useSession } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function HomePage() { const { isLoaded, session, isSignedIn } = useSession() // Handle loading state if (!isLoaded) return Loading... // Protect the page from unauthenticated users if (!isSignedIn) return Sign in to view this page return ( This session has been active since {session.lastActiveAt.toLocaleString()} ) } ``` --- title: useReverification() description: Clerk's useReverification() hook enhances a fetcher function to handle a session's reverification flow. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-reverification lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-reverification.mdx --- > \[!WARNING] > > Depending on the SDK you're using, this feature requires `@clerk/nextjs@6.12.7` or later, `@clerk/clerk-react@5.25.1` or later, `@clerk/clerk-js@5.57.1` or later and `@clerk/clerk-sdk-ruby@3.3.0` or later. Reverification allows you to prompt a user to verify their credentials before performing sensitive actions, even if they're already authenticated. For example, in a banking application, transferring money is considered a "sensitive action." Reverification can be used to confirm the user's identity. The `useReverification()` hook is used to handle a session's reverification flow. If a request requires reverification, a modal will display, prompting the user to verify their credentials. Upon successful verification, the original request will automatically retry. If you'd like to build a custom UI, you can use the onNeedsReverification option. When using reverification, a user's credentials are valid for 10 minutes. Once stale, a user will need to reverify their credentials. This time duration can be customized by using the `has()` helper on the server-side. See the [guide on reverification](/docs/guides/secure/reverification) for more information. ## Parameters | Parameter | Type | Description | | ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `fetcher` | `Fetcher extends (...args: any[]) => Promise` | A function that returns a promise. | | `options?` | `Options` | Optional configuration object extending UseReverificationOptions. | ### `UseReverificationOptions` The optional options object. | Property | Type | Description | | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | `onNeedsReverification?` | (properties: NeedsReverificationParameters) => void | Handler for the reverification process. Opts out of using the default UI. Use this to build a custom UI. | ### `NeedsReverificationParameters` | Property | Type | Description | | -------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `cancel` | () => void | Marks the reverification process as cancelled and rejects the original request. | | `complete` | () => void | Marks the reverification process as complete and retries the original request. | | `level` | undefined \| "first\_factor" \| "second\_factor" \| "multi\_factor" | The verification level required for the reverification process. | ## Examples The `useReverification()` hook displays a prebuilt UI when the user needs to reverify their credentials. You can also build a custom UI to handle the reverification process yourself. Use the following tabs to see examples of either option. > \[!WARNING] > Prebuilt UI is only supported for Expo web apps. For mobile apps, you need to build a custom UI. ### Handle reverification for an action The following example demonstrates how to use the `useReverification()` hook to require a user to reverify their credentials before being able to update their primary email address. It also demonstrates how to handle the cancellation of the reverification process. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/clerk-expo' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { Text, View, TouchableOpacity, ScrollView } from 'react-native' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification((emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return ( Your primary email address is {user?.primaryEmailAddress?.emailAddress} {user?.emailAddresses.map((email) => ( {email.emailAddress} {email.id !== user?.primaryEmailAddress?.id && ( handleClick(email.id)}> Make primary )} ))} ) } ``` ### Handle reverification for a fetcher function The following example demonstrates how to use the `useReverification()` hook to enhance a fetcher function that fetches data from a route that requires reverification. For examples on how to set up a route that requires reverification, see the [guide on reverification](/docs/guides/secure/reverification). ```tsx {{ filename: 'components/AccountBalance.tsx' }} import { useAuth, useReverification } from '@clerk/clerk-expo' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' import { Text, View, TouchableOpacity } from 'react-native' export function AccountBalance() { const { getToken } = useAuth() const [balance, setBalance] = useState(null) const accountBalance = useReverification(async () => { const response = await fetch('/api/balance', { headers: { Authorization: `Bearer ${await getToken()}`, }, }) return await response.json() }) const handleClick = async () => { try { const accountBalanceResponse = await accountBalance() setBalance(accountBalanceResponse.amount) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error('Error fetching account balance', e) } } return ( Your account balance is {balance ? `$${balance}` : '$******'} handleClick()}> See account balance ) } ``` The following example demonstrates how to build a custom UI when using the `useReverification()` hook. In the example, the `useReverification()` hook is used to require a user to reverify their credentials before being able to update their primary email address. It requires two components: the `` component displays the list of email addresses to choose from and it renders the second component, ``, which handles the reverification process. The example handles first factor verification using an email code, so you will need to have the [**Email verification code**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) setting enabled for your application. But you can adapt this example to handle any type of verification level or strategy. The `` component uses `useReverification()` to enhance the `update()` method, requiring the user to reverify their credentials before being able to update their primary email address. The `useReverification()` hook provides the `onNeedsReverification` option, which is a handler for building a custom UI. It provides four properties: `level`, `complete`, `cancel`, and `inProgress`. The example tracks these using the `verificationState` state variable. * The `level` property determines the verification level required for the reverification process. This example only handles first factor verification, which is done in the `` component. * The `complete` and `cancel` properties are the steps of the reverification process, which is also done in the `` component. * The `inProgress` property is used to track the state of the reverification process. When the user selects the "Make primary" button, it triggers the reverification process and sets the `inProgress` property is `true`, which displays the `` component. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/clerk-expo' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' import { SessionVerificationLevel } from '@clerk/types' import { VerificationComponent } from './VerificationComponent' import { Text, View, TouchableOpacity, ScrollView } from 'react-native' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // TODO: Update to use exported type once available const [verificationState, setVerificationState] = useState< | { complete: () => void cancel: () => void level: SessionVerificationLevel | undefined inProgress: boolean } | undefined >(undefined) // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification( (emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), { onNeedsReverification: ({ complete, cancel, level }) => { setVerificationState({ complete, cancel, level, inProgress: true, }) }, }, ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return ( Your primary email address is {user?.primaryEmailAddress?.emailAddress} {user?.emailAddresses.map((email) => ( {email.emailAddress} {user?.primaryEmailAddressId !== email.id && ( handleClick(email.id)}> Make primary )} ))} {verificationState?.inProgress && ( { verificationState.complete() setVerificationState(undefined) }} onCancel={() => { verificationState.cancel() setVerificationState(undefined) }} /> )} ) } ``` The `` component handles the reverification process. It uses the `level` property to determine the verification level, which is set to `first_factor`. First, it finds the determined starting first factor from the supported first factors. Then, it prepares the first factor verification using the `strategy` (`email_code` in this case) and `emailAddressId` properties. Finally, it attempts to verify the session with email code provided by the user. If the verification is successful, the `onComplete()` handler is called to complete the reverification process. ```tsx {{ filename: 'components/VerificationComponent.tsx', collapsible: true }} import { useEffect, useRef, useState } from 'react' import { useSession } from '@clerk/clerk-expo' import { EmailCodeFactor, SessionVerificationLevel, SessionVerificationResource, } from '@clerk/types' import { Text, View, TouchableOpacity, TextInput } from 'react-native' export function VerificationComponent({ level = 'first_factor', onComplete, onCancel, }: { level: SessionVerificationLevel | undefined onComplete: () => void onCancel: () => void }) { const { session } = useSession() const [code, setCode] = useState('') const reverificationRef = useRef(undefined) const [determinedStartingFirstFactor, setDeterminedStartingFirstFactor] = useState< EmailCodeFactor | undefined >() useEffect(() => { if (reverificationRef.current) { return } session?.startVerification({ level }).then(async (response) => { reverificationRef.current = response await prepareEmailVerification(response) }) }, []) const prepareEmailVerification = async (verificationResource: SessionVerificationResource) => { // To simplify the example we will only handle the first factor verification if (verificationResource.status === 'needs_first_factor') { // Determine the starting first factor from the supported first factors const determinedStartingFirstFactor = verificationResource.supportedFirstFactors?.filter( (factor) => factor.strategy === 'email_code', )[0] if (determinedStartingFirstFactor) { setDeterminedStartingFirstFactor(determinedStartingFirstFactor) // Prepare the first factor verification with the determined starting first factor await session?.prepareFirstFactorVerification({ strategy: determinedStartingFirstFactor.strategy, emailAddressId: determinedStartingFirstFactor?.emailAddressId, }) } } } const handleVerificationAttempt = async () => { try { // Attempt to verify the session with the provided code await session?.attemptFirstFactorVerification({ strategy: 'email_code', code, }) onComplete() } catch (e) { // Any error from the attempt to verify the session can be handled here console.error('Error verifying session', e) } } if (!determinedStartingFirstFactor) { return null } return ( Enter verification code sent to {determinedStartingFirstFactor.safeIdentifier || ''} handleVerificationAttempt()}> Complete onCancel()}> Cancel ) } ``` ## Related guides See the custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). guides for examples of how to use the `useReverification()` hook, such as the [Add a phone number to a user's account](/docs/guides/development/custom-flows/account-updates/add-phone) guide. --- title: useClerk() description: Access and manage the Clerk object in your React application with Clerk's useClerk() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-clerk lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-clerk.mdx --- > \[!WARNING] > This hook should only be used for advanced use cases, such as building a completely custom OAuth flow or as an escape hatch to access to the `Clerk` object. The `useClerk()` hook provides access to the Clerk object, allowing you to build alternatives to any Clerk Component. ## Returns Clerk — The `useClerk()` hook returns the `Clerk` object, which includes all the methods and properties listed in the Clerk reference. ## Example The following example uses the `useClerk()` hook to access the `clerk` object. The `clerk` object is used to call the openSignIn() method to open the sign-in modal. ```tsx {{ filename: 'app/(clerk)/index.tsx' }} import { useClerk } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity } from 'react-native' export default function Page() { const clerk = useClerk() return ( clerk.openSignIn({})}> Sign in ) } ``` --- title: useSignUp() description: Access and manage the current user's sign-up state in your React application with Clerk's useSignUp() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-sign-up.mdx --- The `useSignUp()` hook provides access to the SignUp object, which allows you to check the current state of a sign-up attempt and manage the sign-up flow. You can use this to create a [custom sign-up flow](/docs/guides/development/custom-flows/overview#sign-up-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signUp` | `undefined` | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signUp` | SignUpResource | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | ## Examples ### Check the current state of a sign-up The following example uses the `useSignUp()` hook to access the SignUp object, which contains the current sign-up attempt status and methods to create a new sign-up attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'app/(auth)/sign-up.tsx' }} import { useSignUp } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function SignUpPage() { const { isLoaded, signUp } = useSignUp() // Handle loading state if (!isLoaded) return Loading... return ( The current sign-up attempt status is {signUp?.status}. ) } ``` ### Create a custom sign-up flow with `useSignUp()` The `useSignUp()` hook can also be used to build fully custom sign-up flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-up flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignUp()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useUser() description: Access and manage the current user's data in your React application with Clerk's useUser() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/hooks/use-user.mdx --- The `useUser()` hook provides access to the current user's User object, which contains all the data for a single user in your application and provides methods to manage their account. This hook also allows you to check if the user is signed in and if Clerk has loaded and initialized. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that returns `true` if the user is signed in. | | `user` | `undefined` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that returns `true` if the user is signed in. | | `user` | `null` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that returns `true` if the user is signed in. | | `user` | UserResource | The `User` object for the current user. | ## Examples ### Get the current user The following example uses the `useUser()` hook to access the User object, which contains the current user's data such as their full name. The `isLoaded` and `isSignedIn` properties are used to handle the loading state and to check if the user is signed in, respectively. ```tsx {{ filename: 'app/(user)/index.tsx' }} import { useUser } from '@clerk/clerk-expo' import { Text, View } from 'react-native' export default function Page() { const { isSignedIn, user, isLoaded } = useUser() // Handle loading state if (!isLoaded) return Loading... // Protect the page from unauthenticated users if (!isSignedIn) return Sign in to view this page return ( Hello {user.firstName}! ) } ``` ### Update user data The following example uses the `useUser()` hook to access the User object, which calls the update() method to update the current user's information. ```tsx {{ filename: 'app/(user)/index.tsx' }} import { useUser } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity } from 'react-native' export default function Page() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return Loading... // Protect the page from unauthenticated users if (!isSignedIn) return Sign in to view this page const updateUser = async () => { await user.update({ firstName: 'John', lastName: 'Doe', }) } return ( Update your name user.firstName: {user.firstName} user.lastName: {user.lastName} ) } ``` ### Reload user data The following example uses the `useUser()` hook to access the User object, which calls the reload() method to get the latest user's information. ```tsx {{ filename: 'app/(user)/index.tsx' }} import { useUser } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity } from 'react-native' export default function Page() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return Loading... // Protect the page from unauthenticated users if (!isSignedIn) return Sign in to view this page const updateUser = async () => { // Update data via an API endpoint const updateMetadata = await fetch('/api/updateMetadata', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role: 'admin', }), }) // Check if the update was successful if ((await updateMetadata.json()).message !== 'success') { throw new Error('Error updating') } // If the update was successful, reload the user data await user.reload() } return ( Update your metadata user role: {user.publicMetadata.role} ) } ``` --- title: Chrome Extension Quickstart description: Add authentication and user management to your Chrome Extension with Clerk. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: chrome-extension sourceFile: /docs/getting-started/quickstart.chrome-extension.mdx --- ## Enable Native API In the Clerk Dashboard, navigate to the [**Native Applications**](https://dashboard.clerk.com/~/native-applications) page and ensure that the Native API is enabled. This is required to integrate Clerk in your native application. ## Configure your authentication options When creating your Clerk application in the Clerk Dashboard, your authentication options will depend on how you configure your Chrome Extension. Chrome Extensions can be used as a popup, a side panel, or in conjunction with a web app. Popups and side panels have limited authentication options. [Learn more about what options are available.](/docs/reference/chrome-extension/overview#authentication-options) This guide will use a popup. ## Create a new app using the Plasmo framework [Plasmo](https://docs.plasmo.com/framework) is a browser extension framework that includes hot reloading and creating development and production extension builds easily from the same code. Plasmo strongly recommends using `pnpm`, so this guide will only use `pnpm`-based examples. The following command creates an app with Tailwind CSS preconfigured and with a `src/` directory. You can choose to remove one or both of those options. ```bash {{ filename: 'terminal' }} pnpm create plasmo --with-tailwindcss --with-src clerk-chrome-extension cd clerk-chrome-extension ``` ## Install `@clerk/chrome-extension` The [Clerk Chrome Extension SDK](/docs/reference/chrome-extension/overview) gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Add the SDK to your project: ```bash {{ filename: 'terminal' }} pnpm add @clerk/chrome-extension ``` ## Set your Clerk API keys Plasmo offers [several options](https://docs.plasmo.com/framework/env) for environment variable files, as the same codebase can be used for development and production builds, as well as for targeting different browsers. This guide uses `.env.development` and `.env.chrome` files. Add the following keys to your `.env.development` file. These keys can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, select **Chrome Extension** and copy your Clerk Publishable Key and Frontend API URL. 3. Paste your keys into your `.env.development` file. The final result should resemble the following: ```env {{ filename: '.env.development' }} PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_FRONTEND_API=https://{{fapi_url}} ``` ## Add `` to your app The \ component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with `` to make authentication globally accessible. See the reference docs for other configuration options. ```tsx {{ filename: 'src/popup.tsx', mark: [1, [7, 11], 15, 19] }} import { ClerkProvider } from '@clerk/chrome-extension' import { CountButton } from '~features/count-button' import '~style.css' const PUBLISHABLE_KEY = process.env.PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Please add the PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY to the .env.development file') } function IndexPopup() { return (
) } export default IndexPopup ``` ## Create a header with Clerk components You can control what content signed in and signed out users can see with Clerk's prebuilt components. Create a header with the following Clerk components. (With Chrome Extensions, you can also add this logic to a footer). * \: Children of this component can only be seen while **signed in**. * \: Children of this component can only be seen while **signed out**. * \: A prebuilt component that comes styled out-of-the-box to show the avatar from the account the user is signed in with. * \: An unstyled component that links to the sign-in page. For this example, because you have not specified any props or [environment variables](/docs/guides/development/clerk-environment-variables) for the sign-in URL, the component will link to the [Account Portal sign-in page](/docs/guides/customizing-clerk/account-portal#sign-in). ```tsx {{ filename: 'src/popup.tsx', mark: [[1, 7], [22, 29]] }} import { ClerkProvider, SignInButton, SignedIn, SignedOut, UserButton, } from '@clerk/chrome-extension' import { CountButton } from '~features/count-button' import '~style.css' const PUBLISHABLE_KEY = process.env.PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Please add the PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY to the .env.development file') } function IndexPopup() { return (
) } export default IndexPopup ``` ## Update `` props for Chrome Extension navigation To avoid navigation errors, set the `afterSignOutUrl`, `signInFallbackRedirectUrl` and `signUpFallbackRedirectUrl` props for ``. Chrome Extensions don't use an `http` URL, such as `http://localhost:3000`. Instead, they use a `chrome-extension://` URL appended with an unique extension ID called a CRX ID. This URL is what you will pass to these props. ```tsx {{ filename: 'src/popup.tsx', mark: [14, [24, 26]] }} import { ClerkProvider, SignInButton, SignedIn, SignedOut, UserButton, } from '@clerk/chrome-extension' import { CountButton } from '~features/count-button' import '~style.css' const PUBLISHABLE_KEY = process.env.PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY const EXTENSION_URL = chrome.runtime.getURL('.') if (!PUBLISHABLE_KEY) { throw new Error('Please add the PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY to the .env.development file') } function IndexPopup() { return (
) } export default IndexPopup ``` ## Create a consistent CRX ID for your extension Chrome Extensions have a unique CRX ID that rotates by default, which can cause errors with the Clerk integration. To avoid these problems, ensure that you have a **consistent** CRX ID in both development and production for your extension by following these steps: 1. Visit Plasmo Itero's [Generate Keypairs](https://itero.plasmo.com/tools/generate-keypairs) tool. 2. Select **Generate KeyPairs**. 3. Save the **Private Key** somewhere secure in case you need it in the future. Save the **Public Key** and the **CRX ID** for the next steps. ## Create an `.env.chrome` file to store your public key Create an `.env.chrome` file and add your public key to it, as shown in the following example: ```env {{ filename: '.env.chrome' }} CRX_PUBLIC_KEY= ``` ## Edit your `package.json` to use the new public key Plasmo [uses the `package.json` to generate a `manifest.json` on build](https://docs.plasmo.com/framework#where-is-the-manifestjson-file), and allows for the use of environment variables in `package.json`. In your `package.json`, in the `manifest` object: * Set the `key` value to `"$CRX_PUBLIC_KEY"`. This helps configure the consistent CRX ID for your extension. * Set the `permissions` array to include `"cookies"` and `"storage"`. `permissions` specifies which permissions your extension requires. * Set or update the `host_permissions` array to include `"http://localhost/*"` and `"$CLERK_FRONTEND_API/*"`. `host_permissions` specifies which hosts, or websites, have permission to sync auth state with your app. ```json {{ filename: 'package.json' }} { // The rest of your package.json file "manifest": { "key": "$CRX_PUBLIC_KEY", "permissions": ["cookies", "storage"], "host_permissions": ["http://localhost/*", "$CLERK_FRONTEND_API/*"] } } ``` ## Use `pnpm dev` to start your development server and create a build Plasmo facilitates Chrome Extension development by automatically "hot loading" the app whenever you save a changed file in the project. This ensures the `build/chrome-mv3-dev` folder remains up to date. Without the plugin, you would need to manually execute the build command and reload your Chrome Extension after each change. Plasmo automates this process, streamlining development. Run the following command to start your development environment. This also creates the build in `build/chrome-mv3-dev`, and rebuilds when you make changes to the extension. ```bash {{ filename: 'terminal' }} pnpm dev ``` ## Load your Chrome Extension into your Chromium-based browser To load your Chrome Extension, follow these steps: 1. Open Chrome or a Chromium-based browser and navigate to `chrome://extensions`. 2. In the top-right, enable **Developer mode**. 3. In the top-left, select **Load unpacked**. 4. Navigate to where your project is located and select the `build/chrome-mv3-dev` folder. Then select **Select**. Your extension will now be loaded and shown in the list of extensions. 5. Confirm that the ID shown in your extension matches the CRX ID you saved earlier. ## Test your Chrome Extension In your Chrome browser, open the extension popup. Ensure that the `` appears, and that selecting it opens the `` modal. Sign in and ensure that the `` appears in the header. > \[!WARNING] > After signing up or signing in, your popup may appear to crash. Closing and reopening the popup should restart the extension and you should be signed in. > > Your extension does not yet have anything to handle routing, and by default, the Clerk components attempt to redirect the user. See [the guide on adding React Router to your Chrome Extension](/docs/guides/development/add-react-router) to add routing to your extension.
## Next steps * [Add React Router](/docs/guides/development/add-react-router) * Learn how to add React Router to your Chrome Extension. *** * [Sync your Chrome Extension with your web app](/docs/guides/sessions/sync-host) * Learn how to configure your Chrome Extension to sync user authentication with your web application. *** * [createClerkClient()](/docs/reference/chrome-extension/create-clerk-client) * For Chrome Extension's configured as popups, learn how to use Clerk's `createClerkClient()` function in a background service worker to ensure that the user's session is always fresh. --- title: "``" description: The component provides session and user context to Clerk's hooks and components. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/clerk-provider lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/clerk-provider.mdx --- The `` component is required to integrate Clerk into your React application, providing session and user context to Clerk's hooks and components. The recommended approach is to wrap your entire app with `` at the entry point to make authentication globally accessible. If you only need authentication for specific routes or pieces of your application, render `` deeper in the component tree. This allows you to implement Clerk's functionality precisely where required without impacting the rest of your app. ## Example ```jsx {{ filename: 'src/routes/index.tsx' }} import { ClerkProvider, SignedIn, SignedOut, UserButton, SignInButton, } from '@clerk/chrome-extension' const PUBLISHABLE_KEY = process.env.PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY const EXTENSION_URL = chrome.runtime.getURL('.') if (!PUBLISHABLE_KEY) { throw new Error('Please add the PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY to the .env.development file') } export default function Index() { return (
) } ```
## Properties | Property | Type | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`afterMultiSessionSingleSignOutUrl?` | null \| string | The full URL or path to navigate to after signing out the current user is complete. This option applies to [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). | | ~~`afterSignInUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl` or `signInForceRedirectUrl` instead. | | `afterSignOutUrl?` | null \| string | Full URL or path to navigate to after successful sign out. | | ~~`afterSignUpUrl?`~~ | null \| string | **Deprecated.** Use `signUpFallbackRedirectUrl` or `signUpForceRedirectUrl` instead. | | `allowedRedirectOrigins?` | (string \| RegExp)\[] | An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `allowedRedirectProtocols?` | string\[] | An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `appearance?` | [`Appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) | Optional object to style your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `clerkJSUrl?` | `string` | The URL that `@clerk/clerk-js` should be hot-loaded from. | | `clerkJSVariant?` | "" \| "headless" | If your web application only uses Control Components, you can set this value to `'headless'` and load a minimal ClerkJS bundle for optimal page performance. | | `clerkJSVersion?` | `string` | The npm version for `@clerk/clerk-js`. | | `domain?` | string \| (url: URL) => string | **Required if your application is a satellite application**. Sets the domain of the satellite application. | | `experimental?` | `Autocomplete`\<\{ commerce: boolean; persistClient: boolean; rethrowOfflineNetworkErrors: boolean; \}, `Record`\<`string`, `any`\>\> | Enable experimental flags to gain access to new features. These flags are not guaranteed to be stable and may change drastically in between patch or minor versions. | | `initialState?` | `Serializable`\<\{ actor: undefined \| \{ \[x: string]: unknown; sub: string; \}; factorVerificationAge: \[number, number]; organization: undefined \| OrganizationResource; orgId: undefined \| string; orgPermissions: undefined \| string\[]; orgRole: undefined \| string; orgSlug: undefined \| string; session: undefined \| SessionResource; sessionClaims: JwtPayload; sessionId: undefined \| string; sessionStatus: SessionStatusClaim; user: undefined \| UserResource; userId: undefined \| string; \}\> | Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `isSatellite?` | boolean \| (url: URL) => boolean | A boolean that indicates whether the application is a satellite application. | | `localization?` | [`LocalizationResource`](/docs/guides/customizing-clerk/localization) | Optional object to localize your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `newSubscriptionRedirectUrl?` | null \| string | The URL to navigate to after the user completes the checkout and clicks the "Continue" button. | | `nonce?` | `string` | This nonce value will be passed through to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. | | `proxyUrl?` | string \| (url: URL) => string \| (url: URL) => string | **Required for applications that run behind a reverse proxy**. The URL that Clerk will proxy requests to. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). | | `publishableKey` | `string` | The Clerk Publishable 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. | | ~~`redirectUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl`, `signInForceRedirectUrl`, `signUpFallbackRedirectUrl`, or `signUpForceRedirectUrl` instead. | | `routerPush?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "push" navigation. | | `routerReplace?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "replace" navigation. | | `sdkMetadata?` | \{ environment?: string; name: string; version: string; \} | Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `sdkMetadata.environment?` | `string` | Typically this will be the `NODE_ENV` that the SDK is currently running in. | | `sdkMetadata.name` | `string` | The npm package name of the SDK. | | `sdkMetadata.version` | `string` | The npm package version of the SDK. | | `selectInitialSession?` | (client: ClientResource) => null \| SignedInSessionResource | By default, the last signed-in session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. | | `signInFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signInForceRedirectUrl?` | null \| string | 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. | | `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. | | `signUpFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signUpForceRedirectUrl?` | null \| string | 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. | | `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. | | `standardBrowser?` | `boolean` | By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. | | `supportEmail?` | `string` | Optional support email for display in authentication screens. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `taskUrls?` | `Record`\<`"choose-organization"`, `string`\> | Customize the URL paths users are redirected to after sign-in or sign-up when specific session tasks need to be completed. When `undefined`, it uses Clerk's default task flow URLs. Defaults to `undefined`. | | `telemetry?` | false \| \{ debug?: boolean; disabled?: boolean; perEventSampling?: boolean; \} | Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. | | `touchSession?` | `boolean` | By default, the [Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/Sessions#operation/touchSession) is called during page focus to keep the last active session alive. This option allows you to disable this behavior. | | `waitlistUrl?` | `string` | The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). | ## SDK-specific properties ### Next.js * `dynamic` * `boolean` Indicates whether or not Clerk should make dynamic auth data available based on the current request. Defaults to `false`. Opts the application into dynamic rendering when `true`. For more information, see Next.js rendering modes and Clerk. ### Chrome Extension * `syncHost` * `string` To enable, pass the URL of the web application that the extension will sync the authentication state from. See the [dedicated guide](/docs/guides/sessions/sync-host) for more information. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: chrome-extension sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`` component" description: Clerk's component renders a UI for signing in users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/authentication/sign-in.mdx --- ![The \ component renders a UI for signing in users.](/docs/images/ui-components/sign-in.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI to allow users to sign in or sign up by default. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'src/routes/sign-in.tsx' }} import { SignIn } from '@clerk/chrome-extension' export default function SignInPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `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. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-in`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signUpFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Used for the 'Don't have an account? Sign up' link that's rendered. Defaults to `/`. 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 used as the redirect destination after the user signs up. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signUpUrl` * `string` The full URL or path to the sign-up page. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `transferable` * `boolean` Indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `waitlistUrl` * `string` Full URL or path to the waitlist page. Use this property to provide the target of the 'Waitlist' link that's rendered. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). If you've passed the `waitlistUrl` prop to the \ component, it will infer from that, and you can omit this prop. *** * `withSignUp` * `boolean` Opt into sign-in-or-up flow by setting this prop to `true`. When `true`, if a user does not exist, they will be prompted to sign up. If a user exists, they will be prompted to sign in. Defaults to `true` if the `CLERK_SIGN_IN_URL` environment variable is set. Otherwise, defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: The component renders a waitlist form that allows users to join for early access to your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/waitlist lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/authentication/waitlist.mdx --- ![The \ component renders a form that allows users to join for early access to your app.](/docs/images/ui-components/waitlist.png){{ style: { maxWidth: '460px' } }} In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. [Learn more about additional features available in **Waitlist** mode](/docs/guides/secure/restricting-access#waitlist). The `` component renders a form that allows users to join for early access to your app. ## Enable Waitlist mode Before using the `` component, you must enable **Waitlist** mode in the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. ## Example > \[!WARNING] > Before using the `` component, you must provide the `waitlistUrl` prop either in the \ or \ component to ensure proper functionality. The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'src/routes/waitlist.tsx' }} import { Waitlist } from '@clerk/chrome-extension' export default function WaitlistPage() { return } ``` ## Properties All props are optional. * `afterJoinWaitlistUrl` * `string` The full URL or path to navigate to after joining the waitlist. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `signInUrl` * `string` The full URL or path to the sign in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. ## Customization To learn about how to customize Clerk components, see the [customization guide](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component renders a UI for signing up users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/authentication/sign-up.mdx --- ![The \ component renders a UI for signing up users.](/docs/images/ui-components/sign-up.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'src/routes/sign-up.tsx' }} import { SignUp } from '@clerk/chrome-extension' export default function SignUpPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `string` If provided, this URL will always be used as the redirect destination 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. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-up`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signInFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Used for the 'Already have an account? Sign in' link that's rendered. 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. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signInUrl` * `string` The full URL or path to the sign-in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "``" description: Clerk's component displays a table of Plans and Features that users can subscribe to. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/pricing-table lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/billing/pricing-table.mdx --- ![The \ component displays a table of Plans and Features that users can subscribe to.](/docs/images/ui-components/pricing-table.png) The `` component displays a table of Plans and Features that users can subscribe to. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'src/routes/pricing.tsx' }} import { PricingTable } from '@clerk/chrome-extension' export default function PricingPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `checkoutProps` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `collapseFeatures` * `boolean` A boolean that indicates whether the Features are collapsed. **Requires `layout` to be set to `'default'`**. Defaults to `false`. *** * `ctaPosition` * `'top' | 'bottom'` The placement of the CTA button. **Requires `layout` to be set to `'default'`**. Defaults to `'bottom'`. *** * `fallback` * `JSX` An optional UI to show when the pricing table is loading. *** * `for` * `'user' | 'organization'` A string that indicates whether the pricing table is for users or [Organizations](/docs/guides/organizations/overview). If `'user'`, the pricing table will display a list of Plans and Features that **users** can subscribe to. If `'organization'`, the pricing table will display a list of Plans and Features that **Organizations** can subscribe to. Defaults to `'user'`. *** * `newSubscriptionRedirectUrl` * `string` The URL to navigate to after the user completes the checkout and selects the "Continue" button. --- title: "``" description: The component indicates that Clerk is partially operational. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-degraded lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/clerk-degraded.mdx --- The `` component indicates that Clerk is partially operational. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```jsx {{ filename: 'src/routes/home.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/chrome-extension' export default function Home() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: \RedirectCallback /> description: Clerk's `` component is used to implement custom OAuth flows. It handles the OAuth callback and completes the authentication process. sdk: astro, chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/authenticate-with-redirect-callback lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: expo,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/authenticate-with-redirect-callback.mdx --- The `` component is a crucial part of implementing custom OAuth flows in your application. It serves as the callback handler for the authentication process initiated by the `authenticateWithRedirect()` method. Render it on the route specified as the `redirectUrl` in your `authenticateWithRedirect()` call. This component automatically handles the OAuth callback, completing the authentication process and managing the user's session. It uses the handleRedirectCallback() method under the hood. ## Example For an example of how to use the `` component, see the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) guide. ## Properties All props are optional. * `continueSignUpUrl?` * `string | undefined | null` The full URL or path to navigate to if the sign up requires additional information. *** * `signInUrl?` * `string` The full URL or path where the `` component is mounted. *** * `signUpUrl?` * `string` The full URL or path where the `` component is mounted. *** * `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. *** * `firstFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if first factor verification is required. *** * `secondFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) is enabled. *** * `resetPasswordUrl?` * `string` The full URL or path to navigate to during sign in, if the user is required to reset their password. *** * `transferable?` * `boolean` A boolean that indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `verifyEmailAddressUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting email verification. *** * `verifyPhoneNumberUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting phone verification. --- title: "``" description: The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loading lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/clerk-loading.mdx --- The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```jsx {{ filename: 'src/routes/home.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/chrome-extension' export default function Home() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the Clerk object without the need to check it exists. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loaded lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/clerk-loaded.mdx --- The `` component guarantees that the Clerk object has loaded (the `status` is `'ready'` or `'degraded'`) and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```jsx {{ filename: 'src/routes/home.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/chrome-extension' export default function Home() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The Protect component protects content or even entire routes based on authentication, and optionally, authorization. It only renders its children when the current user is signed-in, and if performing authorization checks, if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/protect lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/protect.mdx --- The \ component protects content or even entire routes based on: * authentication: whether the user is signed-in or not. * authorization: whether the user has been granted a specific type of access control (Role, Permission, Feature, or Plan) `` **always** performs authentication checks. To perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., you can pass different props, like `role`, `permission`, `feature`, or `plan`. `` accepts a `fallback` prop that will be rendered if the user fails the authentication or authorization checks. `` can be used both client-side and server-side (in Server Components). > \[!CAUTION] > This component only **visually hides** its children when the current user is not authorized. The contents of its children remain accessible via the browser's source code even if the user fails the authorization check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Usage ### Authentication checks `` always performs authentication checks. It will render its children if the user is signed-in, and its `fallback` prop if the user is signed-out. ```jsx {{ filename: 'src/routes/dashboard.tsx' }} import { Protect } from '@clerk/chrome-extension' export default function DashboardPage() { return ( Users that are signed-out can see this.

}>

Users that are signed-in can see this.

) } ```
### Authorization checks To limit who is able to see the content that `` renders, you can pass **one** of the access control props: `permission`, `role`, `feature`, or `plan`. It's recommended to use **Permission-based** authorization over **Role-based** authorization, and **Feature-based** authorization over **Plan-based** authorization, as they are more flexible, easier to manage, and more secure. If you do not pass any of the access control props, `` will render its children if the user is signed in, regardless of their Role or its Permissions. For more complex authorization logic, pass conditional logic to the `condition` prop. ### Render content by Permissions The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:invoices:create` Permission. ```jsx {{ filename: 'src/routes/invoices.tsx' }} import { Protect } from '@clerk/chrome-extension' export default function InvoicesPage() { return ( You do not have the Permissions to create an invoice.

} >

Users with Permission org:invoices:create can see this.

) } ```
### Render content by Role While authorization by `permission` is **recommended**, for convenience, `` allows a `role` prop to be passed. The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:billing` Role. ```jsx {{ filename: 'src/routes/billing.tsx' }} import { Protect } from '@clerk/chrome-extension' export default function BillingPage() { return ( Only a member of the Billing department can access this content.

} >

Users with Role org:billing can see this.

) } ```
### Render content by Plan The following example demonstrates how to use `` to protect content by checking if the user has a Plan. ```jsx {{ filename: 'src/routes/bronze.tsx' }} import { Protect } from '@clerk/chrome-extension' export default function BronzePage() { return ( Sorry, only subscribers to the Bronze plan can access this content.

} >

Welcome, Bronze subscriber!

) } ```
### Render content by Feature The following example demonstrates how to use `` to protect content by checking if the user has a Feature. ```jsx {{ filename: 'src/routes/premium-access.tsx' }} import { Protect } from '@clerk/chrome-extension' export default function PremiumAccessPage() { return ( Sorry, only subscribers with the Premium Access feature can access this content.

} >

Congratulations! You have access to the Premium Access feature.

) } ```
### Render content conditionally The following example uses ``'s `condition` prop to conditionally render its children if the user has the correct Role. ```jsx {{ filename: 'src/routes/settings.tsx' }} import { Protect } from '@clerk/chrome-extension' export default function SettingsPage() { return ( has({ role: 'org:admin' }) || has({ role: 'org:billing_manager' })} fallback={

Only an Admin or Billing Manager can access this content.

} >

The settings page.

) } ```
## Properties * `condition?` * `has => boolean` Optional conditional logic that renders the children if it returns `true`. *** * `fallback?` * `JSX` Optional UI to show when a user doesn't have the correct type of access control to access the protected content. *** * `feature?` * `string` Optional string corresponding to a [Feature](/docs/guides/billing/overview). *** * `plan?` * `string` Optional string corresponding to a [Plan](/docs/guides/billing/overview). *** * `permission?` * `string` Optional string corresponding to a [Permission](/docs/guides/organizations/roles-and-permissions) in the format `org::` *** * `role?` * `string` Optional string corresponding to a [Role](/docs/guides/organizations/roles-and-permissions) in the format `org:` *** * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: The component indicates that the Clerk object has failed to load. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-failed lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/clerk-failed.mdx --- The `` component indicates that the Clerk object has failed to load. This is useful for displaying an error message to the user. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```jsx {{ filename: 'src/routes/home.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/chrome-extension' export default function Home() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/redirect-to-sign-in.mdx --- The `` component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example > \[!NOTE] > This component relies on React Router for navigation. Ensure that you have integrated React Router into your Chrome Extension application before using it. [Learn how to add React Router to your Chrome Extension](/docs/guides/development/add-react-router). ```jsx {{ filename: 'src/routes/home.tsx' }} import { SignedIn, SignedOut, RedirectToSignIn, UserButton } from '@clerk/chrome-extension' export default function Home() { return ( <> ) } ``` --- title: "``" description: The component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/redirect-to-sign-up.mdx --- The `` component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example > \[!NOTE] > This component relies on React Router for navigation. Ensure that you have integrated React Router into your Chrome Extension application before using it. [Learn how to add React Router to your Chrome Extension](/docs/guides/development/add-react-router). ```jsx {{ filename: 'src/routes/home.tsx' }} import { SignedIn, SignedOut, RedirectToSignUp, UserButton } from '@clerk/chrome-extension' export default function Home() { return ( <> ) } ``` --- title: "``" description: The component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-tasks lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,remix,go,astro,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/redirect-to-tasks.mdx --- The `` component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks**Session tasks** are requirements that users must fulfill in order to complete the authentication process, such as choosing an Organization.. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. The `` component is primarily intended for use in custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. If you're using prebuilt components, you typically won't need to use `` as these components manage task redirection internally. [See the guide on handling session tasks outside of prebuilt components](/docs/guides/configure/session-tasks#redirecting-to-tasks). ## Example > \[!NOTE] > This component relies on React Router for navigation. Ensure that you have integrated React Router into your Chrome Extension application before using it. [Learn how to add React Router to your Chrome Extension](/docs/guides/development/add-react-router). ```jsx {{ filename: 'src/routes/home.tsx' }} import { SignedOut, RedirectToTasks } from '@clerk/chrome-extension' export default function Home() { return ( <> ) } ``` --- title: "``" description: Conditionally render content only when a user is signed in. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/signed-in.mdx --- ## Overview The `` component offers authentication checks as a cross-cutting concern. Any children components wrapped by a `` component will be rendered only if there's a user with an active session signed in your application. > \[!CAUTION] > This component only **visually hides** its children when the current user is not authenticated. The contents of its children remain accessible via the browser's source code even if the user fails the authentication check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Example ```jsx {{ filename: 'src/routes/home.tsx' }} import { SignedIn } from '@clerk/chrome-extension' export default function Home() { return ( <>

You are signed in.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: Conditionally render content only when a user is signed out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-out lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/control/signed-out.mdx --- The `` component offers authentication checks as a cross-cutting concern. Any child nodes wrapped by a `` component will be rendered only if there's no User signed in to your application. ## Example ```jsx {{ filename: 'src/routes/home.tsx' }} import { SignedOut } from '@clerk/chrome-extension' export default function Home() { return ( <>

You are signed out.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` component" description: Clerk's component is used to render an Organization creation UI that allows users to create brand new Organizations within your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/organization/create-organization.mdx --- ![The \ component renders an Organization creation UI that allows users to create brand new organizations within your application.](/docs/images/ui-components/create-organization.png){{ style: { maxWidth: '492px' } }} The `` component is used to render an Organization creation UI that allows users to create brand new Organizations in your application. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'src/routes/create-organization.tsx' }} import { CreateOrganization } from '@clerk/chrome-extension' export default function Home() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterCreateOrganizationUrl` * `string` Full URL or path to navigate to after creating a new organization. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/create-organization`. *** * `skipInvitationScreen` * `boolean` Hides the screen for sending invitations after an Organization is created. When left undefined, Clerk will automatically hide the screen if the number of max allowed members is equal to 1 *** * `hideSlug` * `boolean` Hides the optional slug field in the Organization creation screen. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to display Organization related memberships, invitations, and suggestions for the user. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/organization/organization-list.mdx --- ![The \ component displays Organization-related memberships and automatic invitations and suggestions for the user.](/docs/images/ui-components/organization-list.png){{ style: { maxWidth: '460px' } }} The `` component displays Organization-related memberships and automatic [invitations](/docs/guides/organizations/verified-domains#automatic-invitations) and [suggestions](/docs/guides/organizations/verified-domains#automatic-suggestions) for the user. ## Example ```jsx {{ filename: 'src/routes/organizations.tsx' }} import { OrganizationList } from '@clerk/chrome-extension' export default function OrganizationListPage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after creating a new Organization. *** * `afterSelectOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting an Organization. Defaults to `undefined`. *** * `afterSelectPersonalUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting the [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts). Defaults to `undefined`. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. Defaults to `false`. *** * `skipInvitationScreen` * `boolean | undefined` A boolean that controls whether the screen for sending invitations after an Organization is created is hidden. When `undefined`, Clerk will automatically hide the screen if the number of max allowed members is equal to 1. Defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [org-ref]: /docs/reference/javascript/organization --- title: "`` component" description: Clerk's component is used to enable the ability to switch between available Organizations the user may be part of in your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-switcher lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/organization/organization-switcher.mdx --- ![The \ component allows a user to switch between their account types - their Personal Account and their joined Organizations.](/docs/images/ui-components/organization-switcher.png){{ style: { maxWidth: '436px' } }} The `` component allows a user to switch between their joined Organizations. If [Personal Accounts are enabled](/docs/guides/organizations/overview#allow-personal-accounts), users can also switch to their Personal Account. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple Organizations. It handles all Organization-related flows, including full Organization management for admins. Learn more about [Organizations](/docs/guides/organizations/overview). ## Example ```jsx {{ filename: 'src/routes/organization-switcher.tsx' }} import { OrganizationSwitcher } from '@clerk/chrome-extension' export default function OrganizationSwitcherPage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * `string` The full URL or path to navigate to after creating a new Organization. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after the user leaves the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `afterSelectOrganizationUrl` * `string` The full URL or path to navigate to after a successful Organization switch. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `createOrganizationMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the "Create organization" button will cause the \ component to open as a modal, or if the browser will navigate to the `createOrganizationUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `createOrganizationUrl` * `string` The full URL or path where the ``]createorg-ref component is mounted. *** * `defaultOpen` * `boolean` A boolean that controls the default state of the `` component. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. *** * `organizationProfileMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the **Manage organization** button will cause the \ component to open as a modal, or if the browser will navigate to the `organizationProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `organizationProfileProps` * `object` Specify options for the underlying \ component. For example: `{appearance: {...}}` *** * `organizationProfileUrl` * `string` The full URL or path where the \ component is mounted. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [createorg-ref]: /docs/reference/components/organization/create-organization [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured Organization management UI that allows users to manage their Organization profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/organization/organization-profile.mdx --- ![The \ component allows users to manage their Organization membership and security settings.](/docs/images/ui-components/organization-profile.png) The `` component allows users to manage their Organization membership, security, and billing settings. This component's **General** tab displays the Organization's information and the **Leave organization** button. Admins will be able to see the **Update profile** button, **Verified domains** section, and **Delete organization** button. The **Members** tab shows the Organization's members along with their join dates and Roles. Admins will have the ability to invite a member, change a member's Role, or remove them from the Organization. Admins will have tabs within the **Members** tab to view the Organization's [invitations](/docs/guides/organizations/overview#organization-invitations) and [requests](/docs/guides/organizations/verified-domains#membership-requests). The **Billing** tab displays the Plans and Features that are available to the Organization, as well as the user's billing information, such as their invoices and payment methods. ## Example ```jsx {{ filename: 'src/routes/organization-profile.tsx' }} import { OrganizationProfile } from '@clerk/chrome-extension' export default function OrganizationProfilePage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after leaving an Organization. *** * `customPages` * `CustomPages[]` An array of custom pages to add to the Organization profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/organization-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash- and virtual-based routing.
For example: `/organization-profile`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages.
Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React.
## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages](/docs/guides/customizing-clerk/adding-items/organization-profile) documentation. --- title: "``" description: The component is a button that links to the sign-up page or displays the sign-up modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-up-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/unstyled/sign-up-button.mdx --- The `` component is a button that, by default, links to your app's sign-up page. Your sign-up page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-up page. ## Usage ### Basic usage ```jsx {{ filename: 'src/routes/sign-up.tsx' }} import { SignUpButton } from '@clerk/chrome-extension' export default function SignUpPage() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```jsx {{ filename: 'src/routes/home.tsx' }} import { SignUpButton } from '@clerk/chrome-extension' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-up route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'` *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). --- title: "``" description: The component is a button that links to the sign-in page or displays the sign-in modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/unstyled/sign-in-button.mdx --- The `` component is a button that, by default, links to your app's sign-in page. Your sign-in page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-in page. ## Usage ### Basic usage ```jsx {{ filename: 'src/routes/sign-in.tsx' }} import { SignInButton } from '@clerk/chrome-extension' export default function SignInPage() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```jsx {{ filename: 'src/routes/home.tsx' }} import { SignInButton } from '@clerk/chrome-extension' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-in route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'`. *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. --- title: "``" description: The `` component is a button that signs a user out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-out-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/unstyled/sign-out-button.mdx --- The `` component is a button that signs a user out. By default, it is a ` ) } ``` ### Multi-session usage #### Sign out of all sessions Clicking the `` component signs the user out of all sessions. This is the default behavior. #### Sign out of a specific session You can sign out of a specific session by passing in a `sessionId` to the `sessionId` prop. This is useful for signing a single account out of a [multi-session application](/docs/guides/secure/session-options#multi-session-applications). In the following example, the `sessionId` is retrieved from the useAuth() hook. If the user is not signed in, the `sessionId` will be `null`, and the user is shown the \ component. If the user is signed in, the user is shown the `` component, which when clicked, signs the user out of that specific session. ```jsx {{ filename: 'src/routes/home.tsx' }} import { SignInButton, SignOutButton, useAuth } from '@clerk/chrome-extension' export default function Home() { const { sessionId } = useAuth() if (!sessionId) { return } return } ``` ## Properties * `redirectUrl?` * `string` The full URL or path to navigate after successful sign-out. *** * `sessionId?` * `string` The ID of a specific session to sign out of. Useful for [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. --- title: "`` component" description: Clerk's component is used to render the familiar user button UI popularized by Google. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/user/user-button.mdx --- ![The \ component renders the familiar user button UI popularized by Google.](/docs/images/ui-components/user-button.png){{ style: { maxWidth: '436px' } }} The `` component renders the familiar user button UI popularized by Google. When selected, it opens a dropdown menu with options to manage account settings and sign out. The "Manage account" option launches the \ component, providing access to profile and security settings. For users that have [multi-session](/docs/guides/secure/session-options#multi-session-applications) enabled, the `` also allows users to sign into multiple accounts at once and instantly switch between them without the need for a full page reload. Learn more [here](/docs/guides/secure/session-options#multi-session-applications). ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar and be able to open the popup menu. ```jsx {{ filename: 'src/layouts/root-layout.tsx' }} import { SignedIn, UserButton, SignInButton, SignedOut } from '@clerk/chrome-extension' export default function Header() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `afterMultiSessionSingleSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterMultiSessionSingleSignOutUrl` to \.** The full URL or path to navigate to after signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterSignOutUrl` to \.** The full URL or path to navigate to after a successful sign-out. *** * `afterSwitchSessionUrl` * `string` The full URL or path to navigate to after a successful account change in a multi-session app. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `defaultOpen` * `boolean` Controls whether the `` should open by default during the first render. *** * `showName` * `boolean` Controls if the user name is displayed next to the user image button. *** * `signInUrl` * `string` The full URL or path to navigate to when the **Add another account** button is clicked. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `userProfileMode` * `'modal' | 'navigation'` Controls whether selecting the **Manage your account** button will cause the \ component to open as a modal, or if the browser will navigate to the `userProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `userProfileProps` * `object` Specify options for the underlying \ component. For example: `{additionalOAuthScopes: {google: ['foo', 'bar'], github: ['qux']}}`. *** * `userProfileUrl` * `string` The full URL or path leading to the user management interface. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). You can also [add custom actions and links to the `` menu](/docs/guides/customizing-clerk/adding-items/user-button). --- title: "`` component" description: Clerk's component is used to render the familiar user avatar on its own. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-avatar lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/user/user-avatar.mdx --- ![The \ component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications.](/docs/images/ui-components/user-avatar.png) The `` component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications. ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar. ```jsx {{ filename: 'src/layouts/root-layout.tsx' }} import { SignedIn, UserAvatar, SignInButton, SignedOut } from '@clerk/chrome-extension' export default function Header() { return (
) } ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `rounded?` * `boolean` Determines whether the user avatar is displayed with rounded corners. *** * `appearance?` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` Optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/components/user/user-profile.mdx --- ![The \ component renders a full-featured account management UI that allows users to manage their profile and security settings.](/docs/images/ui-components/user-profile.png){{ style: { maxWidth: '100%' } }} The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile, security, and billing settings. ## Example ```jsx {{ filename: 'src/routes/user-profile.tsx' }} import { UserProfile } from '@clerk/chrome-extension' export default function UserProfilePage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/user-profile`. *** * `additionalOAuthScopes` * `object` Specify additional scopes per OAuth provider that your users would like to provide if not already approved. For example: `{google: ['foo', 'bar'], github: ['qux']}`. *** * `customPages` * CustomPage\[] An array of custom pages to add to the user profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/user-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages documentation](/docs/guides/customizing-clerk/adding-items/user-profile). --- title: useAuth() description: Access and manage authentication state in your application with Clerk's useAuth() hook. sdk: astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-auth.mdx --- The `useAuth()` hook provides access to the current user's authentication state and methods to manage the active session. > \[!NOTE] > To access auth data server-side, see the Auth object reference doc. ## Parameters | Parameter | Type | Description | | ---------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `initialAuthStateOrOptions?` | null \| Record\ \| \{ treatPendingAsSignedOut?: boolean; \} | An object containing the initial authentication state or options for the `useAuth()` hook. If not provided, the hook will attempt to derive the state from the context. `treatPendingAsSignedOut` is a boolean that indicates whether pending sessions are considered as signed out or not. Defaults to `true`. | ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `undefined` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has` | `undefined` | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `undefined` | The ID of the user's active organization. | | `orgRole` | `undefined` | The current user's role in their active organization. | | `orgSlug` | `undefined` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `undefined` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `undefined` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `undefined` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `null` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (params: CheckAuthorizationParamsWithCustomPermissions) => false | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `null` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `null` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `null` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `string` | The ID of the user's active organization. | | `orgRole` | `string` | The current user's role in their active organization. | | `orgSlug` | null \| string | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | ## Example The following example demonstrates how to use the `useAuth()` hook to access the current auth state, like whether the user is signed in or not. It also includes a basic example for using the `getToken()` method to retrieve a session token for fetching data from an external resource. ```tsx {{ filename: 'src/routes/page.tsx' }} import { useAuth } from '@clerk/chrome-extension' export default function ExternalDataPage() { const { userId, sessionId, getToken, isLoaded, isSignedIn } = useAuth() const fetchExternalData = async () => { const token = await getToken() // Fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

Hello, {userId}! Your current active session is {sessionId}.

) } ```
--- title: Hooks Reference description: A list of Clerk's comprehensive suite of hooks for managing authentication, sessions, sign-in and sign-up flows, Organizations, and reverification. sdk: astro, chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/overview.mdx --- Clerk offers a comprehensive suite of hooks that expose low-level access to authentication, session management, and multi-tenancy. With Clerk hooks, you can access and manage user data, handle sign-in and sign-up flows, control session management, and implement advanced flows like session reverification for sensitive actions. By using these hooks, you can extend or replace Clerk's built-in components and customize how authentication behaves in your application. ## Hooks * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: useOrganization() description: Access and manage the currently active Organization in your React application with Clerk's useOrganization() hook. search: rank: 1 sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-organization.mdx --- The `useOrganization()` hook retrieves attributes of the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganization()` accepts a single object with the following optional properties: | Property | Type | Description | | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`domains?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ enrollmentMode?: "manual\_invitation" \| "automatic\_invitation" \| "automatic\_suggestion"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `enrollmentMode`: A string that filters the domains by the provided [enrollment mode](/docs/guides/organizations/verified-domains#enrollment-mode).
  • Any of the properties described in Shared properties.
| |
`invitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: ("expired" \| "pending" \| "accepted" \| "revoked")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`membershipRequests?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the membership requests by the provided status.
  • Any of the properties described in Shared properties.
| |
`memberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ query?: string; role?: string\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `role`: An array of OrganizationCustomRoleKey.
  • `query`: A string that filters the memberships by the provided string.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes aren't populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `invitations`, `membershipRequests`, `memberships`, and `domains` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | > \[!NOTE] > These attributes are updating automatically and will re-render their respective components whenever you set a different Organization using the setActive(\{ organization }) method or update any of the memberships or invitations. No need for you to manage updating anything manually. ## Returns | Property | Type | Description | | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `domains` | null \| PaginatedResourcesWithDefault\<OrganizationDomainResource\> \| PaginatedResources\<OrganizationDomainResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's domains. | | `invitations` | null \| PaginatedResourcesWithDefault\<OrganizationInvitationResource\> \| PaginatedResources\<OrganizationInvitationResource, T\["invitations"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's invitations. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `membership` | undefined \| null \| OrganizationMembershipResource | The current organization membership. | | `membershipRequests` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipRequestResource\> \| PaginatedResources\<OrganizationMembershipRequestResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's membership requests. | | `memberships` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["memberships"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's memberships. | | `organization` | undefined \| null \| OrganizationResource | The currently active organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expand and paginate attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // invitations.data will never be populated. const { invitations } = useOrganization() // Use default values to fetch invitations, such as initialPage = 1 and pageSize = 10 const { invitations } = useOrganization({ invitations: true, }) // Pass your own values to fetch invitations const { invitations } = useOrganization({ invitations: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { invitations } = useOrganization({ invitations: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```jsx {{ filename: 'src/routes/members.tsx' }} import { useOrganization } from '@clerk/chrome-extension' export default function MemberListPage() { const { memberships } = useOrganization({ memberships: { infinite: true, // Append new data to the existing list keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of memberships. Notice the difference between this example's pagination and the infinite pagination example above. ```jsx {{ filename: 'src/routes/members-paginated.tsx' }} import { useOrganization } from '@clerk/chrome-extension' export default function MemberListPage() { const { memberships } = useOrganization({ memberships: { keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
## Related guides * [Update an Organization](/docs/guides/development/custom-flows/organizations/update-organizations) * Use Clerk's API to build a custom flow for updating an Organization *** * [Manage Roles in an Organization](/docs/guides/development/custom-flows/organizations/manage-roles) * Use Clerk's API to build a custom flow for managing Roles in an Organization *** * [Manage an Organization's membership requests](/docs/guides/development/custom-flows/organizations/manage-membership-requests) * Use Clerk's API to build a custom flow for managing an Organization's membership requests *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: "`useOrganizationList()`" description: Access and manage the current user's Organization list in your React application with Clerk's useOrganizationList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-organization-list.mdx --- The `useOrganizationList()` hook provides access to the current user's Organization memberships, invitations, and suggestions. It also includes methods for creating new Organizations and managing the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganizationList()` accepts a single object with the following properties: | Property | Type | Description | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`userInvitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`userMemberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & object & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • Any of the properties described in Shared properties.
| |
`userSuggestions?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "pending" \| "accepted" \| ("pending" \| "accepted")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the suggestions by the provided status.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `userMemberships`, `userInvitations`, and `userSuggestions` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | ## Returns | Property | Type | Description | | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createOrganization` | undefined \| (CreateOrganizationParams: CreateOrganizationParams) => Promise\<OrganizationResource\> | A function that returns a `Promise` which resolves to the newly created `Organization`. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization and there is an authenticated user. Initially `false`, becomes `true` once Clerk loads with a user. | | `setActive` | undefined \| (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. | | `userInvitations` | PaginatedResourcesWithDefault\<UserOrganizationInvitationResource\> \| PaginatedResources\<UserOrganizationInvitationResource, T\["userInvitations"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization invitations. | | `userMemberships` | PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["userMemberships"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization memberships. | | `userSuggestions` | PaginatedResourcesWithDefault\<OrganizationSuggestionResource\> \| PaginatedResources\<OrganizationSuggestionResource, T\["userSuggestions"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of suggestions for organizations that the user can join. | ### `CreateOrganizationParams` | Property | Type | Description | | ------------------------- | -------- | ----------------------------- | | `name` | `string` | The name of the organization. | | `slug?` | `string` | The slug of the organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expanding and paginating attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. So by default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // userMemberships.data will never be populated const { userMemberships } = useOrganizationList() // Use default values to fetch userMemberships, such as initialPage = 1 and pageSize = 10 const { userMemberships } = useOrganizationList({ userMemberships: true, }) // Pass your own values to fetch userMemberships const { userMemberships } = useOrganizationList({ userMemberships: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `userMemberships` attribute will be populated with the first page of the user's Organization memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```jsx {{ filename: 'components/JoinedOrganizations.tsx' }} import { useOrganizationList } from '@clerk/chrome-extension' export function JoinedOrganizations() { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) // Handle loading state if (!isLoaded) return
Loading...
return ( <>
    {userMemberships.data?.map((mem) => (
  • {mem.organization.name}
  • ))}
) } ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `userInvitations` attribute will be populated with the first page of invitations. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of invitations. Notice the difference between this example's pagination and the infinite pagination example above. ```jsx {{ filename: 'components/UserInvitationsTable.tsx' }} import { useOrganizationList } from '@clerk/chrome-extension' export function UserInvitationsTable() { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { infinite: true, keepPreviousData: true, }, }) // Handle loading state if (!isLoaded || userInvitations.isLoading) return
Loading...
return ( <> {userInvitations.data?.map((inv) => ( ))}
Email Org name
{inv.emailAddress} {inv.publicOrganizationData.name}
) } ```
## Related guides * [Build a custom Organization switcher](/docs/guides/development/custom-flows/organizations/organization-switcher) * Use Clerk's API to build a custom flow for switching between Organizations *** * [Create Organizations](/docs/guides/development/custom-flows/organizations/create-organizations) * Use Clerk's API to build a custom flow for creating Organizations *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: useClerk() description: Access and manage the Clerk object in your React application with Clerk's useClerk() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-clerk lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-clerk.mdx --- > \[!WARNING] > This hook should only be used for advanced use cases, such as building a completely custom OAuth flow or as an escape hatch to access to the `Clerk` object. The `useClerk()` hook provides access to the Clerk object, allowing you to build alternatives to any Clerk Component. ## Returns Clerk — The `useClerk()` hook returns the `Clerk` object, which includes all the methods and properties listed in the Clerk reference. ## Example The following example uses the `useClerk()` hook to access the `clerk` object. The `clerk` object is used to call the openSignIn() method to open the sign-in modal. ```tsx {{ filename: 'src/routes/page.tsx' }} import { useClerk } from '@clerk/chrome-extension' export default function Home() { const clerk = useClerk() return } ``` --- title: useReverification() description: Clerk's useReverification() hook enhances a fetcher function to handle a session's reverification flow. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-reverification lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-reverification.mdx --- > \[!WARNING] > > Depending on the SDK you're using, this feature requires `@clerk/nextjs@6.12.7` or later, `@clerk/clerk-react@5.25.1` or later, `@clerk/clerk-js@5.57.1` or later and `@clerk/clerk-sdk-ruby@3.3.0` or later. Reverification allows you to prompt a user to verify their credentials before performing sensitive actions, even if they're already authenticated. For example, in a banking application, transferring money is considered a "sensitive action." Reverification can be used to confirm the user's identity. The `useReverification()` hook is used to handle a session's reverification flow. If a request requires reverification, a modal will display, prompting the user to verify their credentials. Upon successful verification, the original request will automatically retry. If you'd like to build a custom UI, you can use the onNeedsReverification option. When using reverification, a user's credentials are valid for 10 minutes. Once stale, a user will need to reverify their credentials. This time duration can be customized by using the `has()` helper on the server-side. See the [guide on reverification](/docs/guides/secure/reverification) for more information. ## Parameters | Parameter | Type | Description | | ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `fetcher` | `Fetcher extends (...args: any[]) => Promise` | A function that returns a promise. | | `options?` | `Options` | Optional configuration object extending UseReverificationOptions. | ### `UseReverificationOptions` The optional options object. | Property | Type | Description | | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | |
`onNeedsReverification?` | (properties: NeedsReverificationParameters) => void | Handler for the reverification process. Opts out of using the default UI. Use this to build a custom UI. | ### `NeedsReverificationParameters` | Property | Type | Description | | -------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `cancel` | () => void | Marks the reverification process as cancelled and rejects the original request. | | `complete` | () => void | Marks the reverification process as complete and retries the original request. | | `level` | undefined \| "first\_factor" \| "second\_factor" \| "multi\_factor" | The verification level required for the reverification process. | ## Examples The `useReverification()` hook displays a prebuilt UI when the user needs to reverify their credentials. You can also build a custom UI to handle the reverification process yourself. Use the following tabs to see examples of either option. ### Handle reverification for an action The following example demonstrates how to use the `useReverification()` hook to require a user to reverify their credentials before being able to update their primary email address. It also demonstrates how to handle the cancellation of the reverification process. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/chrome-extension' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification((emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {email.id !== user?.primaryEmailAddress?.id && ( )}
  • ))}
) } ```
### Handle reverification for a fetcher function The following example demonstrates how to use the `useReverification()` hook to enhance a fetcher function that fetches data from a route that requires reverification. For examples on how to set up a route that requires reverification, see the [guide on reverification](/docs/guides/secure/reverification). ```tsx {{ filename: 'components/AccountBalance.tsx' }} import { useAuth, useReverification } from '@clerk/chrome-extension' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' export function AccountBalance() { const { getToken } = useAuth() const [balance, setBalance] = useState(null) const accountBalance = useReverification(async () => { const response = await fetch('/api/balance', { headers: { Authorization: `Bearer ${await getToken()}`, }, }) return await response.json() }) const handleClick = async () => { try { const accountBalanceResponse = await accountBalance() setBalance(accountBalanceResponse.amount) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error('Error fetching account balance', e) } } return (
Your account balance is {balance ? `$${balance}` : '$******'}
) } ```
The following example demonstrates how to build a custom UI when using the `useReverification()` hook. In the example, the `useReverification()` hook is used to require a user to reverify their credentials before being able to update their primary email address. It requires two components: the `` component displays the list of email addresses to choose from and it renders the second component, ``, which handles the reverification process. The example handles first factor verification using an email code, so you will need to have the [**Email verification code**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) setting enabled for your application. But you can adapt this example to handle any type of verification level or strategy. The `` component uses `useReverification()` to enhance the `update()` method, requiring the user to reverify their credentials before being able to update their primary email address. The `useReverification()` hook provides the `onNeedsReverification` option, which is a handler for building a custom UI. It provides four properties: `level`, `complete`, `cancel`, and `inProgress`. The example tracks these using the `verificationState` state variable. * The `level` property determines the verification level required for the reverification process. This example only handles first factor verification, which is done in the `` component. * The `complete` and `cancel` properties are the steps of the reverification process, which is also done in the `` component. * The `inProgress` property is used to track the state of the reverification process. When the user selects the "Make primary" button, it triggers the reverification process and sets the `inProgress` property is `true`, which displays the `` component. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/chrome-extension' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/shared' import { useState } from 'react' import type { SessionVerificationLevel } from '@clerk/types' import { VerificationComponent } from './VerificationComponent' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // TODO: Update to use exported type once available const [verificationState, setVerificationState] = useState< | { complete: () => void cancel: () => void level: SessionVerificationLevel | undefined inProgress: boolean } | undefined >(undefined) // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification( (emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), { onNeedsReverification: ({ complete, cancel, level }) => { setVerificationState({ complete, cancel, level, inProgress: true, }) }, }, ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {user?.primaryEmailAddressId !== email.id && ( )}
  • ))}
{verificationState?.inProgress && ( { verificationState.complete() setVerificationState(undefined) }} onCancel={() => { verificationState.cancel() setVerificationState(undefined) }} /> )}
) } ```
The `` component handles the reverification process. It uses the `level` property to determine the verification level, which is set to `first_factor`. First, it finds the determined starting first factor from the supported first factors. Then, it prepares the first factor verification using the `strategy` (`email_code` in this case) and `emailAddressId` properties. Finally, it attempts to verify the session with email code provided by the user. If the verification is successful, the `onComplete()` handler is called to complete the reverification process. ```tsx {{ filename: 'components/VerificationComponent.tsx', collapsible: true }} import { useEffect, useRef, useState } from 'react' import { useSession } from '@clerk/chrome-extension' import type { EmailCodeFactor, SessionVerificationLevel, SessionVerificationResource, } from '@clerk/types' export function VerificationComponent({ level = 'first_factor', onComplete, onCancel, }: { level: SessionVerificationLevel | undefined onComplete: () => void onCancel: () => void }) { const { session } = useSession() const [code, setCode] = useState('') const reverificationRef = useRef(undefined) const [determinedStartingFirstFactor, setDeterminedStartingFirstFactor] = useState< EmailCodeFactor | undefined >() useEffect(() => { if (reverificationRef.current) { return } session?.startVerification({ level }).then(async (response) => { reverificationRef.current = response await prepareEmailVerification(response) }) }, []) const prepareEmailVerification = async (verificationResource: SessionVerificationResource) => { // To simplify the example we will only handle the first factor verification if (verificationResource.status === 'needs_first_factor') { // Determine the starting first factor from the supported first factors const determinedStartingFirstFactor = verificationResource.supportedFirstFactors?.filter( (factor) => factor.strategy === 'email_code', )[0] if (determinedStartingFirstFactor) { setDeterminedStartingFirstFactor(determinedStartingFirstFactor) // Prepare the first factor verification with the determined starting first factor await session?.prepareFirstFactorVerification({ strategy: determinedStartingFirstFactor.strategy, emailAddressId: determinedStartingFirstFactor?.emailAddressId, }) } } } const handleVerificationAttempt = async () => { try { // Attempt to verify the session with the provided code await session?.attemptFirstFactorVerification({ strategy: 'email_code', code, }) onComplete() } catch (e) { // Any error from the attempt to verify the session can be handled here console.error('Error verifying session', e) } } if (!determinedStartingFirstFactor) { return null } return (

Enter verification code sent to {determinedStartingFirstFactor.safeIdentifier || ''}

setCode(e.target.value)} />
) } ```
## Related guides See the custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). guides for examples of how to use the `useReverification()` hook, such as the [Add a phone number to a user's account](/docs/guides/development/custom-flows/account-updates/add-phone) guide. --- title: useSignIn() description: Access and manage the current user's sign-in state in your React application with Clerk's useSignIn() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-sign-in.mdx --- The `useSignIn()` hook provides access to the SignIn object, which allows you to check the current state of a sign-in attempt and manage the sign-in flow. You can use this to create a [custom sign-in flow](/docs/guides/development/custom-flows/overview#sign-in-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signIn` | `undefined` | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signIn` | SignInResource | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | ## Examples ### Check the current state of a sign-in The following example uses the `useSignIn()` hook to access the SignIn object, which contains the current sign-in attempt status and methods to create a new sign-in attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'src/routes/page.tsx' }} import { useSignIn } from '@clerk/chrome-extension' export default function SignInPage() { const { isLoaded, signIn } = useSignIn() if (!isLoaded) { // Handle loading state return null } return
The current sign-in attempt status is {signIn?.status}.
} ```
### Create a custom sign-in flow with `useSignIn()` The `useSignIn()` hook can also be used to build fully custom sign-in flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-in flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignIn()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useSession() description: Access and manage the current user's session in your React application with Clerk's useSession() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-session.mdx --- The `useSession()` hook provides access to the current user's Session object, as well as helpers for setting the active session. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `session` | `undefined` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `session` | `null` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `boolean` | A boolean that indicates whether a user is currently signed in. | | `session` | SignedInSessionResource | The current session for the user. | ## Example ### Access the `Session` object The following example uses the `useSession()` hook to access the `Session` object, which has the `lastActiveAt` property. The `lastActiveAt` property is a `Date` object used to show the time the session was last active. ```tsx {{ filename: 'src/routes/page.tsx' }} import { useSession } from '@clerk/chrome-extension' export default function HomePage() { const { isLoaded, session, isSignedIn } = useSession() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

This session has been active since {session.lastActiveAt.toLocaleString()}

) } ```
--- title: useSignUp() description: Access and manage the current user's sign-up state in your React application with Clerk's useSignUp() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-sign-up.mdx --- The `useSignUp()` hook provides access to the SignUp object, which allows you to check the current state of a sign-up attempt and manage the sign-up flow. You can use this to create a [custom sign-up flow](/docs/guides/development/custom-flows/overview#sign-up-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signUp` | `undefined` | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signUp` | SignUpResource | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | ## Examples ### Check the current state of a sign-up The following example uses the `useSignUp()` hook to access the SignUp object, which contains the current sign-up attempt status and methods to create a new sign-up attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'src/routes/page.tsx' }} import { useSignUp } from '@clerk/chrome-extension' export default function SignUpPage() { const { isLoaded, signUp } = useSignUp() // Handle loading state if (!isLoaded) return
Loading...
return
The current sign-up attempt status is {signUp?.status}.
} ```
### Create a custom sign-up flow with `useSignUp()` The `useSignUp()` hook can also be used to build fully custom sign-up flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-up flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignUp()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useSessionList() description: Access and manage the current user's session list in your React application with Clerk's useSessionList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-session-list.mdx --- The `useSessionList()` hook returns an array of Session objects that have been registered on the client device. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | `undefined` | A list of sessions that have been registered on the client device. | | `setActive` | `undefined` | A function that sets the active session and/or organization. See the reference doc. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | SessionResource\[] | A list of sessions that have been registered on the client device. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. See the reference doc. | ## Example ### Get a list of sessions The following example uses `useSessionList()` to get a list of sessions that have been registered on the client device. The `sessions` property is used to show the number of times the user has visited the page. ```tsx {{ filename: 'src/routes/page.tsx' }} import { useSessionList } from '@clerk/chrome-extension' export default function Home() { const { isLoaded, sessions } = useSessionList() // Handle loading state if (!isLoaded) return
Loading...
return (

Welcome back. You've been here {sessions.length} times before.

) } ```
--- title: useUser() description: Access and manage the current user's data in your React application with Clerk's useUser() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/hooks/use-user.mdx --- The `useUser()` hook provides access to the current user's User object, which contains all the data for a single user in your application and provides methods to manage their account. This hook also allows you to check if the user is signed in and if Clerk has loaded and initialized. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that returns `true` if the user is signed in. | | `user` | `undefined` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that returns `true` if the user is signed in. | | `user` | `null` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that returns `true` if the user is signed in. | | `user` | UserResource | The `User` object for the current user. | ## Examples ### Get the current user The following example uses the `useUser()` hook to access the User object, which contains the current user's data such as their full name. The `isLoaded` and `isSignedIn` properties are used to handle the loading state and to check if the user is signed in, respectively. ```tsx {{ filename: 'src/routes/page.tsx' }} import { useUser } from '@clerk/chrome-extension' export default function Example() { const { isSignedIn, user, isLoaded } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return
Hello {user.firstName}!
} ```
### Update user data The following example uses the `useUser()` hook to access the User object, which calls the update() method to update the current user's information. ```tsx {{ filename: 'src/routes/page.tsx' }} import { useUser } from '@clerk/chrome-extension' export default function Home() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { await user.update({ firstName: 'John', lastName: 'Doe', }) } return ( <>

user.firstName: {user.firstName}

user.lastName: {user.lastName}

) } ```
### Reload user data The following example uses the `useUser()` hook to access the User object, which calls the reload() method to get the latest user's information. ```tsx {{ filename: 'src/routes/page.tsx' }} import { useUser } from '@clerk/chrome-extension' export default function Home() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { // Update data via an API endpoint const updateMetadata = await fetch('/api/updateMetadata', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role: 'admin', }), }) // Check if the update was successful if ((await updateMetadata.json()).message !== 'success') { throw new Error('Error updating') } // If the update was successful, reload the user data await user.reload() } return ( <>

user role: {user.publicMetadata.role}

) } ```
--- title: JavaScript Quickstart description: Add authentication and user management to your JavaScript app with Clerk. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: js-frontend sourceFile: /docs/getting-started/quickstart.js-frontend.mdx --- To add the [JavaScript SDK](/docs/reference/javascript/overview) to your JavaScript app, you have two options: 1. Install the package using a package manager, like `npm`. 2. Use the ` ``` ## Create your first user Run your project with the following command: ```npm npm run dev ``` Now visit your app's homepage at [`http://localhost:5173`](http://localhost:5173). Sign up to create your first user. { /* ``` ## Listen for the `load` event Below the ` tag that initializes the SDK, create another ` ``` ## Allow users to sign in or out Clerk's prebuilt components are the easiest way to add authentication and user management to your app. They come styled out-of-the-box and are customizable to fit your app's design. To get started, you will use: * \: renders a user interface for signing in. * \: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. ```html {{ filename: 'index.html' }}
``` ## More resources * [Clerk class reference](/docs/reference/javascript/clerk) * Learn more about the `Clerk` class and how to use it. *** * [Prebuilt components](/docs/reference/components/overview) * Learn more about Clerk's suite of components that let you quickly add authentication to your app. *** * [Customization & localization](/docs/guides/customizing-clerk/appearance-prop/overview) * Learn how to customize and localize Clerk components. *** * [JavaScript SDK Reference](/docs/reference/javascript/overview) * Learn more about additional JavaScript methods. --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: js-frontend sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const pricingTableDiv = document.getElementById('pricing-table') clerk.mountPricingTable(pricingTableDiv, { for: 'organization' }) ```
## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const bronzeContentDiv = document.getElementById('bronze-content') const hasBronzePlan = clerk.session.checkAuthorization({ plan: 'bronze' }) if (!hasBronzePlan) { bronzeContentDiv.innerHTML = `

Only subscribers to the Bronze plan can access this content.

` } else { bronzeContentDiv.innerHTML = `

For Bronze subscribers only

` } ```
The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const pageContentDiv = document.getElementById('page-content') const hasPremiumAccess = clerk.session.checkAuthorization({ feature: 'premium_access' }) if (!hasPremiumAccess) { pageContentDiv.innerHTML = `

Only subscribers with the Premium Access feature can access this content.

` } else { pageContentDiv.innerHTML = `

Our Exclusive Content

` } ```
The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const managePremiumContentDiv = document.getElementById('manage-premium-content') const hasPremiumAccessManage = clerk.session.checkAuthorization({ permission: 'org:premium_access:manage', }) if (!hasPremiumAccessManage) { managePremiumContentDiv.innerHTML = `

Only subscribers with the Premium Access Manage permission can access this content.

` } else { managePremiumContentDiv.innerHTML = `

Our Exclusive Content

` } ```
### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. > \[!WARNING] > JS Frontend SDK doesn't support the `Protect` component. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. > \[!WARNING] > JS Frontend SDK doesn't support the `Protect` component. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. > \[!WARNING] > JS Frontend SDK doesn't support the `Protect` component. --- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: js-frontend sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const pricingTableDiv = document.getElementById('pricing-table') clerk.mountPricingTable(pricingTableDiv) ```
## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const bronzeContentDiv = document.getElementById('bronze-content') const hasBronzePlan = clerk.session.checkAuthorization({ plan: 'bronze' }) if (!hasBronzePlan) { bronzeContentDiv.innerHTML = `

Only subscribers to the Bronze plan can access this content.

` } else { bronzeContentDiv.innerHTML = `

For Bronze subscribers only

` } ```
The following example demonstrates how to use `has()` to check if a user has a Feature. ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const pageContentDiv = document.getElementById('page-content') const hasPremiumAccess = clerk.session.checkAuthorization({ feature: 'premium_access' }) if (!hasPremiumAccess) { pageContentDiv.innerHTML = `

Only subscribers with the Premium Access feature can access this content.

` } else { pageContentDiv.innerHTML = `

Our Exclusive Content

` } ```
### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. > \[!WARNING] > JS Frontend SDK doesn't support the `Protect` component. The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. > \[!WARNING] > JS Frontend SDK doesn't support the `Protect` component. --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: js-frontend sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: js-frontend sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the [`Clerk` object](/docs/reference/javascript/clerk). A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`` component" description: Clerk's component renders a UI for resolving the `choose-organization` task. sdk: js-frontend, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/task-choose-organization lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/authentication/task-choose-organization.mdx --- ![The \ component renders a UI for resolving the choose-organization session task.](/docs/images/ui-components/task-choose-organization.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for resolving the `choose-organization` session task. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/overview). You can further customize your `` component by passing additional properties at the time of rendering. > \[!IMPORTANT] > The `` component cannot render when a user doesn't have current session tasks. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountTaskChooseOrganization() * unmountTaskChooseOrganization() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ### `mountTaskChooseOrganization()` Render the `` component to an HTML `
` element. ```typescript function mountTaskChooseOrganization( node: HTMLDivElement, props?: TaskChooseOrganizationProps, ): void ``` #### `mountTaskChooseOrganization()` params * `node ` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * TaskChooseOrganizationProps The properties to pass to the `` component. #### `mountTaskChooseOrganization()` usage ```typescript {{ filename: 'main.ts', mark: [26] }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Mount user button component document.getElementById('signed-in').innerHTML = `
` const userbuttonDiv = document.getElementById('user-button') clerk.mountUserButton(userbuttonDiv) } else if (clerk.session?.currentTask) { switch (clerk.session.currentTask.key) { case 'choose-organization': { document.getElementById('app').innerHTML = `
` const taskChooseOrganizationDiv = document.getElementById('task-choose-organization') clerk.mountTaskChooseOrganization(taskChooseOrganizationDiv) } } } ``` ### `unmountTaskChooseOrganization()` Unmount and run cleanup on an existing `` component instance. ```typescript function unmountTaskChooseOrganization(node: HTMLDivElement): void ``` #### `unmountTaskChooseOrganization()` params * `node ` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance #### `unmountTaskChooseOrganization()` usage ```typescript {{ filename: 'main.ts', mark: [30] }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Mount user button component document.getElementById('signed-in').innerHTML = `
` const userbuttonDiv = document.getElementById('user-button') clerk.mountUserButton(userbuttonDiv) } else if (clerk.session?.currentTask) { switch (clerk.session.currentTask.key) { case 'choose-organization': { document.getElementById('app').innerHTML = `
` const taskChooseOrganizationDiv = document.getElementById('task-choose-organization') clerk.mountTaskChooseOrganization(taskChooseOrganizationDiv) // ... clerk.unmountTaskChooseOrganization(taskChooseOrganizationDiv) } } } ``` ## Properties All props are optional. * `redirectUrlComplete` * `string` The full URL or path to navigate to after successfully completing all tasks. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for signing in users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/authentication/sign-in.mdx --- ![The \ component renders a UI for signing in users.](/docs/images/ui-components/sign-in.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI to allow users to sign in or sign up by default. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountSignIn() * unmountSignIn() * openSignIn() * closeSignIn() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ### `mountSignIn()` Render the `` component to an HTML `
` element. ```typescript function mountSignIn(node: HTMLDivElement, props?: SignInProps): void ``` #### `mountSignIn()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element used to render in the `` component *** * `props?` * SignInProps The properties to pass to the `` component #### `mountSignIn()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) ``` ### `unmountSignIn()` Unmount and run cleanup on an existing `` component instance. ```typescript function unmountSignIn(node: HTMLDivElement): void ``` #### `unmountSignIn()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance #### `unmountSignIn()` usage ```js {{ filename: 'index.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) // ... clerk.unmountSignIn(signInDiv) ``` ### `openSignIn()` Opens the `` component as an overlay at the root of your HTML `body` element. ```typescript function openSignIn(props?: SignInProps): void ``` #### `openSignIn()` params * `props?` * SignInProps The properties to pass to the `` component. #### `openSignIn()` usage ```js {{ filename: 'main.js', mark: [9] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() clerk.openSignIn() ``` ### `closeSignIn()` Closes the sign in overlay. ```typescript function closeSignIn(): void ``` #### `closeSignIn()` usage ```js {{ filename: 'index.js', mark: [13] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() clerk.openSignIn() // ... clerk.closeSignIn() ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `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. *** * `initialValues` * [`SignInInitialValues`](/docs/reference/javascript/types/sign-in-initial-values) The values used to prefill the sign-in fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-in`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signUpFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Used for the 'Don't have an account? Sign up' link that's rendered. Defaults to `/`. 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 used as the redirect destination after the user signs up. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signUpUrl` * `string` The full URL or path to the sign-up page. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `transferable` * `boolean` Indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `waitlistUrl` * `string` Full URL or path to the waitlist page. Use this property to provide the target of the 'Waitlist' link that's rendered. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). If you've passed the `waitlistUrl` prop to the \ component, it will infer from that, and you can omit this prop. *** * `withSignUp` * `boolean` Opt into sign-in-or-up flow by setting this prop to `true`. When `true`, if a user does not exist, they will be prompted to sign up. If a user exists, they will be prompted to sign in. Defaults to `true` if the `CLERK_SIGN_IN_URL` environment variable is set. Otherwise, defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for signing up users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/authentication/sign-up.mdx --- ![The \ component renders a UI for signing up users.](/docs/images/ui-components/sign-up.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountSignUp() * unmountSignUp() * openSignUp() * closeSignUp() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ### `mountSignUp()` Render the `` component to an HTML `
` element. ```typescript function mountSignUp(node: HTMLDivElement, props?: SignUpProps): void ``` #### `mountSignUp()` params * `node ` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * SignUpProps The properties to pass to the `` component. #### `mountSignUp()` usage ```typescript {{ filename: 'main.ts', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const signUpDiv = document.getElementById('sign-up') clerk.mountSignUp(signUpDiv) ``` ### `unmountSignUp()` Unmount and run cleanup on an existing `` component instance. ```typescript function unmountSignUp(node: HTMLDivElement): void ``` #### `unmountSignUp()` params * `node ` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance #### `unmountSignUp()` usage ```typescript {{ filename: 'main.ts', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const signUpDiv = document.getElementById('sign-up') clerk.mountSignUp(signUpDiv) // ... clerk.unmountSignUp(signUpDiv) ``` ### `openSignUp()` Opens the `` component as an overlay at the root of your HTML `body` element. ```typescript function openSignUp(props?: SignUpProps): void ``` #### `openSignUp()` params * `props?` * SignUpProps The properties to pass to the `` component #### `openSignUp()` usage ```js {{ filename: 'main.js', mark: [9] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() clerk.openSignUp() ``` ### `closeSignUp()` Closes the sign up overlay. ```typescript function closeSignUp(): void ``` #### `closeSignUp()` usage ```js {{ filename: 'main.js', mark: [13] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() clerk.openSignUp() // ... clerk.closeSignUp() ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `string` If provided, this URL will always be used as the redirect destination 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. *** * `initialValues` * [`SignUpInitialValues`](/docs/reference/javascript/types/sign-up-initial-values) The values used to prefill the sign-up fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-up`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signInFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Used for the 'Already have an account? Sign in' link that's rendered. 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. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signInUrl` * `string` The full URL or path to the sign-in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `unsafeMetadata` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for authenticating users with Google's One Tap API. sdk: astro, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/google-one-tap lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: chrome-extension,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/authentication/google-one-tap.mdx --- > \[!IMPORTANT] > To use Google One Tap with Clerk, you must [enable Google as a social connection in the Clerk Dashboard](/docs/guides/configure/auth-strategies/social-connections/google#configure-for-your-production-instance) and make sure to use custom credentials. The `` component renders the [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) UI so that users can use a single button to sign-up or sign-in to your Clerk application with their Google accounts. By default, this component will redirect users back to the page where the authentication flow started. However, you can override this with force redirect URL props or [force redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). > \[!TIP] > `` does not render if the user is already signed into your Clerk application, so there's no need to manually check if a user is signed in yourself before rendering it. ## Usage with JavaScript The methods in this section are available on instances of the [`Clerk`](/docs/reference/javascript/clerk) class and are used to render and control the `` component. ### `openGoogleOneTap()` Opens the `` component. ```typescript function openGoogleOneTap(params: GoogleOneTapProps): void ``` * See GoogleOneTapProps #### `openGoogleOneTap()` usage ```js {{ filename: 'main.js', mark: [[9, 14]] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() const params = { cancelOnTapOutside: false, itpSupport: false, fedCmSupport: false, } clerk.openGoogleOneTap(params) ``` ### `closeGoogleOneTap()` Closes the `` component. ```typescript function closeGoogleOneTap(): void ``` #### `closeGoogleOneTap()` usage ```js {{ filename: 'main.js', mark: [18] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() const params = { cancelOnTapOutside: false, itpSupport: false, fedCmSupport: false, } clerk.openGoogleOneTap(params) // Do something else clerk.closeGoogleOneTap() ``` ### `authenticateWithGoogleOneTap()` Authenticates the user with a token generated from Google identity services. Also sets the user's current session to active. ```typescript function authenticateWithGoogleOneTap( props?: AuthenticateWithGoogleOneTapParams, ): Promise ``` #### `AuthenticateWithGoogleOneTapParams` * `token?` * `string` A Google authentication token from Google identity services. #### `authenticateWithGoogleOneTap()` usage ```js {{ filename: 'main.js', mark: [[9, 17]] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() // Optionally, you can set redirect URLs. const customUrls = { signInUrl: '/sign-in', signUpUrl: '/sign-up', } // Initiate the authentication flow. const signInOrUp = await clerk.authenticateWithGoogleOneTap({ token: 'xxxx' }) // Set the session as active, and handle any navigation or redirects await clerk.handleGoogleOneTapCallback(signInOrUp, customUrls) ``` ### `handleGoogleOneTapCallback()` Completes a Google One Tap redirection flow started by authenticateWithGoogleOneTap(). Also calls [`Clerk.setActive()`](/docs/reference/javascript/clerk#set-active) and performs a custom navigation if given a custom navigation function. ```typescript function handleGoogleOneTapCallback( signInOrUp: SignInResource | SignUpResource, params: HandleOAuthCallbackParams, customNavigate?: (to: string) => Promise, ): Promise ``` See authenticateWithGoogleOneTap() usage for an example of how to use `handleGoogleOneTapCallback()`. #### `handleGoogleOneTapCallback()` params * `signInOrUp` * [SignInResource](/docs/reference/javascript/sign-in) | [SignUpResource](/docs/reference/javascript/sign-up) The `SignIn` or `SignUp` object returned from `authenticateWithGoogleOneTap()`. *** * `params` * [`HandleOAuthCallbackParams`](/docs/reference/javascript/clerk#handle-o-auth-callback-params) An object containing redirect URLs. Useful if you want to set URLs specific to Google One Tap. Otherwise, consider using [environment variables](/docs/guides/development/clerk-environment-variables) to set redirect URLs. *** * `customNavigate?` * `(to: string) => Promise` A function that overrides Clerk's default navigation behavior, allowing custom handling of navigation during sign-up and sign-in flows. ## Properties * `cancelOnTapOutside?` * `boolean` If `true`, the One Tap prompt closes automatically if the user clicks outside of the prompt. Defaults to `true`. *** * `itpSupport?` * `boolean` If `true`, enables the [ITP-specific UX](https://developers.google.com/identity/gsi/web/guides/itp) when One Tap is rendered on ITP browsers such as Chrome on iOS, Safari, and FireFox. Defaults to `true`. *** * `fedCmSupport?` * `boolean` If `true`, enables Google One Tap to use [the FedCM API](https://developers.google.com/privacy-sandbox/3pcd/fedcm) to sign users in. See Google's docs on [best practices when disabling FedCM support](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap#do_not_cover_google_one_tap). Defaults to `true` *** * `signInForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs in, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). *** * `signUpForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs up, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). ## Limitations * If your application will use the Google API on behalf of your users, the `` component is not recommended, as Google does not provide Clerk with an access or refresh token that you can use. * Users with the 1Password browser extension may not be able to render the Google One Tap UI. They must disable this extension. * When testing in development, if you select the `X` button to close the Google One Tap UI, you may encounter [a cooldown](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown) that prevents you from rendering it again for a period of time. To bypass the cooldown, remove the `g_state` cookie. --- title: "`` component" description: The component renders a waitlist form that allows users to join for early access to your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/waitlist lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/authentication/waitlist.mdx --- ![The \ component renders a form that allows users to join for early access to your app.](/docs/images/ui-components/waitlist.png){{ style: { maxWidth: '460px' } }} In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. [Learn more about additional features available in **Waitlist** mode](/docs/guides/secure/restricting-access#waitlist). The `` component renders a form that allows users to join for early access to your app. ## Enable Waitlist mode Before using the `` component, you must enable **Waitlist** mode in the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountWaitlist() * unmountWaitlist() * openWaitlist() * closeWaitlist() The following examples assume that you followed the [quickstart](/docs/js-frontend/getting-started/quickstart) to add Clerk to your JavaScript app. ### mountWaitlist() Render the `` component to an HTML `
` element. ```typescript function mountWaitlist(node: HTMLDivElement, props?: WaitlistProps): void ``` ### mountWaitlist() params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * WaitlistProps The properties to pass to the `` component #### `mountWaitlist()` usage ```js {{ filename: 'main.js', mark: [13] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerk = new Clerk('{{pub_key}}') await clerk.load() document.getElementById('app').innerHTML = `
` const waitlistDiv = document.getElementById('waitlist') clerk.mountWaitlist(waitlistDiv) ``` ### unmountWaitlist() Unmount and run cleanup on an existing `` component instance. ```typescript function unmountWaitlist(node: HTMLDivElement): void ``` #### `unmountWaitlist()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance #### `unmountWaitlist()` usage ```js {{ filename: 'main.js', mark: [17] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerk = new Clerk('{{pub_key}}') await clerk.load() document.getElementById('app').innerHTML = `
` const waitlistDiv = document.getElementById('waitlist') clerk.mountWaitlist(waitlistDiv) // ... clerk.unmountWaitlist(waitlistDiv) ``` ### `openWaitlist()` Opens the `` component as an overlay at the root of your HTML `body` element. ```typescript function openWaitlist(props?: WaitlistProps): void ``` #### `openWaitlist()` params * `props?` * WaitlistProps The properties to pass to the `` component #### `openWaitlist()` usage ```js {{ filename: 'main.js', mark: [13] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerk = new Clerk('{{pub_key}}') await clerk.load() document.getElementById('app').innerHTML = `
` const waitlistDiv = document.getElementById('waitlist') clerk.openWaitlist(waitlistDiv) ``` ### `closeWaitlist()` Closes the waitlist overlay. ```typescript function closeWaitlist(): void ``` #### `closeWaitlist()` usage ```js {{ filename: 'main.js', mark: [17] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerk = new Clerk('{{pub_key}}') await clerk.load() document.getElementById('app').innerHTML = `
` const waitlistDiv = document.getElementById('waitlist') clerk.openWaitlist(waitlistDiv) // ... clerk.closeWaitlist(waitlistDiv) ``` ## Properties All props are optional. * `afterJoinWaitlistUrl` * `string` The full URL or path to navigate to after joining the waitlist. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `signInUrl` * `string` The full URL or path to the sign in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. ## Customization To learn about how to customize Clerk components, see the [customization guide](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "``" description: Clerk's component displays a table of Plans and Features that users can subscribe to. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/pricing-table lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/billing/pricing-table.mdx --- ![The \ component displays a table of Plans and Features that users can subscribe to.](/docs/images/ui-components/pricing-table.png) The `` component displays a table of Plans and Features that users can subscribe to. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountPricingTable() * unmountPricingTable() The following examples assume that you followed the [quickstart](/docs/js-frontend/getting-started/quickstart) to add Clerk to your JavaScript app. ### `mountPricingTable()` ```typescript function mountPricingTable(node: HTMLDivElement, props?: PricingTableProps): void ``` #### `mountPricingTable()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element used to render in the `` component *** * `props?` * PricingTableProps The properties to pass to the `` component #### `mountPricingTable()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const pricingTableDiv = document.getElementById('pricing-table') clerk.mountPricingTable(pricingTableDiv) ``` ### `unmountPricingTable()` ```typescript function unmountPricingTable(node: HTMLDivElement): void ``` #### `unmountPricingTable()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance #### `unmountPricingTable()` usage ```js {{ filename: 'main.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const pricingTableDiv = document.getElementById('pricing-table') clerk.mountPricingTable(pricingTableDiv) // ... clerk.unmountPricingTable(pricingTableDiv) ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `checkoutProps` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `collapseFeatures` * `boolean` A boolean that indicates whether the Features are collapsed. **Requires `layout` to be set to `'default'`**. Defaults to `false`. *** * `ctaPosition` * `'top' | 'bottom'` The placement of the CTA button. **Requires `layout` to be set to `'default'`**. Defaults to `'bottom'`. *** * `fallback` * `JSX` An optional UI to show when the pricing table is loading. *** * `for` * `'user' | 'organization'` A string that indicates whether the pricing table is for users or [Organizations](/docs/guides/organizations/overview). If `'user'`, the pricing table will display a list of Plans and Features that **users** can subscribe to. If `'organization'`, the pricing table will display a list of Plans and Features that **Organizations** can subscribe to. Defaults to `'user'`. *** * `newSubscriptionRedirectUrl` * `string` The URL to navigate to after the user completes the checkout and selects the "Continue" button. --- title: "``" description: The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the Clerk object without the need to check it exists. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loaded lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/control/clerk-loaded.mdx --- The `` component guarantees that the Clerk object has loaded (the `status` is `'ready'` or `'degraded'`) and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class is used to render and control the `` component: * load() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ### `load()` Render the `` component to an HTML `
` element. ```typescript function load(options?: ClerkOptions): Promise ``` #### `ClerkOptions` The `load()` method accepts an optional object that accepts the following props. All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect \[Clerk components]\[components-ref] and not \[Account Portal]\[ap-ref] pages. *** * `localization` * [Localization](/docs/guides/customizing-clerk/localization) | undefined Optional object to localize your components. Will only affect \[Clerk components]\[components-ref] and not \[Account Portal]\[ap-ref] pages. *** * `routerPush?` * `(to: string) => Promise | void` A function which takes the destination path as an argument and performs a "push" navigation. *** * `routerReplace?` * `(to: string) => Promise | void` A function which takes the destination path as an argument and performs a "replace" navigation. *** * `polling` * `boolean | undefined` Dictates if we should poll against Clerk's backend every 5 minutes. Defaults to `true`. *** * `selectInitialSession` * ((client: \[Client]\[client-ref]) => Session | null) | undefined An optional function which allows you to control which active session is the initial session to base a user's state off of. Defaults to the first session in the client's sessions array. *** * `standardBrowser` * `boolean | undefined` Controls if ClerkJS will load with the standard browser set up using Clerk cookies. Defaults to `true`. *** * `supportEmail` * `string | undefined` Optional support email for display in authentication screens. *** * `touchSession` * `boolean | undefined` Indicates whether the session should be "touched" when user interactions occur, used to record these interactions. Defaults to `true`. *** * `signInUrl` * `string | undefined` The default URL to use to direct to when 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. *** * `signUpUrl` * `string | undefined` The default URL to use to direct to when 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. *** * `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. *** * `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. *** * `afterSignOutUrl?` * `string` The full URL or path to navigate to after a successful sign-out. *** * `allowedRedirectOrigins?` * `Array` An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. *** * `allowedRedirectProtocols?` * `Array` An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. *** * `isSatellite` * `boolean | ((url: URL) => boolean) | undefined` Clerk flag for satellite apps. Experimental. *** * `telemetry?` * `false | { disabled?: boolean; debug?: boolean } | undefined` Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). #### `load()` usage ```js {{ filename: 'main.js', mark: [7] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() ``` --- title: \RedirectCallback /> description: Clerk's `` component is used to implement custom OAuth flows. It handles the OAuth callback and completes the authentication process. sdk: astro, chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/authenticate-with-redirect-callback lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: expo,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/control/authenticate-with-redirect-callback.mdx --- The `` component is a crucial part of implementing custom OAuth flows in your application. It serves as the callback handler for the authentication process initiated by the `authenticateWithRedirect()` method. Render it on the route specified as the `redirectUrl` in your `authenticateWithRedirect()` call. This component automatically handles the OAuth callback, completing the authentication process and managing the user's session. It uses the [`handleRedirectCallback()`](/docs/reference/javascript/clerk#handle-redirect-callback) method under the hood. ## Example For an example of how to use the `` component, see the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) guide. ## Properties All props are optional. * `continueSignUpUrl?` * `string | undefined | null` The full URL or path to navigate to if the sign up requires additional information. *** * `signInUrl?` * `string` The full URL or path where the `` component is mounted. *** * `signUpUrl?` * `string` The full URL or path where the `` component is mounted. *** * `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. *** * `firstFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if first factor verification is required. *** * `secondFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) is enabled. *** * `resetPasswordUrl?` * `string` The full URL or path to navigate to during sign in, if the user is required to reset their password. *** * `transferable?` * `boolean` A boolean that indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `verifyEmailAddressUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting email verification. *** * `verifyPhoneNumberUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting phone verification. --- title: "`` component" description: Clerk's component is used to render an Organization creation UI that allows users to create brand new Organizations within your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/organization/create-organization.mdx --- ![The \ component renders an Organization creation UI that allows users to create brand new organizations within your application.](/docs/images/ui-components/create-organization.png){{ style: { maxWidth: '492px' } }} The `` component is used to render an Organization creation UI that allows users to create brand new Organizations in your application. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountCreateOrganization * unmountCreateOrganization * openCreateOrganization * closeCreateOrganization The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ### mountCreateOrganization() Render the `` component to an HTML `
` element. ```typescript function mountCreateOrganization(node: HTMLDivElement, props?: CreateOrganizationProps): void ``` ### mountCreateOrganization() params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * CreateOrganizationProps The properties to pass to the `` component #### `mountCreateOrganization()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const createOrgDiv = document.getElementById('create-organization') clerk.mountCreateOrganization(createOrgDiv) ``` ### unmountCreateOrganization() Unmount and run cleanup on an existing `` component instance. ```typescript function unmountCreateOrganization(node: HTMLDivElement): void ``` #### `unmountCreateOrganization()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance #### `unmountCreateOrganization()` usage ```js {{ filename: 'main.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const createOrgDiv = document.getElementById('create-organization') clerk.mountCreateOrganization(createOrgDiv) // ... clerk.unmountCreateOrganization(createOrgDiv) ``` ### `openCreateOrganization()` Opens the `` component as an overlay at the root of your HTML `body` element. ```typescript function openCreateOrganization(props?: CreateOrganizationProps): void ``` #### `openCreateOrganization()` params * `props?` * CreateOrganizationProps The properties to pass to the `` component #### `openCreateOrganization()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const createOrgDiv = document.getElementById('create-organization') clerk.openCreateOrganization(createOrgDiv) ``` ### `closeCreateOrganization()` Closes the organization profile overlay. ```typescript function closeCreateOrganization(): void ``` #### `closeCreateOrganization()` usage ```js {{ filename: 'main.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const createOrgDiv = document.getElementById('create-organization') clerk.openCreateOrganization(createOrgDiv) // ... clerk.closeCreateOrganization(createOrgDiv) ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterCreateOrganizationUrl` * `string` Full URL or path to navigate to after creating a new organization. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/create-organization`. *** * `skipInvitationScreen` * `boolean` Hides the screen for sending invitations after an Organization is created. When left undefined, Clerk will automatically hide the screen if the number of max allowed members is equal to 1 *** * `hideSlug` * `boolean` Hides the optional slug field in the Organization creation screen. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to enable the ability to switch between available Organizations the user may be part of in your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-switcher lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/organization/organization-switcher.mdx --- ![The \ component allows a user to switch between their account types - their Personal Account and their joined Organizations.](/docs/images/ui-components/organization-switcher.png){{ style: { maxWidth: '436px' } }} The `` component allows a user to switch between their joined Organizations. If [Personal Accounts are enabled](/docs/guides/organizations/overview#allow-personal-accounts), users can also switch to their Personal Account. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple Organizations. It handles all Organization-related flows, including full Organization management for admins. Learn more about [Organizations](/docs/guides/organizations/overview). ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountOrganizationSwitcher() * unmountOrganizationSwitcher() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ## `mountOrganizationSwitcher()` Render the `` component to an HTML `
` element. ```typescript function mountOrganizationSwitcher(node: HTMLDivElement, props?: OrganizationSwitcherProps): void ``` ### mountOrganizationSwitcher() params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * OrganizationSwitcherProps The properties to pass to the `` component ### mountOrganizationSwitcher() usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const orgSwitcherDiv = document.getElementById('organization-switcher') clerk.mountOrganizationSwitcher(orgSwitcherDiv) ``` ## unmountOrganizationSwitcher() Unmount and run cleanup on an existing `` component instance. ```typescript function unmountOrganizationSwitcher(node: HTMLDivElement): void ``` ### unmountOrganizationSwitcher() params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance ### unmountOrganizationSwitcher() usage ```js {{ filename: 'main.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const orgSwitcherDiv = document.getElementById('organization-switcher') clerk.mountOrganizationSwitcher(orgSwitcherDiv) // ... clerk.unmountOrganizationSwitcher(orgSwitcherDiv) ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * `string` The full URL or path to navigate to after creating a new Organization. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after the user leaves the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `afterSelectOrganizationUrl` * `string` The full URL or path to navigate to after a successful Organization switch. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `createOrganizationMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the "Create organization" button will cause the \ component to open as a modal, or if the browser will navigate to the `createOrganizationUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `createOrganizationUrl` * `string` The full URL or path where the ``]createorg-ref component is mounted. *** * `defaultOpen` * `boolean` A boolean that controls the default state of the `` component. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. *** * `organizationProfileMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the **Manage organization** button will cause the \ component to open as a modal, or if the browser will navigate to the `organizationProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `organizationProfileProps` * `object` Specify options for the underlying \ component. For example: `{appearance: {...}}` *** * `organizationProfileUrl` * `string` The full URL or path where the \ component is mounted. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [createorg-ref]: /docs/reference/components/organization/create-organization [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured Organization management UI that allows users to manage their Organization profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/organization/organization-profile.mdx --- ![The \ component allows users to manage their Organization membership and security settings.](/docs/images/ui-components/organization-profile.png) The `` component allows users to manage their Organization membership, security, and billing settings. This component's **General** tab displays the Organization's information and the **Leave organization** button. Admins will be able to see the **Update profile** button, **Verified domains** section, and **Delete organization** button. The **Members** tab shows the Organization's members along with their join dates and Roles. Admins will have the ability to invite a member, change a member's Role, or remove them from the Organization. Admins will have tabs within the **Members** tab to view the Organization's [invitations](/docs/guides/organizations/overview#organization-invitations) and [requests](/docs/guides/organizations/verified-domains#membership-requests). The **Billing** tab displays the Plans and Features that are available to the Organization, as well as the user's billing information, such as their invoices and payment methods. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountOrganizationProfile() * unmountOrganizationProfile() * openOrganizationProfile() * closeOrganizationProfile() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ### mountOrganizationProfile() Render the `` component to an HTML `
` element. ```typescript function mountOrganizationProfile(node: HTMLDivElement, props?: OrganizationProfileProps): void ``` #### `mountOrganizationProfile()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * OrganizationProfileProps The properties to pass to the `` component #### `mountOrganizationProfile()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const orgProfileDiv = document.getElementById('organization-profile') clerk.mountOrganizationProfile(orgProfileDiv) ``` ### unmountOrganizationProfile() Unmount and run cleanup on an existing `` component instance. ```typescript function unmountOrganizationProfile(node: HTMLDivElement): void ``` #### `unmountOrganizationProfile()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance. #### `unmountOrganizationProfile()` usage ```js {{ filename: 'main.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const orgProfileDiv = document.getElementById('organization-profile') clerk.mountOrganizationProfile(orgProfileDiv) // ... clerk.unmountOrganizationProfile(orgProfileDiv) ``` ### `openOrganizationProfile()` Opens the `` component as an overlay at the root of your HTML `body` element. ```typescript function openOrganizationProfile(props?: OrganizationProfileProps): void ``` #### `openOrganizationProfile()` params * `props?` * OrganizationProfileProps The properties to pass to the `` component #### `openOrganizationProfile()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const orgProfileDiv = document.getElementById('organization-profile') clerk.openOrganizationProfile(orgProfileDiv) ``` ### `closeOrganizationProfile()` Closes the organization profile overlay. ```typescript function closeOrganizationProfile(): void ``` #### `closeOrganizationProfile()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const orgProfileDiv = document.getElementById('organization-profile') clerk.closeOrganizationProfile(orgProfileDiv) ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after leaving an Organization. *** * `customPages` * `CustomPages[]` An array of custom pages to add to the Organization profile. Only available for the [JavaScript SDK](/docs/reference/javascript/overview). To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/organization-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash- and virtual-based routing.
For example: `/organization-profile`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages.
Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React.
## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages](/docs/guides/customizing-clerk/adding-items/organization-profile) documentation. --- title: "`` component" description: Clerk's component is used to display Organization related memberships, invitations, and suggestions for the user. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/organization/organization-list.mdx --- ![The \ component displays Organization-related memberships and automatic invitations and suggestions for the user.](/docs/images/ui-components/organization-list.png){{ style: { maxWidth: '460px' } }} The `` component displays Organization-related memberships and automatic [invitations](/docs/guides/organizations/verified-domains#automatic-invitations) and [suggestions](/docs/guides/organizations/verified-domains#automatic-suggestions) for the user. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountOrganizationList() * unmountOrganizationList() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ## `mountOrganizationList()` Render the `` component to an HTML `
` element. ```typescript function mountOrganizationList(node: HTMLDivElement, props?: OrganizationListProps): void ``` ### `mountOrganizationList()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * OrganizationListProps The properties to pass to the `` component ### `mountOrganizationList()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const orgListDiv = document.getElementById('organization-list') clerk.mountOrganizationList(orgListDiv) ``` ## `unmountOrganizationList()` Unmount and run cleanup on an existing `` component instance. ```typescript function unmountOrganizationList(node: HTMLDivElement): void ``` ### `unmountOrganizationList()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance ### `unmountOrganizationList()` usage ```js {{ filename: 'main.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const orgListDiv = document.getElementById('organization-list') clerk.mountOrganizationList(orgListDiv) // ... clerk.unmountOrganizationList(orgListDiv) ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * ((org: [Organization](/docs/reference/javascript/organization)) => string) | string The full URL or path to navigate to after creating a new Organization. *** * `afterSelectOrganizationUrl` * ((org: [Organization](/docs/reference/javascript/organization)) => string) | string The full URL or path to navigate to after selecting an Organization. Defaults to `undefined`. *** * `afterSelectPersonalUrl` * ((org: [Organization](/docs/reference/javascript/organization)) => string) | string The full URL or path to navigate to after selecting the [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts). Defaults to `undefined`. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. Defaults to `false`. *** * `skipInvitationScreen` * `boolean | undefined` A boolean that controls whether the screen for sending invitations after an Organization is created is hidden. When `undefined`, Clerk will automatically hide the screen if the number of max allowed members is equal to 1. Defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [org-ref]: /docs/reference/javascript/organization --- title: "`` component" description: Clerk's component is used to render the familiar user button UI popularized by Google. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/user/user-button.mdx --- ![The \ component renders the familiar user button UI popularized by Google.](/docs/images/ui-components/user-button.png){{ style: { maxWidth: '436px' } }} The `` component renders the familiar user button UI popularized by Google. When selected, it opens a dropdown menu with options to manage account settings and sign out. The "Manage account" option launches the \ component, providing access to profile and security settings. For users that have [multi-session](/docs/guides/secure/session-options#multi-session-applications) enabled, the `` also allows users to sign into multiple accounts at once and instantly switch between them without the need for a full page reload. Learn more [here](/docs/guides/secure/session-options#multi-session-applications). ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountUserButton() * unmountUserButton() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ### `mountUserButton()` Render the `` component to an HTML `
` element. ```typescript function mountUserButton(node: HTMLDivElement, props?: UserButtonProps): void ``` #### `mountUserButton()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * UserButtonProps The properties to pass to the `` component #### `mountUserButton()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const userbuttonDiv = document.getElementById('user-button') clerk.mountUserButton(userbuttonDiv) ``` ### `unmountUserButton()` Unmount and run cleanup on an existing `` component instance. ```typescript function unmountUserButton(node: HTMLDivElement): void ``` #### `unmountUserButton()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance. #### `unmountUserButton()` usage ```js {{ filename: 'main.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const userButtonDiv = document.getElementById('user-button') clerk.mountUserButton(userButtonDiv) // ... clerk.unmountUserButton(userButtonDiv) ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterMultiSessionSingleSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterMultiSessionSingleSignOutUrl` to \.** The full URL or path to navigate to after signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterSignOutUrl` to \.** The full URL or path to navigate to after a successful sign-out. *** * `afterSwitchSessionUrl` * `string` The full URL or path to navigate to after a successful account change in a multi-session app. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `defaultOpen` * `boolean` Controls whether the `` should open by default during the first render. *** * `showName` * `boolean` Controls if the user name is displayed next to the user image button. *** * `signInUrl` * `string` The full URL or path to navigate to when the **Add another account** button is clicked. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `userProfileMode` * `'modal' | 'navigation'` Controls whether selecting the **Manage your account** button will cause the \ component to open as a modal, or if the browser will navigate to the `userProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `userProfileProps` * `object` Specify options for the underlying \ component. For example: `{additionalOAuthScopes: {google: ['foo', 'bar'], github: ['qux']}}`. *** * `userProfileUrl` * `string` The full URL or path leading to the user management interface. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). You can also [add custom actions and links to the `` menu](/docs/guides/customizing-clerk/adding-items/user-button). --- title: "`` component" description: Clerk's component is used to render the familiar user avatar on its own. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-avatar lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/user/user-avatar.mdx --- ![The \ component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications.](/docs/images/ui-components/user-avatar.png) The `` component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountUserAvatar() * unmountUserAvatar() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ### `mountUserAvatar()` Render the `` component to an HTML `
` element. ```typescript function mountUserAvatar(node: HTMLDivElement, props?: UserAvatarProps): void ``` #### `mountUserAvatar()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * UserAvatarProps The properties to pass to the `` component #### `mountUserAvatar()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const userAvatarDiv = document.getElementById('user-avatar') clerk.mountUserAvatar(userAvatarDiv) ``` ### `unmountUserAvatar()` Unmount and run cleanup on an existing `` component instance. ```typescript function unmountUserAvatar(node: HTMLDivElement): void ``` #### `unmountUserAvatar()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance. #### `unmountUserAvatar()` usage ```js {{ filename: 'main.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const userAvatarDiv = document.getElementById('user-avatar') clerk.mountUserAvatar(userAvatarDiv) // ... clerk.unmountUserAvatar(userAvatarDiv) ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `rounded?` * `boolean` Determines whether the user avatar is displayed with rounded corners. *** * `appearance?` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` Optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/components/user/user-profile.mdx --- ![The \ component renders a full-featured account management UI that allows users to manage their profile and security settings.](/docs/images/ui-components/user-profile.png){{ style: { maxWidth: '100%' } }} The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile, security, and billing settings. ## Usage with JavaScript The following methods available on an instance of the [`Clerk`](/docs/reference/javascript/clerk) class are used to render and control the `` component: * mountUserProfile() * unmountUserProfile() * openUserProfile() * closeUserProfile() The following examples assume that you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application. ### `mountUserProfile()` Render the `` component to an HTML `
` element. ```typescript function mountUserProfile(node: HTMLDivElement, props?: UserProfileProps): void ``` #### `mountUserProfile()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The `
` element used to render in the `` component *** * `props?` * UserProfileProps The properties to pass to the `` component #### `mountUserProfile()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const userProfileDiv = document.getElementById('user-profile') clerk.mountUserProfile(userProfileDiv) ``` ### `unmountUserProfile()` Unmount and run cleanup on an existing `` component instance. ```typescript function unmountUserProfile(node: HTMLDivElement): void ``` #### `unmountUserProfile()` params * `node` * [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) The container `
` element with a rendered `` component instance. #### `unmountUserProfile()` usage ```js {{ filename: 'main.js', mark: [19] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const userProfileDiv = document.getElementById('user-profile') clerk.mountUserProfile(userProfileDiv) // ... clerk.unmountUserProfile(userProfileDiv) ``` ### `openUserProfile()` Opens the `` component as an overlay at the root of your HTML `body` element. ```typescript function openUserProfile(props?: UserProfileProps): void ``` #### `openUserProfile()` params * `props?` * UserProfileProps The properties to pass to the `` component #### `openUserProfile()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const userProfileDiv = document.getElementById('user-profile') clerk.openUserProfile(userProfileDiv) ``` ### `closeUserProfile()` Closes the user profile overlay. ```typescript function closeUserProfile(): void ``` #### `closeUserProfile()` usage ```js {{ filename: 'main.js', mark: [15] }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const userProfileDiv = document.getElementById('user-profile') clerk.closeUserProfile(userProfileDiv) ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/user-profile`. *** * `additionalOAuthScopes` * `object` Specify additional scopes per OAuth provider that your users would like to provide if not already approved. For example: `{google: ['foo', 'bar'], github: ['qux']}`. *** * `customPages` * [CustomPage](/docs/reference/javascript/types/custom-page)\[] An array of custom pages to add to the user profile. Only available for the [JavaScript SDK](/docs/reference/javascript/overview). To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/user-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages documentation](/docs/guides/customizing-clerk/adding-items/user-profile). --- title: React Quickstart description: Add authentication and user management to your React app with Clerk. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: react sourceFile: /docs/getting-started/quickstart.react.mdx --- This tutorial will demonstrate how to create a new React app using Vite and add authentication to it using Clerk. If you would like to create an application using the React Router framework, see the React Router quickstart. ## Create a React app using Vite Run the following commands to create a new React app using [Vite](https://vitejs.dev/guide/#scaffolding-your-first-vite-project): ```npm npm create vite@latest clerk-react -- --template react-ts cd clerk-react npm install npm run dev ``` ## Install `@clerk/clerk-react` The [Clerk React SDK](/docs/reference/react/overview) gives you access to prebuilt components, hooks, and helpers to make user authentication easier. Run the following command to install the SDK: ```npm npm install @clerk/clerk-react ``` ## Set your Clerk API keys Add your Clerk Publishable Key to your `.env` file. It can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, copy your Clerk Publishable Key. 3. Paste your key into your `.env` file. The final result should resemble the following: ```env {{ filename: '.env' }} VITE_CLERK_PUBLISHABLE_KEY={{pub_key}} ``` ## Import the Clerk Publishable Key In your `main.tsx` file, import your Clerk Publishable Key. You can add an `if` statement to check that it is imported and that it exists. This will prevent running the app without the Publishable Key, and will also prevent TypeScript errors. ```tsx {{ filename: 'src/main.tsx', mark: [[6, 7], [9, 11]] }} import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App.tsx' // Import your Publishable Key const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Add your Clerk Publishable Key to the .env file') } createRoot(document.getElementById('root')!).render( , ) ``` ## Add `` to your app The \ component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with `` to make authentication globally accessible. See the reference docs for other configuration options. Pass your Publishable Key as a prop to the component. ```tsx {{ filename: 'src/main.tsx', mark: [5, 16, 18] }} import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App.tsx' import { ClerkProvider } from '@clerk/clerk-react' // Import your Publishable Key const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Add your Clerk Publishable Key to the .env file') } createRoot(document.getElementById('root')!).render( , ) ``` ## Create a header with Clerk components You can control which content signed-in and signed-out users can see with the prebuilt control components. The following example creates a header using the following components: * \: Children of this component can only be seen while **signed in**. * \: Children of this component can only be seen while **signed out**. * \: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. * \: 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: 'src/App.tsx', mark: [1, [5, 12]] }} import { SignedIn, SignedOut, SignInButton, UserButton } from '@clerk/clerk-react' export default function App() { return (
) } ``` ## Create your first user Run your project with the following command: ```npm npm run dev ``` Visit your app's homepage at [`http://localhost:5173`](http://localhost:5173). Sign up to create your first user.
## Next step: Add routing with React Router * Integrate React Router into your Clerk app in declarative mode ## More resources Learn more about Clerk components, how to customize them, and how to use Clerk's client-side helpers using the following guides. * [Prebuilt components](/docs/reference/components/overview) * Learn more about Clerk's suite of components that let you quickly add authentication to your app. *** * [Customization & localization](/docs/guides/customizing-clerk/appearance-prop/overview) * Learn how to customize and localize Clerk components. *** * [Client-side helpers (hooks)](/docs/reference/hooks/use-user) * Learn more about Clerk's client-side helpers and how to use them. --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: react sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'src/screens/pricing.tsx' }} import { PricingTable } from '@clerk/clerk-react' export default function PricingScreen() { return (
) } ```
## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```tsx {{ filename: 'src/pages/bronze-content.tsx' }} import { useAuth } from '@clerk/clerk-react' export default function BronzeContentPage() { const { has, isLoaded } = useAuth() if (!isLoaded) return
Loading...
const hasBronzePlan = has({ plan: 'bronze' }) if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```tsx {{ filename: 'src/pages/premium-content.tsx' }} import { useAuth } from '@clerk/clerk-react' export default function PremiumContentPage() { const { isLoaded, has } = useAuth() if (!isLoaded) return
Loading...
const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```tsx {{ filename: 'src/pages/manage-premium-content.tsx' }} import { useAuth } from '@clerk/clerk-react' export default function ManagePremiumContentPage() { const { has, isLoaded } = useAuth() if (!isLoaded) return
Loading...
const hasPremiumAccessManage = has({ permission: 'org:premium_access:manage' }) if (!hasPremiumAccessManage) return (

Only subscribers with the Premium Access Manage permission can access this content.

) return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. ```tsx {{ filename: 'src/pages/protected-content.tsx' }} import { Protect } from '@clerk/clerk-react' export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. ```tsx {{ filename: 'src/pages/protected-premium-content.tsx' }} import { Protect } from '@clerk/clerk-react' export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. ```tsx {{ filename: 'src/pages/protected-manage-content.tsx' }} import { Protect } from '@clerk/clerk-react' export default function ProtectedManageContentPage() { return ( Only subscribers with the Premium Access Manage permission can access this content.

} >

Exclusive Management Content

This content is only visible to users with Premium Access Manage permission.

) } ```
--- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: react sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'src/screens/pricing.tsx' }} import { PricingTable } from '@clerk/clerk-react' export default function PricingScreen() { return (
) } ```
## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```tsx {{ filename: 'src/pages/bronze-content.tsx' }} import { useAuth } from '@clerk/clerk-react' export default function BronzeContentPage() { const { has, isLoaded } = useAuth() if (!isLoaded) return
Loading...
const hasBronzePlan = has({ plan: 'bronze' }) if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if a user has a Feature. ```tsx {{ filename: 'src/pages/premium-content.tsx' }} import { useAuth } from '@clerk/clerk-react' export default function PremiumContentPage() { const { isLoaded, has } = useAuth() if (!isLoaded) return
Loading...
const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. ```tsx {{ filename: 'src/pages/protected-content.tsx' }} import { Protect } from '@clerk/clerk-react' export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. ```tsx {{ filename: 'src/pages/protected-premium-content.tsx' }} import { Protect } from '@clerk/clerk-react' export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
--- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: react sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: "``" description: The component provides session and user context to Clerk's hooks and components. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/clerk-provider lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/clerk-provider.mdx --- The `` component is required to integrate Clerk into your React application, providing session and user context to Clerk's hooks and components. The recommended approach is to wrap your entire app with `` at the entry point to make authentication globally accessible. If you only need authentication for specific routes or pieces of your application, render `` deeper in the component tree. This allows you to implement Clerk's functionality precisely where required without impacting the rest of your app. ## Example ```tsx {{ filename: 'index.tsx' }} import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' import { ClerkProvider } from '@clerk/clerk-react' // Import your Publishable Key const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Add your Clerk Publishable Key to the .env file') } ReactDOM.createRoot(document.getElementById('root')!).render( , ) ``` ## Properties | Property | Type | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `afterMultiSessionSingleSignOutUrl?` | null \| string | The full URL or path to navigate to after signing out the current user is complete. This option applies to [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). | | ~~`afterSignInUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl` or `signInForceRedirectUrl` instead. | | `afterSignOutUrl?` | null \| string | Full URL or path to navigate to after successful sign out. | | ~~`afterSignUpUrl?`~~ | null \| string | **Deprecated.** Use `signUpFallbackRedirectUrl` or `signUpForceRedirectUrl` instead. | | `allowedRedirectOrigins?` | (string \| RegExp)\[] | An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `allowedRedirectProtocols?` | string\[] | An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `appearance?` | [`Appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) | Optional object to style your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `clerkJSUrl?` | `string` | The URL that `@clerk/clerk-js` should be hot-loaded from. | | `clerkJSVariant?` | "" \| "headless" | If your web application only uses Control Components, you can set this value to `'headless'` and load a minimal ClerkJS bundle for optimal page performance. | | `clerkJSVersion?` | `string` | The npm version for `@clerk/clerk-js`. | | `domain?` | string \| (url: URL) => string | **Required if your application is a satellite application**. Sets the domain of the satellite application. | | `experimental?` | `Autocomplete`\<\{ commerce: boolean; persistClient: boolean; rethrowOfflineNetworkErrors: boolean; \}, `Record`\<`string`, `any`\>\> | Enable experimental flags to gain access to new features. These flags are not guaranteed to be stable and may change drastically in between patch or minor versions. | | `initialState?` | `Serializable`\<\{ actor: undefined \| \{ \[x: string]: unknown; sub: string; \}; factorVerificationAge: \[number, number]; organization: undefined \| OrganizationResource; orgId: undefined \| string; orgPermissions: undefined \| string\[]; orgRole: undefined \| string; orgSlug: undefined \| string; session: undefined \| SessionResource; sessionClaims: JwtPayload; sessionId: undefined \| string; sessionStatus: SessionStatusClaim; user: undefined \| UserResource; userId: undefined \| string; \}\> | Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `isSatellite?` | boolean \| (url: URL) => boolean | A boolean that indicates whether the application is a satellite application. | | `localization?` | [`LocalizationResource`](/docs/guides/customizing-clerk/localization) | Optional object to localize your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `newSubscriptionRedirectUrl?` | null \| string | The URL to navigate to after the user completes the checkout and clicks the "Continue" button. | | `nonce?` | `string` | This nonce value will be passed through to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. | | `proxyUrl?` | string \| (url: URL) => string \| (url: URL) => string | **Required for applications that run behind a reverse proxy**. The URL that Clerk will proxy requests to. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). | | `publishableKey` | `string` | The Clerk Publishable 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. | | ~~`redirectUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl`, `signInForceRedirectUrl`, `signUpFallbackRedirectUrl`, or `signUpForceRedirectUrl` instead. | | `routerPush?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "push" navigation. | | `routerReplace?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "replace" navigation. | | `sdkMetadata?` | \{ environment?: string; name: string; version: string; \} | Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `sdkMetadata.environment?` | `string` | Typically this will be the `NODE_ENV` that the SDK is currently running in. | | `sdkMetadata.name` | `string` | The npm package name of the SDK. | | `sdkMetadata.version` | `string` | The npm package version of the SDK. | | `selectInitialSession?` | (client: ClientResource) => null \| SignedInSessionResource | By default, the last signed-in session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. | | `signInFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signInForceRedirectUrl?` | null \| string | 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. | | `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. | | `signUpFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signUpForceRedirectUrl?` | null \| string | 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. | | `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. | | `standardBrowser?` | `boolean` | By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. | | `supportEmail?` | `string` | Optional support email for display in authentication screens. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `taskUrls?` | `Record`\<`"choose-organization"`, `string`\> | Customize the URL paths users are redirected to after sign-in or sign-up when specific session tasks need to be completed. When `undefined`, it uses Clerk's default task flow URLs. Defaults to `undefined`. | | `telemetry?` | false \| \{ debug?: boolean; disabled?: boolean; perEventSampling?: boolean; \} | Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. | | `touchSession?` | `boolean` | By default, the [Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/Sessions#operation/touchSession) is called during page focus to keep the last active session alive. This option allows you to disable this behavior. | | `waitlistUrl?` | `string` | The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). | ## SDK-specific properties ### Next.js * `dynamic` * `boolean` Indicates whether or not Clerk should make dynamic auth data available based on the current request. Defaults to `false`. Opts the application into dynamic rendering when `true`. For more information, see Next.js rendering modes and Clerk. ### Chrome Extension * `syncHost` * `string` To enable, pass the URL of the web application that the extension will sync the authentication state from. See the dedicated guide for more information. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: react sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`` component" description: Clerk's component renders a UI for signing up users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/authentication/sign-up.mdx --- ![The \ component renders a UI for signing up users.](/docs/images/ui-components/sign-up.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'src/App.tsx' }} import { SignUp } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `string` If provided, this URL will always be used as the redirect destination 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. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-up`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signInFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Used for the 'Already have an account? Sign in' link that's rendered. 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. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signInUrl` * `string` The full URL or path to the sign-in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for signing in users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/authentication/sign-in.mdx --- ![The \ component renders a UI for signing in users.](/docs/images/ui-components/sign-in.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI to allow users to sign in or sign up by default. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'src/App.tsx' }} import { SignIn } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `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. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-in`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signUpFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Used for the 'Don't have an account? Sign up' link that's rendered. Defaults to `/`. 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 used as the redirect destination after the user signs up. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signUpUrl` * `string` The full URL or path to the sign-up page. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `transferable` * `boolean` Indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `waitlistUrl` * `string` Full URL or path to the waitlist page. Use this property to provide the target of the 'Waitlist' link that's rendered. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). If you've passed the `waitlistUrl` prop to the \ component, it will infer from that, and you can omit this prop. *** * `withSignUp` * `boolean` Opt into sign-in-or-up flow by setting this prop to `true`. When `true`, if a user does not exist, they will be prompted to sign up. If a user exists, they will be prompted to sign in. Defaults to `true` if the `CLERK_SIGN_IN_URL` environment variable is set. Otherwise, defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: The component renders a waitlist form that allows users to join for early access to your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/waitlist lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/authentication/waitlist.mdx --- ![The \ component renders a form that allows users to join for early access to your app.](/docs/images/ui-components/waitlist.png){{ style: { maxWidth: '460px' } }} In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. [Learn more about additional features available in **Waitlist** mode](/docs/guides/secure/restricting-access#waitlist). The `` component renders a form that allows users to join for early access to your app. ## Enable Waitlist mode Before using the `` component, you must enable **Waitlist** mode in the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. ## Example > \[!WARNING] > Before using the `` component, you must provide the `waitlistUrl` prop either in the \ or \ component to ensure proper functionality. The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'src/App.tsx' }} import { Waitlist } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties All props are optional. * `afterJoinWaitlistUrl` * `string` The full URL or path to navigate to after joining the waitlist. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `signInUrl` * `string` The full URL or path to the sign in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. ## Customization To learn about how to customize Clerk components, see the [customization guide](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component renders a UI for resolving the `choose-organization` task. sdk: js-frontend, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/task-choose-organization lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/authentication/task-choose-organization.mdx --- ![The \ component renders a UI for resolving the choose-organization session task.](/docs/images/ui-components/task-choose-organization.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for resolving the `choose-organization` session task. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/overview). You can further customize your `` component by passing additional properties at the time of rendering. > \[!IMPORTANT] > The `` component cannot render when a user doesn't have current session tasks. ## Example The following example demonstrates how to host the `` component on a custom page. ```tsx {{ filename: 'index.tsx', mark: [17] }} import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' import { ClerkProvider } from '@clerk/clerk-react' // Import your Publishable Key const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Add your Clerk Publishable Key to the .env file') } ReactDOM.createRoot(document.getElementById('root')!).render( , ) ``` ```jsx {{ filename: 'src/onboarding/choose-organization.tsx' }} import { TaskChooseOrganization } from '@clerk/clerk-react' const ChooseOrganizationPage = () => export default ChooseOrganizationPage ``` ## Properties All props are optional. * `redirectUrlComplete` * `string` The full URL or path to navigate to after successfully completing all tasks. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for authenticating users with Google's One Tap API. sdk: astro, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/google-one-tap lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: chrome-extension,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/authentication/google-one-tap.mdx --- > \[!IMPORTANT] > To use Google One Tap with Clerk, you must [enable Google as a social connection in the Clerk Dashboard](/docs/guides/configure/auth-strategies/social-connections/google#configure-for-your-production-instance) and make sure to use custom credentials. The `` component renders the [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) UI so that users can use a single button to sign-up or sign-in to your Clerk application with their Google accounts. By default, this component will redirect users back to the page where the authentication flow started. However, you can override this with force redirect URL props or [force redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). > \[!TIP] > `` does not render if the user is already signed into your Clerk application, so there's no need to manually check if a user is signed in yourself before rendering it. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'src/App.tsx' }} import { GoogleOneTap } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties * `cancelOnTapOutside?` * `boolean` If `true`, the One Tap prompt closes automatically if the user clicks outside of the prompt. Defaults to `true`. *** * `itpSupport?` * `boolean` If `true`, enables the [ITP-specific UX](https://developers.google.com/identity/gsi/web/guides/itp) when One Tap is rendered on ITP browsers such as Chrome on iOS, Safari, and FireFox. Defaults to `true`. *** * `fedCmSupport?` * `boolean` If `true`, enables Google One Tap to use [the FedCM API](https://developers.google.com/privacy-sandbox/3pcd/fedcm) to sign users in. See Google's docs on [best practices when disabling FedCM support](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap#do_not_cover_google_one_tap). Defaults to `true` *** * `signInForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs in, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). *** * `signUpForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs up, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). ## Limitations * If your application will use the Google API on behalf of your users, the `` component is not recommended, as Google does not provide Clerk with an access or refresh token that you can use. * Users with the 1Password browser extension may not be able to render the Google One Tap UI. They must disable this extension. * When testing in development, if you select the `X` button to close the Google One Tap UI, you may encounter [a cooldown](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown) that prevents you from rendering it again for a period of time. To bypass the cooldown, remove the `g_state` cookie. --- title: "`` component" description: Clerk's component renders a button that opens the checkout drawer for Plan subscriptions. sdk: react, nextjs, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/checkout-button lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react,nextjs,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/billing/checkout-button.mdx --- ![The \ component renders a button that opens the checkout drawer.](/docs/images/ui-components/checkout-button.png) The `` component renders a button that opens the checkout drawer when selected, allowing users to subscribe to a Plan for either their Personal Account or an Organization. It must be wrapped inside a \ component to ensure the user is authenticated. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. ## Usage `` must be wrapped inside a \ component to ensure the user is authenticated. ```tsx <> // ❌ This will throw an error // ✅ Correct usage ``` `` will throw an error if the `for` prop is set to `'organization'` and no Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. is set. ```tsx <> // ❌ This will throw an error if no Organization is active // ✅ Correct usage {auth.orgId ? : null} ``` `` preserves any click handlers attached to custom button elements, while maintaining the checkout drawer functionality. ```tsx ``` ### Examples ```tsx {{ filename: 'src/components/PricingSection.tsx' }} import { SignedIn } from '@clerk/clerk-react' import { CheckoutButton } from '@clerk/clerk-react/experimental' const PricingSection = () => { return ( {/* Basic usage */} {/* Customizes the appearance of the checkout drawer */} {/* Custom button */} { console.log('Subscription completed!') }} newSubscriptionRedirectUrl="/dashboard" > ) } export default PricingSection ``` ## Properties * `planId` * `string` The ID of the Plan to subscribe to. *** * `planPeriod?` * `'month' | 'annual'` The billing period for the subscription. *** * `for?` * `'user' | 'organization'` Determines whether the subscription is for the current user or Organization. Defaults to `'user'`. *** * `children?` * `React.ReactNode` A custom button element. If not provided, defaults to a button with the text "Checkout". *** * `onSubscriptionComplete?` * `() => void` A callback function that is called when a subscription is successfully completed. *** * `newSubscriptionRedirectUrl?` * `string` The URL to redirect to after a successful subscription. *** * `checkoutProps?` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. For example: ``. --- title: "``" description: Clerk's component displays a table of Plans and Features that users can subscribe to. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/pricing-table lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/billing/pricing-table.mdx --- ![The \ component displays a table of Plans and Features that users can subscribe to.](/docs/images/ui-components/pricing-table.png) The `` component displays a table of Plans and Features that users can subscribe to. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'src/App.tsx' }} import { PricingTable } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `checkoutProps` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `collapseFeatures` * `boolean` A boolean that indicates whether the Features are collapsed. **Requires `layout` to be set to `'default'`**. Defaults to `false`. *** * `ctaPosition` * `'top' | 'bottom'` The placement of the CTA button. **Requires `layout` to be set to `'default'`**. Defaults to `'bottom'`. *** * `fallback` * `JSX` An optional UI to show when the pricing table is loading. *** * `for` * `'user' | 'organization'` A string that indicates whether the pricing table is for users or [Organizations](/docs/guides/organizations/overview). If `'user'`, the pricing table will display a list of Plans and Features that **users** can subscribe to. If `'organization'`, the pricing table will display a list of Plans and Features that **Organizations** can subscribe to. Defaults to `'user'`. *** * `newSubscriptionRedirectUrl` * `string` The URL to navigate to after the user completes the checkout and selects the "Continue" button. --- title: "`` component" description: Clerk's component renders a button that opens the Plan details drawer. sdk: react, nextjs, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/plan-details-button lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react,nextjs,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/billing/plan-details-button.mdx --- ![The \ component renders a button that opens the Plan details drawer.](/docs/images/ui-components/plan-details.png){{ style: { maxWidth: '460px' } }} The `` component renders a button that opens the Plan details drawer, allowing users to view detailed information about a specific Plan, including pricing, Features, and other Plan-specific details. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. ## Usage `` preserves any click handlers attached to custom button elements, while maintaining the Plan details drawer functionality. ```tsx ``` `` supports rendering the Plan details drawer in a custom portal container. ```tsx {{ prettier: false }} const portalRoot = document.getElementById('custom-portal') ``` ### Examples ```tsx {{ filename: 'src/components/PricingSection.tsx' }} import { PlanDetailsButton } from '@clerk/clerk-react' const PricingSection = () => { return (
{/* Basic usage with Plan ID */} {/* Customizes the appearance of the Plan details drawer */} {/* Custom button */}
) } export default PricingSection ```
## Properties * `planId?` * `string` The ID of the Plan to display details for. It is required if `plan` is not provided. *** * `plan?` * BillingPlanResource The Plan to display details for. It is used as initial data until the Plan is fetched from the server. *** * `children?` * `React.ReactNode` Optional custom button element. If not provided, defaults to a button with the text "Plan details". *** * `initialPlanPeriod?` * `'month' | 'annual'` Optional prop to set the initial billing period view when the Plan details drawer opens. *** * `planDetailsProps?` * `{ appearance: Appearance }` Options for the Plan details drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. For example: ``. --- title: "`` component" description: Clerk's component renders a button that opens the subscription details drawer. sdk: react, nextjs, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/subscription-details-button lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react,nextjs,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/billing/subscription-details-button.mdx --- ![The \ component renders a button that opens the subscription details drawer.](/docs/images/ui-components/subscription.png) The `` component renders a button that opens the subscription details drawer when selected, allowing users to view and manage their subscription details, whether for their Personal Account or Organization. It must be wrapped inside a \ component to ensure the user is authenticated. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. ## Usage `` must be wrapped inside a \ component to ensure the user is authenticated. ```tsx <> // ❌ This will throw an error // ✅ Correct usage ``` `` will throw an error if the `for` prop is set to `'organization'` and no Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. is set. ```tsx <> // ❌ This will throw an error if no Organization is active // ✅ Correct usage {auth.orgId ? : null} ``` ### Examples ```tsx {{ filename: 'src/components/BillingSection.tsx' }} import { SignedIn } from '@clerk/clerk-react' import { SubscriptionDetailsButton } from '@clerk/clerk-react/experimental' const BillingSection = () => { return ( {/* Basic usage */} {/* Customizes the appearance of the subscription details drawer */} {/* Custom button */} console.log('Subscription canceled')}> ) } export default BillingSection ``` ## Properties All props are optional. * `for?` * `'user' | 'organization'` Determines whether to show subscription details for the current user or Organization. Defaults to `'user'`. *** * `children?` * `React.ReactNode` Optional custom button element. If not provided, defaults to a button with the text "Subscription details". *** * `onSubscriptionCancel?` * `() => void` A callback function that is called when a subscription is cancelled. *** * `subscriptionDetailsProps?` * `{ appearance: Appearance }` Options for the subscription details drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. For example: ``. --- title: "``" description: The component indicates that the Clerk object has failed to load. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-failed lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/clerk-failed.mdx --- The `` component indicates that the Clerk object has failed to load. This is useful for displaying an error message to the user. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'src/App.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/clerk-react' export default function App() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } export default App ```
--- title: "``" description: The component indicates that Clerk is partially operational. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-degraded lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/clerk-degraded.mdx --- The `` component indicates that Clerk is partially operational. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'src/App.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/clerk-react' export default function App() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } export default App ```
--- title: "``" description: The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the Clerk object without the need to check it exists. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loaded lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/clerk-loaded.mdx --- The `` component guarantees that the Clerk object has loaded (the `status` is `'ready'` or `'degraded'`) and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'src/App.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/clerk-react' export default function App() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } export default App ```
--- title: "``" description: The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loading lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/clerk-loading.mdx --- The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'src/App.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/clerk-react' export default function App() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } export default App ```
--- title: "`` (deprecated)" description: The component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/redirect-to-organization-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToOrganizationProfile() method instead. The `` component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'pages/index.tsx' }} import { SignedIn, SignedOut, RedirectToOrganizationProfile } from '@clerk/clerk-react' export default function Page() { return ( <> You need to sign in to view your Organization profile. ) } ``` --- title: "`` (deprecated)" description: The component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/redirect-to-create-organization.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToCreateOrganization() method instead. The `` component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'pages/index.tsx' }} import { SignedIn, SignedOut, RedirectToCreateOrganization } from '@clerk/clerk-react' export default function Page() { return ( <> You need to sign in to create an Organization. ) } ``` --- title: \RedirectCallback /> description: Clerk's `` component is used to implement custom OAuth flows. It handles the OAuth callback and completes the authentication process. sdk: astro, chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/authenticate-with-redirect-callback lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: expo,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/authenticate-with-redirect-callback.mdx --- The `` component is a crucial part of implementing custom OAuth flows in your application. It serves as the callback handler for the authentication process initiated by the `authenticateWithRedirect()` method. Render it on the route specified as the `redirectUrl` in your `authenticateWithRedirect()` call. This component automatically handles the OAuth callback, completing the authentication process and managing the user's session. It uses the handleRedirectCallback() method under the hood. ## Example For an example of how to use the `` component, see the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) guide. ## Properties All props are optional. * `continueSignUpUrl?` * `string | undefined | null` The full URL or path to navigate to if the sign up requires additional information. *** * `signInUrl?` * `string` The full URL or path where the `` component is mounted. *** * `signUpUrl?` * `string` The full URL or path where the `` component is mounted. *** * `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. *** * `firstFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if first factor verification is required. *** * `secondFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) is enabled. *** * `resetPasswordUrl?` * `string` The full URL or path to navigate to during sign in, if the user is required to reset their password. *** * `transferable?` * `boolean` A boolean that indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `verifyEmailAddressUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting email verification. *** * `verifyPhoneNumberUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting phone verification. --- title: "``" description: The component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/redirect-to-sign-in.mdx --- The `` component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'pages/index.tsx' }} import { SignedIn, SignedOut, RedirectToSignIn, UserButton } from '@clerk/clerk-react' export default function Page() { return ( <> ) } ``` --- title: "``" description: The Protect component protects content or even entire routes based on authentication, and optionally, authorization. It only renders its children when the current user is signed-in, and if performing authorization checks, if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/protect lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/protect.mdx --- The \ component protects content or even entire routes based on: * authentication: whether the user is signed-in or not. * authorization: whether the user has been granted a specific type of access control (Role, Permission, Feature, or Plan) `` **always** performs authentication checks. To perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., you can pass different props, like `role`, `permission`, `feature`, or `plan`. `` accepts a `fallback` prop that will be rendered if the user fails the authentication or authorization checks. `` can be used both client-side and server-side (in Server Components). > \[!CAUTION] > This component only **visually hides** its children when the current user is not authorized. The contents of its children remain accessible via the browser's source code even if the user fails the authorization check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Usage ### Authentication checks `` always performs authentication checks. It will render its children if the user is signed-in, and its `fallback` prop if the user is signed-out. ```jsx {{ filename: 'src/App.tsx' }} import { Protect } from '@clerk/clerk-react' function App() { return ( Users that are signed-out can see this.

}>

Users that are signed-in can see this.

) } export default App ```
### Authorization checks To limit who is able to see the content that `` renders, you can pass **one** of the access control props: `permission`, `role`, `feature`, or `plan`. It's recommended to use **Permission-based** authorization over **Role-based** authorization, and **Feature-based** authorization over **Plan-based** authorization, as they are more flexible, easier to manage, and more secure. If you do not pass any of the access control props, `` will render its children if the user is signed in, regardless of their Role or its Permissions. For more complex authorization logic, pass conditional logic to the `condition` prop. ### Render content by Permissions The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:invoices:create` Permission. ```jsx {{ filename: 'src/App.tsx' }} import { Protect } from '@clerk/clerk-react' function App() { return ( You do not have the Permissions to create an invoice.

} >

Users with Permission org:invoices:create can see this.

) } export default App ```
### Render content by Role While authorization by `permission` is **recommended**, for convenience, `` allows a `role` prop to be passed. The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:billing` Role. ```jsx {{ filename: 'src/App.tsx' }} import { Protect } from '@clerk/clerk-react' function App() { return ( Only a member of the Billing department can access this content.

} >

Users with Role org:billing can see this.

) } export default App ```
### Render content by Plan The following example demonstrates how to use `` to protect content by checking if the user has a Plan. ```tsx {{ filename: 'src/App.tsx' }} import { Protect } from '@clerk/clerk-react' function App() { return ( Sorry, only subscribers to the Bronze plan can access this content.

} >

Welcome, Bronze subscriber!

) } export default App ```
### Render content by Feature The following example demonstrates how to use `` to protect content by checking if the user has a Feature. ```tsx {{ filename: 'src/App.tsx' }} import { Protect } from '@clerk/clerk-react' function App() { return ( Sorry, only subscribers with the Premium Access feature can access this content.

} >

Congratulations! You have access to the Premium Access feature.

) } export default App ```
### Render content conditionally The following example uses ``'s `condition` prop to conditionally render its children if the user has the correct Role. ```tsx {{ filename: 'src/App.tsx' }} import { Protect } from '@clerk/clerk-react' function App() { return ( has({ role: 'org:admin' }) || has({ role: 'org:billing_manager' })} fallback={

Only an Admin or Billing Manager can access this content.

} >

The settings page.

) } export default App ```
## Properties * `condition?` * `has => boolean` Optional conditional logic that renders the children if it returns `true`. *** * `fallback?` * `JSX` Optional UI to show when a user doesn't have the correct type of access control to access the protected content. *** * `feature?` * `string` Optional string corresponding to a [Feature](/docs/guides/billing/overview). *** * `plan?` * `string` Optional string corresponding to a [Plan](/docs/guides/billing/overview). *** * `permission?` * `string` Optional string corresponding to a [Permission](/docs/guides/organizations/roles-and-permissions) in the format `org::` *** * `role?` * `string` Optional string corresponding to a [Role](/docs/guides/organizations/roles-and-permissions) in the format `org:` *** * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: The component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/redirect-to-sign-up.mdx --- The `` component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'pages/index.tsx' }} import { SignedIn, SignedOut, RedirectToSignUp, UserButton } from '@clerk/clerk-react' export default function Page() { return ( <> ) } ``` --- title: "``" description: The component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-tasks lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,remix,go,astro,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/redirect-to-tasks.mdx --- The `` component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks**Session tasks** are requirements that users must fulfill in order to complete the authentication process, such as choosing an Organization.. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. The `` component is primarily intended for use in custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. If you're using prebuilt components, you typically won't need to use `` as these components manage task redirection internally. [See the guide on handling session tasks outside of prebuilt components](/docs/guides/configure/session-tasks#redirecting-to-tasks). ## Example ```tsx {{ filename: 'pages/index.tsx' }} import { SignedOut, RedirectToTasks } from '@clerk/clerk-react' export default function Page() { return ( <> ) } ``` --- title: "`` (deprecated)" description: The component will navigate to the user profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/redirect-to-user-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToUserProfile() method instead. The `` component will navigate to the Account Portal User Profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. To find your User Profile URL: 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Under **User profile**, select the **Visit** icon. ## Example ```tsx {{ filename: 'pages/index.tsx' }} import { SignedIn, SignedOut, RedirectToUserProfile } from '@clerk/clerk-react' export default function Page() { return ( <>

You need to sign in to view your user profile.

) } ```
--- title: "``" description: Conditionally render content only when a user is signed out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-out lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/signed-out.mdx --- The `` component offers authentication checks as a cross-cutting concern. Any child nodes wrapped by a `` component will be rendered only if there's no User signed in to your application. ## Example ```tsx {{ filename: 'routes/index.tsx' }} import { SignedOut } from '@clerk/clerk-react' export default function Page() { return ( <>

You are signed out.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: Conditionally render content only when a user is signed in. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/control/signed-in.mdx --- ## Overview The `` component offers authentication checks as a cross-cutting concern. Any children components wrapped by a `` component will be rendered only if there's a user with an active session signed in your application. > \[!CAUTION] > This component only **visually hides** its children when the current user is not authenticated. The contents of its children remain accessible via the browser's source code even if the user fails the authentication check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Example ```tsx {{ filename: 'routes/index.tsx' }} import { SignedIn } from '@clerk/clerk-react' export default function Page() { return ( <>
You are signed in.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` component" description: Clerk's component is used to render an Organization creation UI that allows users to create brand new Organizations within your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/organization/create-organization.mdx --- ![The \ component renders an Organization creation UI that allows users to create brand new organizations within your application.](/docs/images/ui-components/create-organization.png){{ style: { maxWidth: '492px' } }} The `` component is used to render an Organization creation UI that allows users to create brand new Organizations in your application. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'src/App.tsx' }} import { CreateOrganization } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterCreateOrganizationUrl` * `string` Full URL or path to navigate to after creating a new organization. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/create-organization`. *** * `skipInvitationScreen` * `boolean` Hides the screen for sending invitations after an Organization is created. When left undefined, Clerk will automatically hide the screen if the number of max allowed members is equal to 1 *** * `hideSlug` * `boolean` Hides the optional slug field in the Organization creation screen. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured Organization management UI that allows users to manage their Organization profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/organization/organization-profile.mdx --- ![The \ component allows users to manage their Organization membership and security settings.](/docs/images/ui-components/organization-profile.png) The `` component allows users to manage their Organization membership, security, and billing settings. This component's **General** tab displays the Organization's information and the **Leave organization** button. Admins will be able to see the **Update profile** button, **Verified domains** section, and **Delete organization** button. The **Members** tab shows the Organization's members along with their join dates and Roles. Admins will have the ability to invite a member, change a member's Role, or remove them from the Organization. Admins will have tabs within the **Members** tab to view the Organization's [invitations](/docs/guides/organizations/overview#organization-invitations) and [requests](/docs/guides/organizations/verified-domains#membership-requests). The **Billing** tab displays the Plans and Features that are available to the Organization, as well as the user's billing information, such as their invoices and payment methods. ## Example ```jsx {{ filename: 'src/App.tsx' }} import { OrganizationProfile } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after leaving an Organization. *** * `customPages` * `CustomPages[]` An array of custom pages to add to the Organization profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/organization-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash- and virtual-based routing.
For example: `/organization-profile`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages.
Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React.
## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages](/docs/guides/customizing-clerk/adding-items/organization-profile) documentation. --- title: "`` component" description: Clerk's component is used to display Organization related memberships, invitations, and suggestions for the user. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/organization/organization-list.mdx --- ![The \ component displays Organization-related memberships and automatic invitations and suggestions for the user.](/docs/images/ui-components/organization-list.png){{ style: { maxWidth: '460px' } }} The `` component displays Organization-related memberships and automatic [invitations](/docs/guides/organizations/verified-domains#automatic-invitations) and [suggestions](/docs/guides/organizations/verified-domains#automatic-suggestions) for the user. ## Example ```jsx {{ filename: 'src/App.tsx' }} import { OrganizationList } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after creating a new Organization. *** * `afterSelectOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting an Organization. Defaults to `undefined`. *** * `afterSelectPersonalUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting the [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts). Defaults to `undefined`. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. Defaults to `false`. *** * `skipInvitationScreen` * `boolean | undefined` A boolean that controls whether the screen for sending invitations after an Organization is created is hidden. When `undefined`, Clerk will automatically hide the screen if the number of max allowed members is equal to 1. Defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [org-ref]: /docs/reference/javascript/organization --- title: "`` component" description: Clerk's component is used to enable the ability to switch between available Organizations the user may be part of in your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-switcher lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/organization/organization-switcher.mdx --- ![The \ component allows a user to switch between their account types - their Personal Account and their joined Organizations.](/docs/images/ui-components/organization-switcher.png){{ style: { maxWidth: '436px' } }} The `` component allows a user to switch between their joined Organizations. If [Personal Accounts are enabled](/docs/guides/organizations/overview#allow-personal-accounts), users can also switch to their Personal Account. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple Organizations. It handles all Organization-related flows, including full Organization management for admins. Learn more about [Organizations](/docs/guides/organizations/overview). ## Example ```jsx {{ filename: 'src/App.tsx' }} import { OrganizationSwitcher } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * `string` The full URL or path to navigate to after creating a new Organization. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after the user leaves the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `afterSelectOrganizationUrl` * `string` The full URL or path to navigate to after a successful Organization switch. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `createOrganizationMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the "Create organization" button will cause the \ component to open as a modal, or if the browser will navigate to the `createOrganizationUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `createOrganizationUrl` * `string` The full URL or path where the ``]createorg-ref component is mounted. *** * `defaultOpen` * `boolean` A boolean that controls the default state of the `` component. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. *** * `organizationProfileMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the **Manage organization** button will cause the \ component to open as a modal, or if the browser will navigate to the `organizationProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `organizationProfileProps` * `object` Specify options for the underlying \ component. For example: `{appearance: {...}}` *** * `organizationProfileUrl` * `string` The full URL or path where the \ component is mounted. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [createorg-ref]: /docs/reference/components/organization/create-organization [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "``" description: The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. sdk: expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-with-metamask lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/unstyled/sign-in-with-metamask.mdx --- The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. ## Usage ### Basic usage ```jsx {{ filename: 'src/App.tsx' }} import { SignInWithMetamaskButton } from '@clerk/clerk-react' function App() { return } export default App ``` ### Custom usage In some cases, you will want to use your own button, or button text. You can do that by wrapping your button in the `` component. ```jsx {{ filename: 'src/App.tsx' }} import { SignInWithMetamaskButton } from '@clerk/clerk-react' function App() { return ( ) } export default App ``` --- title: "``" description: The `` component is a button that signs a user out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-out-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/unstyled/sign-out-button.mdx --- The `` component is a button that signs a user out. By default, it is a ` ) } export default App ``` ### Multi-session usage #### Sign out of all sessions Clicking the `` component signs the user out of all sessions. This is the default behavior. #### Sign out of a specific session You can sign out of a specific session by passing in a `sessionId` to the `sessionId` prop. This is useful for signing a single account out of a [multi-session application](/docs/guides/secure/session-options#multi-session-applications). In the following example, the `sessionId` is retrieved from the useAuth() hook. If the user is not signed in, the `sessionId` will be `null`, and the user is shown the \ component. If the user is signed in, the user is shown the `` component, which when clicked, signs the user out of that specific session. ```jsx {{ filename: 'src/App.tsx' }} import { SignInButton, SignOutButton, useAuth } from '@clerk/clerk-react' function App() { const { sessionId } = useAuth() if (!sessionId) { return } return } export default App ``` ## Properties * `redirectUrl?` * `string` The full URL or path to navigate after successful sign-out. *** * `sessionId?` * `string` The ID of a specific session to sign out of. Useful for [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. --- title: "``" description: The component is a button that links to the sign-up page or displays the sign-up modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-up-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/unstyled/sign-up-button.mdx --- The `` component is a button that, by default, links to your app's sign-up page. Your sign-up page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-up page. ## Usage ### Basic usage ```jsx {{ filename: 'src/App.tsx' }} import { SignUpButton } from '@clerk/clerk-react' function App() { return } export default App ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```jsx {{ filename: 'src/App.jsx' }} import { SignUpButton } from '@clerk/clerk-react' function App() { return ( ) } export default App ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-up route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'` *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). --- title: "``" description: The component is a button that links to the sign-in page or displays the sign-in modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/unstyled/sign-in-button.mdx --- The `` component is a button that, by default, links to your app's sign-in page. Your sign-in page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-in page. ## Usage ### Basic usage ```jsx {{ filename: 'src/App.tsx' }} import { SignInButton } from '@clerk/clerk-react' function App() { return } export default App ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```jsx {{ filename: 'src/App.tsx' }} import { SignInButton } from '@clerk/clerk-react' function App() { return ( ) } export default App ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-in route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'`. *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. --- title: "`` component" description: Clerk's component is used to render the familiar user button UI popularized by Google. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/user/user-button.mdx --- ![The \ component renders the familiar user button UI popularized by Google.](/docs/images/ui-components/user-button.png){{ style: { maxWidth: '436px' } }} The `` component renders the familiar user button UI popularized by Google. When selected, it opens a dropdown menu with options to manage account settings and sign out. The "Manage account" option launches the \ component, providing access to profile and security settings. For users that have [multi-session](/docs/guides/secure/session-options#multi-session-applications) enabled, the `` also allows users to sign into multiple accounts at once and instantly switch between them without the need for a full page reload. Learn more [here](/docs/guides/secure/session-options#multi-session-applications). ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar and be able to open the popup menu. ```tsx {{ filename: 'src/App.tsx' }} import { SignedIn, UserButton, SignInButton, SignedOut } from '@clerk/clerk-react' function App() { return (
) } export default App ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `afterMultiSessionSingleSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterMultiSessionSingleSignOutUrl` to \.** The full URL or path to navigate to after signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterSignOutUrl` to \.** The full URL or path to navigate to after a successful sign-out. *** * `afterSwitchSessionUrl` * `string` The full URL or path to navigate to after a successful account change in a multi-session app. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `defaultOpen` * `boolean` Controls whether the `` should open by default during the first render. *** * `showName` * `boolean` Controls if the user name is displayed next to the user image button. *** * `signInUrl` * `string` The full URL or path to navigate to when the **Add another account** button is clicked. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `userProfileMode` * `'modal' | 'navigation'` Controls whether selecting the **Manage your account** button will cause the \ component to open as a modal, or if the browser will navigate to the `userProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `userProfileProps` * `object` Specify options for the underlying \ component. For example: `{additionalOAuthScopes: {google: ['foo', 'bar'], github: ['qux']}}`. *** * `userProfileUrl` * `string` The full URL or path leading to the user management interface. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). You can also [add custom actions and links to the `` menu](/docs/guides/customizing-clerk/adding-items/user-button). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/user/user-profile.mdx --- ![The \ component renders a full-featured account management UI that allows users to manage their profile and security settings.](/docs/images/ui-components/user-profile.png){{ style: { maxWidth: '100%' } }} The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile, security, and billing settings. ## Example ```jsx {{ filename: 'src/App.tsx' }} import { UserProfile } from '@clerk/clerk-react' function App() { return } export default App ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/user-profile`. *** * `additionalOAuthScopes` * `object` Specify additional scopes per OAuth provider that your users would like to provide if not already approved. For example: `{google: ['foo', 'bar'], github: ['qux']}`. *** * `customPages` * CustomPage\[] An array of custom pages to add to the user profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/user-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages documentation](/docs/guides/customizing-clerk/adding-items/user-profile). --- title: "`` component" description: Clerk's component is used to render the familiar user avatar on its own. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-avatar lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: react sourceFile: /docs/reference/components/user/user-avatar.mdx --- ![The \ component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications.](/docs/images/ui-components/user-avatar.png) The `` component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications. ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar. ```tsx {{ filename: 'src/App.tsx' }} import { SignedIn, UserAvatar, SignInButton, SignedOut } from '@clerk/clerk-react' function App() { return (
) } export default App ```
## Properties The `` component accepts the following properties, all of which are **optional**: * `rounded?` * `boolean` Determines whether the user avatar is displayed with rounded corners. *** * `appearance?` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` Optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`useCheckout()`" description: Clerk's useCheckout() hook provides state and methods to manage a Subscription checkout flow. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-checkout lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-checkout.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `useCheckout()` hook is used to create, manage, and confirm a checkout session for a user or an Organization's Subscription Plan. It provides the state of the current checkout process, such as its status and any errors, along with methods to initiate and complete the checkout. There are two ways to use `useCheckout()`: 1. In conjunction with \ to create a shared checkout context. All child components inside the provider can then use `useCheckout()` to access or update the same checkout state. 2. On its own by passing configuration options directly to it. This is ideal for self-contained components that handle their own checkout flow without needing a shared context. ## Parameters | Parameter | Type | Description | | ---------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `options?` | `PropsWithChildren`\<`UseCheckoutOptions`\> | An object containing the configuration for the checkout flow. **Required** if the hook is used without a `` wrapping the component tree. | ### `UseCheckoutOptions` | Property | Type | Description | | ------------------------------------ | ------------------------------------- | ----------------------------------------------------------------------- | |
`for?` | "user" \| "organization" | Specifies if the checkout is for an organization. Defaults to `'user'`. | | `planId` | `string` | The ID of the subscription plan to check out (e.g. `cplan_xxx`). | | `planPeriod` | "month" \| "annual" | The billing period for the plan. | ## Returns `useCheckout()` returns a `{ checkout }` object. The `checkout` object contains the following properties. They are `null` until the checkout process is started by calling the `start()` method. | Property | Type | Description | | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `clear` | () => void | A function that clears the current checkout state from the cache. | | `confirm` | (params: ConfirmCheckoutParams) => Promise\<\{ data: BillingCheckoutResource; error: null; \} \| \{ data: null; error: ClerkAPIResponseError; \}\> | A function that confirms and finalizes the checkout process, usually after the user has provided and validated payment information. | | `error` | null \| ClerkAPIResponseError | Returns an error object if any part of the checkout process fails. | | `externalClientSecret` | null \| string | A client secret from an external payment provider (such as Stripe) used to complete the payment on the client-side. | | `externalGatewayId` | null \| string | The identifier for the external payment gateway used for this checkout session. | | `fetchStatus` | "error" \| "idle" \| "fetching" | The data fetching status. | | `finalize` | (params?: \{ navigate?: SetActiveNavigate; \}) => void | A function that finalizes the checkout process. Can optionally accept a `navigate()` function to redirect the user after completion. | | `freeTrialEndsAt?` | null \| Date | Unix timestamp (milliseconds) of when the free trial ends. | | `id` | null \| string | The unique identifier for the checkout session. | | `isConfirming` | `boolean` | A boolean that indicates if the `confirm()` method is in progress. | | `isImmediatePlanChange` | null \| boolean | Whether the plan change will take effect immediately after checkout. | | `isStarting` | `boolean` | A boolean that indicates if the `start()` method is in progress. | | `needsPaymentMethod` | null \| boolean | Whether a payment method is required for this checkout. | | `payer` | null \| BillingPayerResource | The payer associated with the checkout. | | `paymentMethod?` | null \| BillingPaymentMethodResource | The payment method being used for the checkout, such as a credit card or bank account. | | `plan` | null \| BillingPlanResource | The subscription plan details for the checkout. | | `planPeriod` | null \| "month" \| "annual" | The billing period for the plan. | | `planPeriodStart?` | null \| number | The start date of the plan period, represented as a Unix timestamp. | | `start` | () => Promise\<\{ data: BillingCheckoutResource; error: null; \} \| \{ data: null; error: ClerkAPIResponseError; \}\> | A function that initializes the checkout process by creating a checkout resource on the server. | | `status` | "needs\_confirmation" \| "completed" \| "needs\_initialization" | The current status of the checkout session. The following statuses are possible:
  • `needs_initialization`: The checkout hasn't started but the hook is mounted. Call `start()` to continue.
  • `needs_confirmation`: The checkout has been initialized and is awaiting confirmation. Call `confirm()` to continue.
  • `completed`: The checkout has been successfully confirmed. Call `finalize()` to complete the checkout.
| |
`totals` | null \| BillingCheckoutTotals | The total costs, taxes, and other pricing details for the checkout. | ## `` The `` component is a wrapper that provides a checkout context to its children, allowing checkout state to be shared across multiple components. Child components can access the checkout context by calling `useCheckout()`. ### Properties The `` component accepts the following props: | Property | Type | Description | | ------------------------------------ | ------------------------------------- | ----------------------------------------------------------------------- | | `for?` | "user" \| "organization" | Specifies if the checkout is for an organization. Defaults to `'user'`. | | `planId` | `string` | The ID of the subscription plan to check out (e.g. `cplan_xxx`). | | `planPeriod` | "month" \| "annual" | The billing period for the plan. | ## Usage For the best user experience and to prevent potential errors, always wrap components using `useCheckout()` with both `` and `` components. This ensures that the user is properly authenticated and Clerk is fully initialized before accessing checkout functionality. ```tsx function CheckoutPage() { return ( ) } ``` ### Examples The `useCheckout()` hook can be used with a context provider for managing state across multiple components or as a standalone hook for more isolated use cases. ", "Standalone Hook"]}> The following example shows the basic structure for a checkout flow. A parent component, ``, sets up the `` and renders the checkout flow. A child component, ``, uses the `useCheckout()` hook to access the checkout state. ", ""]}> ```tsx {{ filename: 'src/components/SubscriptionPage.tsx', collapsible: true }} import { CheckoutProvider } from '@clerk/clerk-react/experimental' import { ClerkLoaded } from '@clerk/clerk-react' import { CheckoutFlow } from './CheckoutFlow' export default function SubscriptionPage() { // `` sets the context for the checkout flow. // Any child component can now call `useCheckout()` to access this context. return (

Upgrade Your Plan

You are about to subscribe to our monthly plan

) } ```
```tsx {{ filename: 'src/components/CheckoutFlow.tsx', collapsible: true }} import { useCheckout } from '@clerk/clerk-react/experimental' import { useState } from 'react' import { useNavigate } from 'react-router-dom' export function CheckoutFlow() { const { checkout } = useCheckout() const { status } = checkout if (status === 'needs_initialization') { return } return (
) } function CheckoutInitialization() { const { checkout } = useCheckout() const { start, fetchStatus } = checkout return ( ) } function PaymentSection() { const { checkout } = useCheckout() const { isConfirming, confirm, finalize, error } = checkout const [isProcessing, setIsProcessing] = useState(false) const [paymentMethodId, setPaymentMethodId] = useState(null) const navigate = useNavigate() const submitSelectedMethod = async () => { if (isProcessing || !paymentMethodId) return setIsProcessing(true) try { // Confirm checkout with payment method await confirm({ paymentSourceId: paymentMethodId, }) // Calling `.finalize` enables you to sync the client-side state with the server-side state of your users. // It revalidates all authorization checks computed within server components. await finalize({ navigate: () => navigate('/dashboard'), }) } catch (error) { console.error('Payment failed:', error) } finally { setIsProcessing(false) } } return ( <> {/* A component that lists a user's payment methods and allows them to select one. See an example: https://clerk.com/docs/reference/hooks/use-payment-methods#examples */} {error &&
{error.message}
} ) } function CheckoutSummary() { const { checkout } = useCheckout() const { plan, totals } = checkout return (

Order Summary

{plan?.name} {totals?.totalDueNow.currencySymbol} {totals?.totalDueNow.amountFormatted}
) } ```
For simple, self-contained components, you can use `useCheckout()` by passing the configuration options directly to the hook. This avoids the need to wrap the component in a provider. The following example shows an `` component that manages its own checkout flow. ```tsx {{ filename: 'src/components/UpgradeButton.tsx' }} import { useCheckout } from '@clerk/clerk-react/experimental' export function UpgradeButton({ planId, planPeriod, }: { planId: string planPeriod: 'month' | 'annual' }) { // Pass options directly to the hook when not using a provider. const { checkout } = useCheckout({ planId, planPeriod, for: 'user', }) const { start, status, isStarting, error } = checkout const handleStartCheckout = async () => { try { await start() // In a real app, you would now use the `externalClientSecret` // from the checkout object to render a payment form. console.log('Checkout started! Status:', checkout.status) } catch (e) { console.error('Error starting checkout:', e) } } return (
{error &&

Error: {error.errors[0].message}

}
) } ```
## Related guides * [Checkout flow with a new payment method](/docs/guides/development/custom-flows/billing/checkout-new-payment-method) * Prompt users to add a new payment method during checkout *** * [Checkout flow for returning users](/docs/guides/development/custom-flows/billing/checkout-existing-payment-method) * Prompt users to select an existing payment method during checkout --- title: "`useOrganizationList()`" description: Access and manage the current user's Organization list in your React application with Clerk's useOrganizationList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-organization-list.mdx --- The `useOrganizationList()` hook provides access to the current user's Organization memberships, invitations, and suggestions. It also includes methods for creating new Organizations and managing the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganizationList()` accepts a single object with the following properties: | Property | Type | Description | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`userInvitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`userMemberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & object & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • Any of the properties described in Shared properties.
| |
`userSuggestions?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "pending" \| "accepted" \| ("pending" \| "accepted")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the suggestions by the provided status.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `userMemberships`, `userInvitations`, and `userSuggestions` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | ## Returns | Property | Type | Description | | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createOrganization` | undefined \| (CreateOrganizationParams: CreateOrganizationParams) => Promise\<OrganizationResource\> | A function that returns a `Promise` which resolves to the newly created `Organization`. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization and there is an authenticated user. Initially `false`, becomes `true` once Clerk loads with a user. | | `setActive` | undefined \| (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. | | `userInvitations` | PaginatedResourcesWithDefault\<UserOrganizationInvitationResource\> \| PaginatedResources\<UserOrganizationInvitationResource, T\["userInvitations"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization invitations. | | `userMemberships` | PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["userMemberships"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization memberships. | | `userSuggestions` | PaginatedResourcesWithDefault\<OrganizationSuggestionResource\> \| PaginatedResources\<OrganizationSuggestionResource, T\["userSuggestions"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of suggestions for organizations that the user can join. | ### `CreateOrganizationParams` | Property | Type | Description | | ------------------------- | -------- | ----------------------------- | | `name` | `string` | The name of the organization. | | `slug?` | `string` | The slug of the organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expanding and paginating attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. So by default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // userMemberships.data will never be populated const { userMemberships } = useOrganizationList() // Use default values to fetch userMemberships, such as initialPage = 1 and pageSize = 10 const { userMemberships } = useOrganizationList({ userMemberships: true, }) // Pass your own values to fetch userMemberships const { userMemberships } = useOrganizationList({ userMemberships: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `userMemberships` attribute will be populated with the first page of the user's Organization memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```tsx {{ filename: 'src/components/JoinedOrganizations.tsx' }} import { useOrganizationList } from '@clerk/clerk-react' import React from 'react' const JoinedOrganizations = () => { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) // Handle loading state if (!isLoaded) return
Loading...
return ( <>
    {userMemberships.data?.map((mem) => (
  • {mem.organization.name}
  • ))}
) } export default JoinedOrganizations ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `userInvitations` attribute will be populated with the first page of invitations. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of invitations. Notice the difference between this example's pagination and the infinite pagination example above. ```tsx {{ filename: 'src/components/UserInvitationsTable.tsx' }} import { useOrganizationList } from '@clerk/clerk-react' import React from 'react' const UserInvitationsTable = () => { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { infinite: true, keepPreviousData: true, }, }) // Handle loading state if (!isLoaded || userInvitations.isLoading) return
Loading...
return ( <> {userInvitations.data?.map((inv) => ( ))}
Email Org name
{inv.emailAddress} {inv.publicOrganizationData.name}
) } export default UserInvitationsTable ```
## Related guides * [Build a custom Organization switcher](/docs/guides/development/custom-flows/organizations/organization-switcher) * Use Clerk's API to build a custom flow for switching between Organizations *** * [Create Organizations](/docs/guides/development/custom-flows/organizations/create-organizations) * Use Clerk's API to build a custom flow for creating Organizations *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: useAuth() description: Access and manage authentication state in your application with Clerk's useAuth() hook. sdk: astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-auth.mdx --- The `useAuth()` hook provides access to the current user's authentication state and methods to manage the active session. > \[!NOTE] > To access auth data server-side, see the Auth object reference doc. ## Parameters | Parameter | Type | Description | | ---------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `initialAuthStateOrOptions?` | null \| Record\ \| \{ treatPendingAsSignedOut?: boolean; \} | An object containing the initial authentication state or options for the `useAuth()` hook. If not provided, the hook will attempt to derive the state from the context. `treatPendingAsSignedOut` is a boolean that indicates whether pending sessions are considered as signed out or not. Defaults to `true`. | ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `undefined` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has` | `undefined` | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `undefined` | The ID of the user's active organization. | | `orgRole` | `undefined` | The current user's role in their active organization. | | `orgSlug` | `undefined` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `undefined` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `undefined` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `undefined` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `null` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (params: CheckAuthorizationParamsWithCustomPermissions) => false | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `null` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `null` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `null` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `string` | The ID of the user's active organization. | | `orgRole` | `string` | The current user's role in their active organization. | | `orgSlug` | null \| string | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | ## Example The following example demonstrates how to use the `useAuth()` hook to access the current auth state, like whether the user is signed in or not. It also includes a basic example for using the `getToken()` method to retrieve a session token for fetching data from an external resource. ```tsx {{ filename: 'src/pages/ExternalDataPage.tsx' }} import { useAuth } from '@clerk/clerk-react' export default function ExternalDataPage() { const { userId, sessionId, getToken, isLoaded, isSignedIn } = useAuth() const fetchExternalData = async () => { const token = await getToken() // Fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

Hello, {userId}! Your current active session is {sessionId}.

) } ```
--- title: useClerk() description: Access and manage the Clerk object in your React application with Clerk's useClerk() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-clerk lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-clerk.mdx --- > \[!WARNING] > This hook should only be used for advanced use cases, such as building a completely custom OAuth flow or as an escape hatch to access to the `Clerk` object. The `useClerk()` hook provides access to the Clerk object, allowing you to build alternatives to any Clerk Component. ## Returns Clerk — The `useClerk()` hook returns the `Clerk` object, which includes all the methods and properties listed in the Clerk reference. ## Example The following example uses the `useClerk()` hook to access the `clerk` object. The `clerk` object is used to call the openSignIn() method to open the sign-in modal. ```tsx {{ filename: 'src/pages/Example.tsx' }} import { useClerk } from '@clerk/clerk-react' export default function Example() { const clerk = useClerk() return } ``` --- title: Hooks Reference description: A list of Clerk's comprehensive suite of hooks for managing authentication, sessions, sign-in and sign-up flows, Organizations, and reverification. sdk: astro, chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/overview.mdx --- Clerk offers a comprehensive suite of hooks that expose low-level access to authentication, session management, and multi-tenancy. With Clerk hooks, you can access and manage user data, handle sign-in and sign-up flows, control session management, and implement advanced flows like session reverification for sensitive actions. By using these hooks, you can extend or replace Clerk's built-in components and customize how authentication behaves in your application. ## Hooks * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: useOrganization() description: Access and manage the currently active Organization in your React application with Clerk's useOrganization() hook. search: rank: 1 sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-organization.mdx --- The `useOrganization()` hook retrieves attributes of the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganization()` accepts a single object with the following optional properties: | Property | Type | Description | | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`domains?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ enrollmentMode?: "manual\_invitation" \| "automatic\_invitation" \| "automatic\_suggestion"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `enrollmentMode`: A string that filters the domains by the provided [enrollment mode](/docs/guides/organizations/verified-domains#enrollment-mode).
  • Any of the properties described in Shared properties.
| |
`invitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: ("expired" \| "pending" \| "accepted" \| "revoked")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`membershipRequests?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the membership requests by the provided status.
  • Any of the properties described in Shared properties.
| |
`memberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ query?: string; role?: string\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `role`: An array of OrganizationCustomRoleKey.
  • `query`: A string that filters the memberships by the provided string.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes aren't populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `invitations`, `membershipRequests`, `memberships`, and `domains` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | > \[!NOTE] > These attributes are updating automatically and will re-render their respective components whenever you set a different Organization using the setActive(\{ organization }) method or update any of the memberships or invitations. No need for you to manage updating anything manually. ## Returns | Property | Type | Description | | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `domains` | null \| PaginatedResourcesWithDefault\<OrganizationDomainResource\> \| PaginatedResources\<OrganizationDomainResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's domains. | | `invitations` | null \| PaginatedResourcesWithDefault\<OrganizationInvitationResource\> \| PaginatedResources\<OrganizationInvitationResource, T\["invitations"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's invitations. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `membership` | undefined \| null \| OrganizationMembershipResource | The current organization membership. | | `membershipRequests` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipRequestResource\> \| PaginatedResources\<OrganizationMembershipRequestResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's membership requests. | | `memberships` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["memberships"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's memberships. | | `organization` | undefined \| null \| OrganizationResource | The currently active organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expand and paginate attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // invitations.data will never be populated. const { invitations } = useOrganization() // Use default values to fetch invitations, such as initialPage = 1 and pageSize = 10 const { invitations } = useOrganization({ invitations: true, }) // Pass your own values to fetch invitations const { invitations } = useOrganization({ invitations: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { invitations } = useOrganization({ invitations: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```jsx {{ filename: 'src/components/MemberList.tsx' }} import { useOrganization } from '@clerk/clerk-react' export default function MemberList() { const { memberships } = useOrganization({ memberships: { infinite: true, // Append new data to the existing list keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of memberships. Notice the difference between this example's pagination and the infinite pagination example above. ```jsx {{ filename: 'src/components/MemberList.tsx' }} import { useOrganization } from '@clerk/clerk-react' export default function MemberList() { const { memberships } = useOrganization({ memberships: { keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
## Related guides * [Update an Organization](/docs/guides/development/custom-flows/organizations/update-organizations) * Use Clerk's API to build a custom flow for updating an Organization *** * [Manage Roles in an Organization](/docs/guides/development/custom-flows/organizations/manage-roles) * Use Clerk's API to build a custom flow for managing Roles in an Organization *** * [Manage an Organization's membership requests](/docs/guides/development/custom-flows/organizations/manage-membership-requests) * Use Clerk's API to build a custom flow for managing an Organization's membership requests *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: "`usePaymentAttempts()`" description: Access and manage payment attempts in your React application with Clerk's usePaymentAttempts() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-payment-attempts lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-payment-attempts.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `usePaymentAttempts()` hook provides access to the payment attempts associated with a user or Organization. It returns a paginated list of payment attempts and includes methods for managing them. ## Parameters `usePaymentAttempts()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | ## Returns `usePaymentAttempts()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | BillingPaymentResource\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `CacheSetter`\<undefined \| ClerkPaginatedResponse\<BillingPaymentResource\>\> | A function that allows you to set the data manually. | ## Examples ### Basic usage The following example demonstrates how to fetch and display a user's payment attempts. ```tsx {{ filename: 'src/pages/billing/PaymentAttemptsList.tsx' }} import { usePaymentAttempts } from '@clerk/clerk-react/experimental' export default function PaymentAttemptsList() { const { data, isLoading } = usePaymentAttempts({ for: 'user', pageSize: 10, }) if (isLoading) { return
Loading payment attempts...
} if (!data || data.length === 0) { return
No payment attempts found.
} return (
    {data?.map((attempt) => (
  • Payment #{attempt.id} - {attempt.status}
    Amount: {attempt.amount.amountFormatted} on {new Date(attempt.updatedAt).toLocaleString()}
  • ))}
) } ```
### Infinite pagination The following example demonstrates how to implement infinite scrolling with payment attempts. ```tsx {{ filename: 'src/pages/billing/PaymentAttemptsList.tsx' }} import { usePaymentAttempts } from '@clerk/clerk-react/experimental' export default function InfinitePaymentAttempts() { const { data, isLoading, hasNextPage, fetchNext } = usePaymentAttempts({ for: 'user', infinite: true, pageSize: 20, }) if (isLoading) { return
Loading...
} if (!data || data.length === 0) { return
No payment attempts found.
} return (
    {data?.map((attempt) => (
  • Payment attempt for {attempt.amount.amountFormatted}
    Status: {attempt.status}
    {attempt.status === 'failed' && attempt.failedAt && ( Failed At: {new Date(attempt.failedAt).toLocaleString()} )}
  • ))}
{hasNextPage && }
) } ```
### Payment attempts history table The following example demonstrates how to use `usePaymentAttempts()` to display a detailed payment history table. ```tsx {{ filename: 'src/pages/billing/PaymentAttemptsHistory.tsx', collapsible: true }} import { usePaymentAttempts } from '@clerk/clerk-react/experimental' export default function PaymentAttemptsHistory() { const { data, isLoading } = usePaymentAttempts({ for: 'user' }) if (isLoading) { return
Loading payment attempts...
} if (!data || data.length === 0) { return
No payment attempts found.
} const getStatusColor = (status: string) => { switch (status) { case 'paid': return 'green' case 'failed': return 'red' case 'pending': return 'orange' default: return 'gray' } } return ( {data?.map((attempt) => ( ))}
Payment ID Amount Status Date Payment Method
{attempt.id} {attempt.amount.amountFormatted} {attempt.status} {attempt.paidAt ? new Date(attempt.paidAt).toLocaleDateString() : '-'} {attempt.paymentSource.cardType} ****{attempt.paymentSource.last4}
) } ```
--- title: "`usePlans()`" description: Access Plans in your React application with Clerk's usePlans() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-plans lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-plans.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `usePlans()` hook provides access to the Subscription Plans available in your application. It returns a paginated list of Plans and includes methods for managing them. ## Parameters `usePlans()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | ## Returns `usePlans()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | BillingPlanResource\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `CacheSetter`\<undefined \| ClerkPaginatedResponse\<BillingPlanResource\>\> | A function that allows you to set the data manually. | ## Examples ### Basic usage The following example shows how to fetch and display available Plans. ```tsx {{ filename: 'src/pages/billing/PlansList.tsx' }} import { usePlans } from '@clerk/clerk-react/experimental' export default function PlansList() { const { data, isLoading, hasNextPage, fetchNext, hasPreviousPage, fetchPrevious } = usePlans({ for: 'user', pageSize: 10, }) if (isLoading) { return
Loading plans...
} return (
    {data?.map((plan) => (
  • {plan.name}

    {plan.description}

    Is free plan: {!plan.hasBaseFee ? 'Yes' : 'No'}

    Price per month: {plan.currency} {plan.amountFormatted}

    Price per year: {plan.currency} {plan.annualAmountFormatted} equivalent to{' '} {plan.currency} {plan.annualMonthlyAmountFormatted} per month

    Features:

      {plan.features.map((feature) => (
    • {feature.name}
    • ))}
  • ))} {hasNextPage && } {hasPreviousPage && }
) } ```
### Infinite pagination The following example demonstrates how to implement infinite scrolling with Plans. ```tsx {{ filename: 'src/pages/billing/PlansList.tsx' }} import { usePlans } from '@clerk/clerk-react/experimental' export default function InfinitePlansList() { const { data, isLoading, hasNextPage, fetchNext } = usePlans({ for: 'user', infinite: true, pageSize: 2, }) if (isLoading) { return
Loading plans...
} return (
    {data?.map((plan) => (
  • {plan.name}

    {plan.description}

    Is free plan: {!plan.hasBaseFee ? 'Yes' : 'No'}

    Price per month: {plan.currency} {plan.amountFormatted}

    Price per year: {plan.currency} {plan.annualAmountFormatted} equivalent to{' '} {plan.currency} {plan.annualMonthlyAmountFormatted} per month

    Features:

      {plan.features.map((feature) => (
    • {feature.name}
    • ))}
  • ))}
{hasNextPage && }
) } ```
## Related guides * [Checkout flow with a new payment method](/docs/guides/development/custom-flows/billing/checkout-new-payment-method) * Prompt users to add a new payment method during checkout *** * [Checkout flow for returning users](/docs/guides/development/custom-flows/billing/checkout-existing-payment-method) * Prompt users to select an existing payment method during checkout --- title: "`usePaymentMethods()`" description: Access and manage payment methods in your React application with Clerk's usePaymentMethods() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-payment-methods lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-payment-methods.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `usePaymentMethods()` hook provides access to the payment methods associated with a user or Organization. It returns a paginated list of payment methods and includes methods for managing them. ## Parameters `usePaymentMethods()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | ## Returns `usePaymentMethods()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | BillingPaymentMethodResource\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `CacheSetter`\<undefined \| ClerkPaginatedResponse\<BillingPaymentMethodResource\>\> | A function that allows you to set the data manually. | ## Examples ### Basic usage The following example demonstrates how to fetch and display a user's payment methods. ```tsx {{ filename: 'src/pages/billing/PaymentMethodsList.tsx' }} import { usePaymentMethods } from '@clerk/clerk-react/experimental' export default function PaymentMethodsList() { const { data, isLoading } = usePaymentMethods({ for: 'user', pageSize: 10, }) if (isLoading) { return
Loading payment methods...
} if (!data || data.length === 0) { // Code for how to add a new payment method: https://clerk.com/docs/guides/development/custom-flows/billing/add-new-payment-method return
No payment methods found. Please add a payment method to your account.
} return (
    {data?.map((method) => (
  • {method.cardType} **** {method.last4} {method.isDefault ? ' (Default)' : null}
  • ))}
) } ```
### Infinite pagination The following example demonstrates how to implement infinite scrolling with payment methods. ```tsx {{ filename: 'src/pages/billing/PaymentMethodsList.tsx' }} import { usePaymentMethods } from '@clerk/clerk-react/experimental' export default function InfinitePaymentMethods() { const { data, isLoading, hasNextPage, fetchNext } = usePaymentMethods({ for: 'user', infinite: true, pageSize: 20, }) if (isLoading) { return
Loading...
} if (!data || data.length === 0) { // Code for how to add a new payment method: https://clerk.com/docs/guides/development/custom-flows/billing/add-new-payment-method return
No payment methods found. Please add a payment method to your account.
} return (
    {data?.map((method) => (
  • {method.cardType} ending in {method.last4} {method.status === 'expired' ? ' (Expired)' : null} {method.status === 'disconnected' ? ' (Disconnected)' : null}
  • ))}
{hasNextPage && }
) } ```
### With checkout flow The following example demonstrates how to use `usePaymentMethods()` in a checkout flow to select an existing payment method. For more information on how to build a checkout flow with an existing payment method, see [Build a custom checkout flow](/docs/guides/development/custom-flows/billing/checkout-new-payment-method). ```tsx {{ filename: 'src/pages/billing/CheckoutPaymentSelection.tsx' }} import { usePaymentMethods, useCheckout } from '@clerk/clerk-react/experimental' import { useNavigate } from 'react-router-dom' export default function CheckoutPaymentSelection() { const { data, isLoading } = usePaymentMethods({ for: 'user' }) const { checkout } = useCheckout() const { confirm, finalize } = checkout const navigate = useNavigate() const handlePaymentSubmit = async (paymentMethodId: string) => { try { // Confirm checkout with selected payment method await confirm({ paymentSourceId: paymentMethodId }) // Complete checkout and redirect await finalize({ navigate: () => navigate('/dashboard'), }) } catch (error) { console.error('Payment failed:', error) } } if (isLoading) { return
Loading payment methods...
} if (!data || data.length === 0) { // Code for how to add a new payment method: https://clerk.com/docs/guides/development/custom-flows/billing/checkout-new-payment-method return
No payment methods found. Please add a payment method to your account.
} return (

Select a payment method

{data?.map((method) => ( ))}
) } ```
## Related guides * [Add a new payment method during checkout](/docs/guides/development/custom-flows/billing/checkout-new-payment-method) * Build a custom checkout flow that allows users to add a new payment method during checkout *** * [Add a new payment method outside of a checkout flow](/docs/guides/development/custom-flows/billing/add-new-payment-method) * Build a custom user interface that allows users to add a new payment method to their account --- title: "`usePaymentElement()`" description: Clerk's usePaymentElement() hook provides methods and state for interacting with a payment form. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-payment-element lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-payment-element.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `usePaymentElement()` hook is used to control the payment form rendered by the \ component. It provides the necessary state and methods to submit payment details to a payment provider like Stripe. This hook must be used within a component that is a descendant of the `` component. It is typically used in a checkout flow that prompts a user to add a new payment method, or for adding a new payment method outside of a checkout. ## Parameters `usePaymentElement()` doesn't accept any parameters. It derives its state and configuration from the nearest \. ## Returns `usePaymentElement()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`isFormReady` | `boolean` | A boolean that indicates if the payment form UI has been rendered and is ready for user input. This is useful for disabling a submit button until the form is interactive. | | `isProviderReady` | `boolean` | A boolean that indicates if the underlying payment provider (e.g. Stripe) has been fully initialized. | | `provider` | undefined \| \{ name: "stripe"; \} | An object containing information about the initialized payment provider. It is `undefined` until `isProviderReady` is `true`. | | `reset` | () => Promise\ | A function that resets the payment form to its initial, empty state. | | `submit` | () => Promise\<\{ data: \{ gateway: "stripe"; paymentToken: string; \}; error: null; \} \| \{ data: null; error: PaymentElementError; \}\> | A function that submits the payment form data to the payment provider. It returns a promise that resolves with either a `data` object containing a payment token on success, or an `error` object on failure. | ## Payment element components The `usePaymentElement()` hook works in conjunction with the `` and `` components. ### `` The `` component sets up the context for the payment element. It fetches all the necessary data from the payment provider (e.g., Stripe) and makes it available to its children. #### Properties | Property | Type | Description | | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `checkout?` | BillingCheckoutResource \| UseCheckoutReturn | An optional checkout resource object. When provided, the payment element is scoped to the specific checkout session. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `paymentDescription?` | `string` | An optional description to display to the user within the payment element UI. | | `stripeAppearance?` | `internalStripeAppearance` | An optional object to customize the appearance of the Stripe Payment Element. This allows you to match the form's styling to your application's theme. | ### `` This component renders the actual payment form from the provider (e.g., the Stripe Payment Element). It should be rendered as a child of ``. #### Properties | Property | Type | Description | | --------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------- | | `fallback?` | `ReactNode` | Optional fallback content, such as a loading skeleton, to display while the payment form is being initialized. | ## Example The following example demonstrates how to create a billing page where a user can add a new payment method. It is split into two components: * **``**: Sets up the ``, which specifies that the payment actions within its children are `for` the `user`. * **``**: Renders the payment form and handles the submission logic. It uses `usePaymentElement()` to get the `submit` function and `useUser()` to get the `user` object. When the form is submitted, it first creates a payment token and then attaches it to the user. ", ""]}> ```tsx {{ filename: 'src/pages/user/billing/page.tsx' }} import { ClerkLoaded } from '@clerk/clerk-react' import { PaymentElementProvider } from '@clerk/clerk-react/experimental' import { AddPaymentMethodForm } from './AddPaymentMethodForm' export default function Page() { return (

Billing Settings

) } ``` ```tsx {{ filename: 'src/pages/user/billing/AddPaymentMethodForm.tsx', collapsible: true }} import { useUser } from '@clerk/clerk-react' import { usePaymentElement, PaymentElement } from '@clerk/clerk-react/experimental' import { useState } from 'react' export function AddPaymentMethodForm() { const { user } = useUser() const { submit, isFormReady } = usePaymentElement() const [isSubmitting, setIsSubmitting] = useState(false) const [error, setError] = useState(null) const handleAddPaymentMethod = async (e: React.FormEvent) => { e.preventDefault() if (!isFormReady || !user) { return } setError(null) setIsSubmitting(true) try { // 1. Submit the form to the payment provider to get a payment token const { data, error } = await submit() // Usually a validation error from stripe that you can ignore. if (error) { setIsSubmitting(false) return } // 2. Use the token to add the payment source to the user await user.addPaymentSource(data) // 3. Handle success (e.g., show a confirmation, clear the form) alert('Payment method added successfully!') } catch (err: any) { setError(err.message || 'An unexpected error occurred.') } finally { setIsSubmitting(false) } } return (

Add a new payment method

{error &&

{error}

} ) } ```
## Related guides * [Use PaymentElement in a checkout flow](/docs/guides/development/custom-flows/billing/checkout-new-payment-method) * Add a new payment method during checkout *** * [Use PaymentElement outside of a checkout flow](/docs/guides/development/custom-flows/billing/add-new-payment-method) * Add a new payment method outside of a checkout flow --- title: useReverification() description: Clerk's useReverification() hook enhances a fetcher function to handle a session's reverification flow. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-reverification lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-reverification.mdx --- > \[!WARNING] > > Depending on the SDK you're using, this feature requires `@clerk/nextjs@6.12.7` or later, `@clerk/clerk-react@5.25.1` or later, `@clerk/clerk-js@5.57.1` or later and `@clerk/clerk-sdk-ruby@3.3.0` or later. Reverification allows you to prompt a user to verify their credentials before performing sensitive actions, even if they're already authenticated. For example, in a banking application, transferring money is considered a "sensitive action." Reverification can be used to confirm the user's identity. The `useReverification()` hook is used to handle a session's reverification flow. If a request requires reverification, a modal will display, prompting the user to verify their credentials. Upon successful verification, the original request will automatically retry. If you'd like to build a custom UI, you can use the onNeedsReverification option. When using reverification, a user's credentials are valid for 10 minutes. Once stale, a user will need to reverify their credentials. This time duration can be customized by using the `has()` helper on the server-side. See the [guide on reverification](/docs/guides/secure/reverification) for more information. ## Parameters | Parameter | Type | Description | | ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `fetcher` | `Fetcher extends (...args: any[]) => Promise` | A function that returns a promise. | | `options?` | `Options` | Optional configuration object extending UseReverificationOptions. | ### `UseReverificationOptions` The optional options object. | Property | Type | Description | | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | |
`onNeedsReverification?` | (properties: NeedsReverificationParameters) => void | Handler for the reverification process. Opts out of using the default UI. Use this to build a custom UI. | ### `NeedsReverificationParameters` | Property | Type | Description | | -------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `cancel` | () => void | Marks the reverification process as cancelled and rejects the original request. | | `complete` | () => void | Marks the reverification process as complete and retries the original request. | | `level` | undefined \| "first\_factor" \| "second\_factor" \| "multi\_factor" | The verification level required for the reverification process. | ## Examples The `useReverification()` hook displays a prebuilt UI when the user needs to reverify their credentials. You can also build a custom UI to handle the reverification process yourself. Use the following tabs to see examples of either option. ### Handle reverification for an action The following example demonstrates how to use the `useReverification()` hook to require a user to reverify their credentials before being able to update their primary email address. It also demonstrates how to handle the cancellation of the reverification process. ```tsx {{ filename: 'src/components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/clerk-react' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/clerk-react/errors' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification((emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {email.id !== user?.primaryEmailAddress?.id && ( )}
  • ))}
) } ```
### Handle reverification for a fetcher function The following example demonstrates how to use the `useReverification()` hook to enhance a fetcher function that fetches data from a route that requires reverification. For examples on how to set up a route that requires reverification, see the [guide on reverification](/docs/guides/secure/reverification). ```tsx {{ filename: 'src/components/AccountBalance.tsx' }} import { useAuth, useReverification } from '@clerk/clerk-react' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/clerk-react/errors' import { useState } from 'react' export function AccountBalance() { const { getToken } = useAuth() const [balance, setBalance] = useState(null) const accountBalance = useReverification(async () => { const response = await fetch('/api/balance', { headers: { Authorization: `Bearer ${await getToken()}`, }, }) return await response.json() }) const handleClick = async () => { try { const accountBalanceResponse = await accountBalance() setBalance(accountBalanceResponse.amount) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error('Error fetching account balance', e) } } return (
Your account balance is {balance ? `$${balance}` : '$******'}
) } ```
The following example demonstrates how to build a custom UI when using the `useReverification()` hook. In the example, the `useReverification()` hook is used to require a user to reverify their credentials before being able to update their primary email address. It requires two components: the `` component displays the list of email addresses to choose from and it renders the second component, ``, which handles the reverification process. The example handles first factor verification using an email code, so you will need to have the [**Email verification code**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) setting enabled for your application. But you can adapt this example to handle any type of verification level or strategy. The `` component uses `useReverification()` to enhance the `update()` method, requiring the user to reverify their credentials before being able to update their primary email address. The `useReverification()` hook provides the `onNeedsReverification` option, which is a handler for building a custom UI. It provides four properties: `level`, `complete`, `cancel`, and `inProgress`. The example tracks these using the `verificationState` state variable. * The `level` property determines the verification level required for the reverification process. This example only handles first factor verification, which is done in the `` component. * The `complete` and `cancel` properties are the steps of the reverification process, which is also done in the `` component. * The `inProgress` property is used to track the state of the reverification process. When the user selects the "Make primary" button, it triggers the reverification process and sets the `inProgress` property is `true`, which displays the `` component. ```tsx {{ filename: 'src/components/UpdateUserEmail.tsx', collapsible: true }} import { useReverification, useUser } from '@clerk/clerk-react' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/clerk-react/errors' import { useState } from 'react' import { SessionVerificationLevel } from '@clerk/types' import { VerificationComponent } from './VerificationComponent' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // TODO: Update to use exported type once available const [verificationState, setVerificationState] = useState< | { complete: () => void cancel: () => void level: SessionVerificationLevel | undefined inProgress: boolean } | undefined >(undefined) // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification( (emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), { onNeedsReverification: ({ complete, cancel, level }) => { setVerificationState({ complete, cancel, level, inProgress: true, }) }, }, ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {user?.primaryEmailAddressId !== email.id && ( )}
  • ))}
{verificationState?.inProgress && ( { verificationState.complete() setVerificationState(undefined) }} onCancel={() => { verificationState.cancel() setVerificationState(undefined) }} /> )}
) } ```
The `` component handles the reverification process. It uses the `level` property to determine the verification level, which is set to `first_factor`. First, it finds the determined starting first factor from the supported first factors. Then, it prepares the first factor verification using the `strategy` (`email_code` in this case) and `emailAddressId` properties. Finally, it attempts to verify the session with email code provided by the user. If the verification is successful, the `onComplete()` handler is called to complete the reverification process. ```tsx {{ filename: 'src/components/VerificationComponent.tsx', collapsible: true }} import { useEffect, useRef, useState } from 'react' import { useSession } from '@clerk/clerk-react' import { EmailCodeFactor, SessionVerificationLevel, SessionVerificationResource, } from '@clerk/types' export function VerificationComponent({ level = 'first_factor', onComplete, onCancel, }: { level: SessionVerificationLevel | undefined onComplete: () => void onCancel: () => void }) { const { session } = useSession() const [code, setCode] = useState('') const reverificationRef = useRef(undefined) const [determinedStartingFirstFactor, setDeterminedStartingFirstFactor] = useState< EmailCodeFactor | undefined >() useEffect(() => { if (reverificationRef.current) { return } session?.startVerification({ level }).then(async (response) => { reverificationRef.current = response await prepareEmailVerification(response) }) }, []) const prepareEmailVerification = async (verificationResource: SessionVerificationResource) => { // To simplify the example we will only handle the first factor verification if (verificationResource.status === 'needs_first_factor') { // Determine the starting first factor from the supported first factors const determinedStartingFirstFactor = verificationResource.supportedFirstFactors?.filter( (factor) => factor.strategy === 'email_code', )[0] if (determinedStartingFirstFactor) { setDeterminedStartingFirstFactor(determinedStartingFirstFactor) // Prepare the first factor verification with the determined starting first factor await session?.prepareFirstFactorVerification({ strategy: determinedStartingFirstFactor.strategy, emailAddressId: determinedStartingFirstFactor?.emailAddressId, }) } } } const handleVerificationAttempt = async () => { try { // Attempt to verify the session with the provided code await session?.attemptFirstFactorVerification({ strategy: 'email_code', code, }) onComplete() } catch (e) { // Any error from the attempt to verify the session can be handled here console.error('Error verifying session', e) } } if (!determinedStartingFirstFactor) { return null } return (

Enter verification code sent to {determinedStartingFirstFactor.safeIdentifier || ''}

setCode(e.target.value)} />
) } ```
## Related guides See the custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). guides for examples of how to use the `useReverification()` hook, such as the [Add a phone number to a user's account](/docs/guides/development/custom-flows/account-updates/add-phone) guide. --- title: useSessionList() description: Access and manage the current user's session list in your React application with Clerk's useSessionList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-session-list.mdx --- The `useSessionList()` hook returns an array of Session objects that have been registered on the client device. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | `undefined` | A list of sessions that have been registered on the client device. | | `setActive` | `undefined` | A function that sets the active session and/or organization. See the reference doc. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | SessionResource\[] | A list of sessions that have been registered on the client device. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. See the reference doc. | ## Example ### Get a list of sessions The following example uses `useSessionList()` to get a list of sessions that have been registered on the client device. The `sessions` property is used to show the number of times the user has visited the page. ```tsx {{ filename: 'src/pages/Home.tsx' }} import { useSessionList } from '@clerk/clerk-react' export default function Home() { const { isLoaded, sessions } = useSessionList() // Handle loading state if (!isLoaded) return
Loading...
return (

Welcome back. You've been here {sessions.length} times before.

) } ```
--- title: useSession() description: Access and manage the current user's session in your React application with Clerk's useSession() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-session.mdx --- The `useSession()` hook provides access to the current user's Session object, as well as helpers for setting the active session. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `session` | `undefined` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `session` | `null` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `boolean` | A boolean that indicates whether a user is currently signed in. | | `session` | SignedInSessionResource | The current session for the user. | ## Example ### Access the `Session` object The following example uses the `useSession()` hook to access the `Session` object, which has the `lastActiveAt` property. The `lastActiveAt` property is a `Date` object used to show the time the session was last active. ```tsx {{ filename: 'src/pages/Home.tsx' }} import { useSession } from '@clerk/clerk-react' export default function Home() { const { isLoaded, session, isSignedIn } = useSession() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

This session has been active since {session.lastActiveAt.toLocaleString()}

) } ```
--- title: useSignIn() description: Access and manage the current user's sign-in state in your React application with Clerk's useSignIn() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-sign-in.mdx --- The `useSignIn()` hook provides access to the SignIn object, which allows you to check the current state of a sign-in attempt and manage the sign-in flow. You can use this to create a [custom sign-in flow](/docs/guides/development/custom-flows/overview#sign-in-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signIn` | `undefined` | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signIn` | SignInResource | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | ## Examples ### Check the current state of a sign-in The following example uses the `useSignIn()` hook to access the SignIn object, which contains the current sign-in attempt status and methods to create a new sign-in attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'src/pages/SignInPage.tsx' }} import { useSignIn } from '@clerk/clerk-react' export default function SignInPage() { const { isLoaded, signIn } = useSignIn() // Handle loading state if (!isLoaded) return
Loading...
return
The current sign-in attempt status is {signIn?.status}.
} ```
### Create a custom sign-in flow with `useSignIn()` The `useSignIn()` hook can also be used to build fully custom sign-in flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-in flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignIn()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useSignUp() description: Access and manage the current user's sign-up state in your React application with Clerk's useSignUp() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-sign-up.mdx --- The `useSignUp()` hook provides access to the SignUp object, which allows you to check the current state of a sign-up attempt and manage the sign-up flow. You can use this to create a [custom sign-up flow](/docs/guides/development/custom-flows/overview#sign-up-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signUp` | `undefined` | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signUp` | SignUpResource | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | ## Examples ### Check the current state of a sign-up The following example uses the `useSignUp()` hook to access the SignUp object, which contains the current sign-up attempt status and methods to create a new sign-up attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'src/pages/SignUpPage.tsx' }} import { useSignUp } from '@clerk/clerk-react' export default function SignUpPage() { const { isLoaded, signUp } = useSignUp() // Handle loading state if (!isLoaded) return
Loading...
return
The current sign-up attempt status is {signUp?.status}.
} ```
### Create a custom sign-up flow with `useSignUp()` The `useSignUp()` hook can also be used to build fully custom sign-up flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-up flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignUp()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`useStatements()`" description: Access and manage statements in your React application with Clerk's useStatements() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-statements lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-statements.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `useStatements()` hook provides access to the statements associated with a user or Organization. It returns a paginated list of statements and includes methods for managing them. ## Parameters `useStatements()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | ## Returns `useStatements()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | BillingStatementResource\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `CacheSetter`\<undefined \| ClerkPaginatedResponse\<BillingStatementResource\>\> | A function that allows you to set the data manually. | ## Examples ### Basic usage The following example demonstrates how to fetch and display a user's statements. ```tsx {{ filename: 'src/pages/billing/StatementsList.tsx' }} import { useStatements } from '@clerk/clerk-react/experimental' export default function StatementsList() { const { data, isLoading } = useStatements({ for: 'user', pageSize: 10, }) if (isLoading) { return
Loading statements...
} if (!data || data.length === 0) { return
No statements found.
} return (
    {data?.map((statement) => (
  • Statement ID: {statement.id} - {statement.status}
    Date: {statement.timestamp.toLocaleDateString()}
  • ))}
) } ```
### Infinite pagination The following example demonstrates how to implement infinite scrolling with statements. ```tsx {{ filename: 'src/pages/billing/StatementsList.tsx' }} import { useStatements } from '@clerk/clerk-react/experimental' export default function InfiniteStatements() { const { data, isLoading, hasNextPage, fetchNext } = useStatements({ for: 'user', infinite: true, pageSize: 20, }) if (isLoading) { return
Loading...
} if (!data || data.length === 0) { return
No statements found.
} return (
    {data?.map((statement) => (
  • Statement ID: {statement.id}
    Amount: {statement.totals.grandTotal.amountFormatted}
    Status: {statement.status}
  • ))}
{hasNextPage && }
) } ```
--- title: "`useSubscription()`" description: Access Subscription information in your React application with Clerk's useSubscription() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-subscription lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-subscription.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `useSubscription()` hook provides access to Subscription information for users or Organizations in your application. It returns the current Subscription data and includes methods for managing it. > \[!WARNING] > The `useSubscription()` hook should only be used for accessing and displaying subscription information. For authorization purposes (i.e., controlling access to Features or content), use the [`has()`](/docs/guides/secure/authorization-checks#use-has-for-authorization-checks) helper or the \ component instead. ## Parameters `useSubscription()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch the subscription for an organization or a user. Defaults to `'user'`. | | `keepPreviousData?` | `boolean` | If true, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | ## Returns `useSubscription()` returns an object with the following properties: | Property | Type | Description | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | `data` | undefined \| null \| BillingSubscriptionResource | The subscription object, `undefined` before the first fetch, or `null` if no subscription exists. | | `error` | undefined \| Error | Any error that occurred during the data fetch, or `undefined` if no error occurred. | | `isFetching` | `boolean` | A boolean that indicates whether any request is still in flight, including background updates. | | `isLoading` | `boolean` | A boolean that indicates whether the initial data is still being fetched. | | `revalidate` | () => void \| Promise\ | Function to manually revalidate or refresh the subscription data. | ## Examples ### Basic usage The following example shows how to fetch and display subscription information. ```tsx {{ filename: 'src/pages/pricing/SubscriptionDetails.tsx' }} import { useSubscription } from '@clerk/clerk-react/experimental' export default function SubscriptionInfo() { const { data, isLoading, error } = useSubscription() if (isLoading) { return
Loading subscription...
} if (error) { return
Error loading subscription: {error.message}
} if (!data) { return
No subscription found
} return (

Your Subscription

{/* Display subscription details */}
) } ```
### Organization subscription The following example shows how to fetch an Organization's subscription. ```tsx {{ filename: 'src/pages/pricing/OrganizationSubscription.tsx' }} import { useSubscription } from '@clerk/clerk-react/experimental' export default function OrganizationSubscription() { const { data, isLoading, revalidate } = useSubscription({ for: 'organization', keepPreviousData: true, }) const handleSubscriptionUpdate = async () => { // After making changes to the subscription await revalidate() } if (isLoading) { return
Loading Organization subscription...
} return (

Organization Subscription

{/* Display Organization subscription details */}
) } ```
### With error handling The following example shows how to handle subscription data with proper error states. ```tsx {{ filename: 'src/pages/pricing/SubscriptionDetails.tsx', collapsible: true }} import { useSubscription } from '@clerk/clerk-react/experimental' export function SubscriptionDetails() { const { data: subscription, isLoading } = useSubscription() if (isLoading) { return
Loading subscription...
} if (!subscription) { return
No subscription
} return (

Subscription Details

Status: {subscription.status}

Active since: {subscription.activeAt.toLocaleDateString()}

{subscription.pastDueAt && (

Past due since: {subscription.pastDueAt.toLocaleDateString()}

)}
{subscription.nextPayment && (

Next Payment

Amount: {subscription.nextPayment.amount.amountFormatted}

Due: {subscription.nextPayment.date.toLocaleDateString()}

)}

Subscription Items

    {subscription.subscriptionItems.map((item) => (
  • {/* Display subscription item details */}
  • ))}
) } export default function Page() { const { data, isLoading, error, isFetching, revalidate } = useSubscription() if (error) { return (

Failed to load subscription

{error.message}

) } return (
{isLoading ? (
Loading...
) : ( <>
{isFetching && Refreshing...}
{data ? :
No active subscription
} )}
) } ```
--- title: useUser() description: Access and manage the current user's data in your React application with Clerk's useUser() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/hooks/use-user.mdx --- The `useUser()` hook provides access to the current user's User object, which contains all the data for a single user in your application and provides methods to manage their account. This hook also allows you to check if the user is signed in and if Clerk has loaded and initialized. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that returns `true` if the user is signed in. | | `user` | `undefined` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that returns `true` if the user is signed in. | | `user` | `null` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that returns `true` if the user is signed in. | | `user` | UserResource | The `User` object for the current user. | ## Examples ### Get the current user The following example uses the `useUser()` hook to access the User object, which contains the current user's data such as their full name. The `isLoaded` and `isSignedIn` properties are used to handle the loading state and to check if the user is signed in, respectively. ```tsx {{ filename: 'src/pages/Example.tsx' }} import { useUser } from '@clerk/clerk-react' export default function Example() { const { isSignedIn, user, isLoaded } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return
Hello {user.firstName}!
} ```
### Update user data The following example uses the `useUser()` hook to access the User object, which calls the update() method to update the current user's information. ```tsx {{ filename: 'src/pages/Example.tsx' }} import { useUser } from '@clerk/clerk-react' export default function Example() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { await user.update({ firstName: 'John', lastName: 'Doe', }) } return ( <>

user.firstName: {user.firstName}

user.lastName: {user.lastName}

) } ```
### Reload user data The following example uses the `useUser()` hook to access the User object, which calls the reload() method to get the latest user's information. ```tsx {{ filename: 'src/pages/Home.tsx' }} import { useUser } from '@clerk/clerk-react' export default function Home() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { // Update data via an API endpoint const updateMetadata = await fetch('/api/updateMetadata', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role: 'admin', }), }) // Check if the update was successful if ((await updateMetadata.json()).message !== 'success') { throw new Error('Error updating') } // If the update was successful, reload the user data await user.reload() } return ( <>

user role: {user.publicMetadata.role}

) } ```
--- title: Next.js Quickstart (App Router) description: Add authentication and user management to your Next.js app. sdk: nextjs, react, js-frontend, chrome-extension, expo, android, ios, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/getting-started/quickstart lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: "" activeSdk: nextjs sourceFile: /docs/getting-started/quickstart.mdx --- ## Create a new Next.js application Run the following command to [create a new Next.js application](https://nextjs.org/docs/getting-started/installation). It will create an app with the name `my-clerk-app`, but you can replace it with any name you want. ```npm npm create next-app@latest my-clerk-app -- --yes ``` ## Install `@clerk/nextjs` Run the following command to install the Next.js SDK: ```npm npm install @clerk/nextjs ``` ## Add `clerkMiddleware()` to your app `clerkMiddleware()` grants you access to user authentication state throughout your app. > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. 1. Create a `proxy.ts` file. * If you're using the `/src` directory, create `proxy.ts` in the `/src` directory. * If you're not using the `/src` directory, create `proxy.ts` in the root directory. 2. In your `proxy.ts` file, export the `clerkMiddleware()` helper: ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware } from '@clerk/nextjs/server' export default clerkMiddleware() export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` 3. By default, `clerkMiddleware()` will not protect any routes. All routes are public and you must opt-in to protection for routes. See the [`clerkMiddleware()` reference](/docs/reference/nextjs/clerk-middleware) to learn how to require authentication for specific routes. ## Add `` and Clerk components to your app 1. Add the \ component to your app's layout. This component provides Clerk's authentication context to your app. 2. Copy and paste the following file into your `layout.tsx` file. This creates a header with Clerk's prebuilt components to allow users to sign in and out. ```tsx {{ filename: 'app/layout.tsx', mark: [[2, 9], 34, [37, 49], 53], fold: [[12, 27]] }} import type { Metadata } from 'next' import { ClerkProvider, SignInButton, SignUpButton, SignedIn, SignedOut, UserButton, } from '@clerk/nextjs' import { Geist, Geist_Mono } from 'next/font/google' import './globals.css' const geistSans = Geist({ variable: '--font-geist-sans', subsets: ['latin'], }) const geistMono = Geist_Mono({ variable: '--font-geist-mono', subsets: ['latin'], }) export const metadata: Metadata = { title: 'Clerk Next.js Quickstart', description: 'Generated by create next app', } export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { return (
{children}
) } ``` ## Create your first user 1. Run your project with the following command: ```npm npm run dev ``` 2. Visit your app's homepage at [http://localhost:3000](http://localhost:3000). 3. Click "Sign up" in the header and authenticate to create your first user. ## It's time to build! You've added Clerk to your Next.js app 🎉. From here, you can continue developing your application. To make configuration changes to your Clerk development instance, claim the Clerk keys that were generated for you by selecting **Claim your application** in the bottom right of your app. This will associate the application with your Clerk account.
## Next steps * [Create a custom sign-in or sign-up page](/docs/nextjs/guides/development/custom-sign-in-or-up-page) * This tutorial gets you started with Clerk's `` component, which uses the Account Portal. If you don't want to use the Account Portal, read this guide about creating a custom authentication page. *** * [Add custom onboarding to your authentication flow](/docs/guides/development/add-onboarding-flow) * If you need to collect additional information about users that Clerk's Account Portal or prebuilt components don't collect, read this guide about adding a custom onboarding flow to your authentication flow. *** * [Protect specific routes](/docs/reference/nextjs/clerk-middleware) * This tutorial taught you that by default, `clerkMiddleware()` will not protect any routes. Read this reference doc to learn how to protect specific routes from unauthenticated users. *** * [Protect content and read user data](/docs/nextjs/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your Next.js app. *** * [Next.js SDK Reference](/docs/reference/nextjs/overview) * Learn more about the Clerk Next.js SDK and how to use it. *** * [Deploy to Production](/docs/guides/development/deployment/production) * Learn how to deploy your Clerk app to production. --- title: Clerk Billing for B2B SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2b lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: nextjs sourceFile: /docs/guides/billing/for-b2b.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2B SaaS allows you to create Plans and manage Subscriptions **for companies or organizations** in your application. If you'd like to charge individual users, see Billing for B2C SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your customers subscribe to. There is no limit to the number of Plans you can create. If your Clerk instance has existing [Custom Permissions](/docs/guides/organizations/roles-and-permissions), the corresponding Features from those Permissions will automatically be added to the free Plan for Orgs. This ensures that Organization members get the same set of Custom Permissions when Billing is enabled, because all Organizations start on the free Plan. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2B Billing, select the **Plans for Organizations** tab and select **Add Plan**. When creating a Plan, you can also create [Features](/docs/guides/secure/features) for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's an Organization Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that customers can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'app/pricing/page.tsx' }} import { PricingTable } from '@clerk/nextjs' export default function PricingPage() { return (
) } ```
## Control access with Features, Plans, and Permissions You can use Clerk's Features, Plans, and Permissions to gate access to content using authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript-based framework, while `` is a component, and therefore, is only available for React-based frameworks. > \[!IMPORTANT] > Permission-based authorization checks link with Feature-based authorization checks. This means that if you are checking a Custom Permission, it will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. ### Example: Using `has()` Use the `has()` method to test if the Organization has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. > \[!TIP] > Why aren't Custom Permissions appearing in the session token (JWT) or in API responses (including the result of the `has()` check)? > > *** > > Custom Permissions will only appear in the session token (JWT) and in API responses (including the result of the `has()` check) if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. If the Feature is not part of the Plan, the `has()` check for Permissions using that Feature will return `false`, and those Permissions will not be represented in the session token. > > For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. The user's Organization must be subscribed to a Plan that has the `teams` Feature for authorization checks to work. If the user's Organization is not subscribed to a Plan that has the `teams` Feature, the authorization check will always return `false`, *even if the user has the Custom Permission*. The following example demonstrates how to use `has()` to check if an Organization has a Plan. ```tsx {{ filename: 'app/bronze-content/page.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function BronzeContentPage() { const { has } = await auth() const hasBronzePlan = has({ plan: 'bronze' }) if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Feature. ```tsx {{ filename: 'app/premium-content/page.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function PremiumContentPage() { const { has } = await auth() const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
The following example demonstrates how to use `has()` to check if an Organization has a Permission. ```tsx {{ filename: 'app/manage-premium-content/page.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function ManagePremiumContentPage() { const { has } = await auth() const hasPremiumAccessManage = has({ permission: 'org:premium_access:manage' }) if (!hasPremiumAccessManage) return (

Only subscribers with the Premium Access Manage permission can access this content.

) return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the Organization does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the Organization has a Plan. ```tsx {{ filename: 'app/protected-content/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Feature. ```tsx {{ filename: 'app/protected-premium-content/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the Organization has a Permission. ```tsx {{ filename: 'app/protected-manage-content/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function ProtectedManageContentPage() { return ( Only subscribers with the Premium Access Manage permission can access this content.

} >

Exclusive Management Content

This content is only visible to users with Premium Access Manage permission.

) } ```
--- title: Clerk Billing for B2C SaaS description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/billing/for-b2c lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: nextjs sourceFile: /docs/guides/billing/for-b2c.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing for B2C SaaS allows you to create Plans and manage Subscriptions **for individual users** in your application. If you'd like to charge companies or organizations, see Billing for B2B SaaS. You can also combine both B2C and B2B Billing in the same application. ## Enable Billing To enable Billing for your application, navigate to the [**Billing Settings**](https://dashboard.clerk.com/~/billing/settings) page in the Clerk Dashboard. This page will guide you through enabling Billing for your application. Clerk Billing costs the same as using Stripe Billing directly, just 0.7% per transaction, plus transaction fees which are paid directly to Stripe. Clerk Billing is **not** the same as Stripe Billing. Plans and pricing are managed directly through the Clerk Dashboard and won't sync with your existing Stripe products or plans. Clerk uses Stripe **only** for payment processing, so you don't need to set up Stripe Billing. ### Payment gateway Once you have enabled Billing, you will see the following **Payment gateway** options for collecting payments via Stripe: * **Clerk development gateway**: A shared **test** Stripe account used for development instances. This allows developers to test and build Billing flows **in development** without needing to create and configure a Stripe account. * **Stripe account**: Use your own Stripe account for production. **A Stripe account created for a development instance cannot be used for production**. You will need to create a separate Stripe account for your production environment. ## Create a Plan Subscription Plans are what your users subscribe to. There is no limit to the number of Plans you can create. To create a Plan, navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. Here, you can create, edit, and delete Plans. To setup B2C Billing, select the **Plans for Users** tab and select **Add Plan**. When creating a Plan, you can also create Features for the Plan; see the next section for more information. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When creating or editing a Plan, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Add Features to a Plan [Features](/docs/guides/secure/features) make it easy to give entitlements to your Plans. You can add any number of Features to a Plan. You can add a Feature to a Plan when you are creating a Plan. To add it after a Plan is created: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you'd like to add a Feature to. 3. In the **Features** section, select **Add Feature**. > \[!TIP] > What is the **Publicly available** option? > > *** > > Plans appear in some Clerk components depending on what kind of Plan it is. All Plans can appear in the `` component. If it's a user Plan, it can appear in the `` component. When adding a Feature to a Plan, it will also automatically appear in the corresponding Plan. When creating or editing a Feature, if you'd like to hide it from appearing in Clerk components, you can toggle the **Publicly available** option off. ## Create a pricing page You can create a pricing page by using the \ component. This component displays a table of Plans and Features that users can subscribe to. **It's recommended to create a dedicated page**, as shown in the following example. ```tsx {{ filename: 'app/pricing/page.tsx' }} import { PricingTable } from '@clerk/nextjs' export default function PricingPage() { return (
) } ```
## Control access with Features and Plans You can use Clerk's Features and Plans to gate access to the content. There are a few ways to do this, but the recommended approach is to either use the has() method or the \ component. The `has()` method is available for any JavaScript framework, while `` is only available for React-based frameworks. ### Example: Using `has()` Use the `has()` method to test if the user has access to a **Plan**: ```jsx const hasPremiumAccess = has({ plan: 'gold' }) ``` Or a **Feature**: ```jsx const hasPremiumAccess = has({ feature: 'widgets' }) ``` The has() method is a server-side helper that checks if the Organization has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. `has()` is available on the auth object, which you will access differently depending on the framework you are using. The following example demonstrates how to use `has()` to check if a user has a Plan. ```tsx {{ filename: 'app/bronze-content/page.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function BronzeContentPage() { const { has } = await auth() const hasBronzePlan = has({ plan: 'bronze' }) if (!hasBronzePlan) return

Only subscribers to the Bronze plan can access this content.

return

For Bronze subscribers only

} ```
The following example demonstrates how to use `has()` to check if a user has a Feature. ```tsx {{ filename: 'app/premium-content/page.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function PremiumContentPage() { const { has } = await auth() const hasPremiumAccess = has({ feature: 'premium_access' }) if (!hasPremiumAccess) return

Only subscribers with the Premium Access feature can access this content.

return

Our Exclusive Content

} ```
### Example: Using `` The \ component protects content or even entire routes by checking if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). You can pass a `fallback` prop to `` that will be rendered if the user does not have the access control. The following example demonstrates how to use `` to protect a page by checking if the user has a Plan. ```tsx {{ filename: 'app/protected-content/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function ProtectedContentPage() { return ( Only subscribers to the Bronze plan can access this content.

} >

Exclusive Bronze Content

This content is only visible to Bronze subscribers.

) } ```
The following example demonstrates how to use `` to protect a page by checking if the user has a Feature. ```tsx {{ filename: 'app/protected-premium-content/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function ProtectedPremiumContentPage() { return ( Only subscribers with the Premium Access feature can access this content.

} >

Exclusive Premium Content

This content is only visible to users with Premium Access feature.

) } ```
--- title: Protect content and read user data description: Learn how to use Clerk's hooks and helpers to protect content and read user data in your Next.js application. metadata: title: Read session and user data in your Next.js app with Clerk sdk: nextjs, expo, react-router, remix, tanstack-react-start, astro, nuxt sdkScoped: "true" canonical: /docs/:sdk:/guides/users/reading lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,expo,react-router,remix,tanstack-react-start,astro,nuxt notAvailableSdks: react,js-frontend,chrome-extension,android,ios,expressjs,fastify,go,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/guides/users/reading.mdx --- Clerk provides a set of [hooks and helpers](/docs/reference/nextjs/overview#client-side-helpers) that you can use to protect content and read user data in your Next.js application. Here are examples of how to use these helpers in both the client and server-side to get you started. ## Server-side ### App Router [`auth()`](/docs/reference/nextjs/app-router/auth) and [`currentUser()`](/docs/reference/nextjs/app-router/current-user) are App Router-specific helpers that you can use inside of your Route Handlers, Middleware, Server Components, and Server Actions. * The `auth()` helper will return the Auth object of the currently active user. * The `currentUser()` helper will return the Backend User object of the currently active user, which includes helpful information like the user's name or email address. **It does count towards the [Backend API request rate limit](/docs/guides/how-clerk-works/system-limits)** so it's recommended to use the useUser() hook on the client side when possible and only use `currentUser()` when you specifically need user data in a server context. For more information on this helper, see the [`currentUser()`](/docs/reference/nextjs/app-router/current-user) reference. The following example uses the [`auth()`](/docs/reference/nextjs/app-router/auth) helper to validate an authenticated user and the `currentUser()` helper to access the `Backend User` object for the authenticated user. > \[!TIP] > Any requests from a Client Component to a Route Handler will read the session from cookies and will not need the token sent as a Bearer token. ```tsx {{ filename: 'app/page.tsx' }} import { auth, currentUser } from '@clerk/nextjs/server' export default async function Page() { // Use `auth()` to access `isAuthenticated` - if false, the user is not signed in const { isAuthenticated } = await auth() // Protect the route by checking if the user is signed in if (!isAuthenticated) { return
Sign in to view this page
} // Get the Backend User object when you need access to the user's information const user = await currentUser() // Use `user` to render user details or create UI elements return
Welcome, {user.firstName}!
} ```
> \[!WARNING] > The Backend User object includes a `privateMetadata` field that should not be exposed to the frontend. Avoid passing the full user object returned by `currentUser()` to the frontend. Instead, pass only the specified fields you need. ```tsx {{ filename: 'app/api/user/route.ts' }} import { NextResponse } from 'next/server' import { currentUser, auth } from '@clerk/nextjs/server' export async function GET() { // Use `auth()` to access `isAuthenticated` - if false, the user is not signed in const { isAuthenticated } = await auth() // Protect the route by checking if the user is signed in if (!isAuthenticated) { return new NextResponse('Unauthorized', { status: 401 }) } // Use `currentUser()` to get the Backend User object const user = await currentUser() // Add your Route Handler's logic with the returned `user` object return NextResponse.json( { userId: user.id, email: user.emailAddresses[0].emailAddress }, { status: 200 }, ) } ```
### Pages Router For Next.js applications using the Pages Router, the [`getAuth()`](/docs/reference/nextjs/pages-router/get-auth) helper will return the Auth object of the currently active user, which contains important information like the current user's session ID, user ID, and Organization ID, as well as the `isAuthenticated` property which can be used to protect your API routes. In some cases, you may need the full Backend User object of the currently active user. This is helpful if you want to render information, like their first and last name, directly from the server. The `clerkClient()` helper returns an instance of the JS Backend SDK, which exposes Clerk's Backend API resources through methods such as the getUser(){{ target: '_blank' }} method. This method returns the full `Backend User` object. **It does count towards the [Backend API request rate limit](/docs/guides/how-clerk-works/system-limits)** so it's recommended to use the useUser() hook on the client side when possible and only use `getUser()` when you specifically need user data in a server context. In the following example, the `userId` is passed to the JS Backend SDK's `getUser()` method to get the user's full `Backend User` object. ```tsx {{ filename: 'pages/api/auth.ts' }} import { getAuth, clerkClient } from '@clerk/nextjs/server' import type { NextApiRequest, NextApiResponse } from 'next' export default async function handler(req: NextApiRequest, res: NextApiResponse) { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(req) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return res.status(401).json({ error: 'Unauthorized' }) } // Initialize the JS Backend SDK const client = await clerkClient() // Get the user's full Backend User object const user = await client.users.getUser(userId) return res.status(200).json({ user }) } ``` The `buildClerkProps()` function is used in your Next.js application's `getServerSideProps` to pass authentication state from the server to the client. It returns props that get spread into the `` component. This enables Clerk's client-side helpers, such as `useAuth()`, to correctly determine the user's authentication status during server-side rendering. ```tsx {{ filename: 'pages/example.tsx' }} import { getAuth, buildClerkProps } from '@clerk/nextjs/server' import { GetServerSideProps } from 'next' export const getServerSideProps: GetServerSideProps = async (ctx) => { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(ctx.req) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return { redirect: { destination: '/sign-in', permanent: false, }, } } // Initialize the JS Backend SDK const client = await clerkClient() // Get the user's full `Backend User` object const user = await client.users.getUser(userId) // Pass the `user` object to buildClerkProps() return { props: { ...buildClerkProps(ctx.req, { user }) } } } ``` ## Client-side ### `useAuth()` {/* TODO: Keep in sync with /tanstack-react-start/read-session-data and /expo/read-session-user-data */} The following example uses the useAuth() hook to access the current auth state, as well as helper methods to manage the current session. ```tsx {{ filename: 'example.tsx' }} export default function Example() { const { isLoaded, isSignedIn, userId, sessionId, getToken } = useAuth() const fetchExternalData = async () => { // Use `getToken()` to get the current user's session token const token = await getToken() // Use `token` to fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return
Loading...
} // Use `isSignedIn` to check if the user is signed in if (!isSignedIn) { // You could also add a redirect to the sign-in page here return
Sign in to view this page
} return (
Hello, {userId}! Your current active session is {sessionId}.
) } ``` ### `useUser()` {/* TODO: Keep in sync with /reference/tanstack-react-start/read-session-data and /reference/expo/read-session-user-data */} The following example uses the useUser() hook to access the User object, which contains the current user's data such as their full name. The following example demonstrates how to use `useUser()` to check if the user is signed in and display their first name. ```tsx {{ filename: 'src/Example.tsx' }} export default function Example() { const { isSignedIn, user, isLoaded } = useUser() // Use `isLoaded` to check if Clerk is loaded if (!isLoaded) { return
Loading...
} // Use `isSignedIn` to protect the content if (!isSignedIn) { return
Sign in to view this page
} // Use `user` to access the current user's data return
Hello {user.firstName}!
} ``` --- title: Build your own sign-in-or-up page for your Next.js app with Clerk description: Learn how to add a custom sign-in-or-up page to your Next.js app with Clerk's prebuilt components. sdk: nextjs, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/custom-sign-in-or-up-page lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,remix,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/guides/development/custom-sign-in-or-up-page.mdx --- This guide shows you how to use the \ component to build a custom page that **allows users to sign in or sign up within a single flow**. To set up separate sign-in and sign-up pages, follow this guide, and then follow the custom sign-up page guide. > \[!NOTE] > Just getting started with Clerk and Next.js? See the quickstart tutorial! ## Build a sign-in-or-up page The following example demonstrates how to render the \ component on a dedicated page using the [Next.js optional catch-all route](https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes#catch-all-segments). ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx' }} import { SignIn } from '@clerk/nextjs' export default function Page() { return } ``` ## Make the sign-in-or-up route public By default, `clerkMiddleware()` makes all routes public. **This step is specifically for applications that have configured `clerkMiddleware()` to make [all routes protected](/docs/reference/nextjs/clerk-middleware#protect-all-routes).** If you have not configured `clerkMiddleware()` to protect all routes, you can skip this step. > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. To make the sign-in route public: * Navigate to your `proxy.ts` file. * Create a new [route matcher](/docs/reference/nextjs/clerk-middleware#create-route-matcher) that matches the sign-in route, or you can add it to your existing route matcher that is making routes public. * Create a check to see if the user's current route is a public route. If it is not a public route, use [`auth.protect()`](/docs/reference/nextjs/app-router/auth#auth-protect) to protect the route. ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isPublicRoute = createRouteMatcher(['/sign-in(.*)']) export default clerkMiddleware(async (auth, req) => { if (!isPublicRoute(req)) { await auth.protect() } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ## Update your environment variables * Set the `CLERK_SIGN_IN_URL` environment variable to tell Clerk where the `` component is being hosted. * Set `CLERK_SIGN_IN_FALLBACK_REDIRECT_URL` as a fallback URL incase users visit the `/sign-in` route directly. * Set `CLERK_SIGN_UP_FALLBACK_REDIRECT_URL` as a fallback URL incase users select the 'Don't have an account? Sign up' link at the bottom of the component. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```env {{ filename: '.env' }} NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/ NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/ ``` ## Visit your new page Run your project with the following command: ```npm npm run dev ``` Visit your new custom page locally at [localhost:3000/sign-in](http://localhost:3000/sign-in). ## Next steps * [Custom sign-up page](/docs/nextjs/guides/development/custom-sign-up-page) * Learn how to add a custom sign-up page to your Next.js app with Clerk's prebuilt components. *** * [Protect content and read user data](/docs/nextjs/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your Next.js application. *** * [Client-side helpers](/docs/reference/nextjs/overview#client-side-helpers) * Learn more about Next.js client-side helpers and how to use them. *** * [Next.js SDK Reference](/docs/reference/nextjs/overview) * Learn more about additional Next.js methods. *** * [Clerk components](/docs/reference/components/overview) * Learn more about Clerk's prebuilt components that make authentication and user management easy. --- title: Build your own sign-up page for your Next.js app with Clerk description: Learn how to add a custom sign-up page to your Next.js app with Clerk's prebuilt components. sdk: nextjs, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/custom-sign-up-page lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,remix,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/guides/development/custom-sign-up-page.mdx --- By default, the \ component handles signing in and signing up, but if you'd like to have a dedicated sign-up page, this guide shows you how to use the \ component to build a custom sign-up page. To set up a single sign-in-or-up page, follow the custom sign-in-or-up page guide. > \[!NOTE] > Just getting started with Clerk and Next.js? See the quickstart tutorial! ## Build a sign-up page The following example demonstrates how to render the \ component on a dedicated sign-up page using the [Next.js optional catch-all route](https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes#catch-all-segments). ```tsx {{ filename: 'app/sign-up/[[...sign-up]]/page.tsx' }} import { SignUp } from '@clerk/nextjs' export default function Page() { return } ``` ## Make the sign-up route public By default, `clerkMiddleware()` makes all routes public. **This step is specifically for applications that have configured `clerkMiddleware()` to make [all routes protected](/docs/reference/nextjs/clerk-middleware#protect-all-routes).** If you have not configured `clerkMiddleware()` to protect all routes, you can skip this step. > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. To make the sign-up route public: * Navigate to your `proxy.ts` file. * Add the sign-up route to your existing route matcher that is making routes public. ```tsx {{ filename: 'proxy.ts', ins: [5] }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' // prettier-ignore const isPublicRoute = createRouteMatcher([ '/sign-in(.*)', '/sign-up(.*)' ]) export default clerkMiddleware(async (auth, req) => { if (!isPublicRoute(req)) { await auth.protect() } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ## Update your environment variables * Set the `CLERK_SIGN_UP_URL` environment variable to tell Clerk where the `` component is being hosted. * Set `CLERK_SIGN_UP_FALLBACK_REDIRECT_URL` as a fallback URL incase users visit the `/sign-up` route directly. * Set `CLERK_SIGN_IN_FALLBACK_REDIRECT_URL` as a fallback URL incase users select the 'Already have an account? Sign in' link at the bottom of the component. Learn more about these environment variables and how to customize Clerk's redirect behavior in the [dedicated guide](/docs/guides/development/customize-redirect-urls). ```env {{ filename: '.env' }} NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/ NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/ ``` ## Visit your new page Run your project with the following command: ```npm npm run dev ``` Visit your new custom page locally at [localhost:3000/sign-up](http://localhost:3000/sign-up). ## Next steps * [Protect content and read user data](/docs/nextjs/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your Next.js application. *** * [Client-side helpers](/docs/reference/nextjs/overview#client-side-helpers) * Learn more about Next.js client-side helpers and how to use them. *** * [Next.js SDK Reference](/docs/reference/nextjs/overview) * Learn more about additional Next.js methods. *** * [Clerk components](/docs/reference/components/overview) * Learn more about Clerk's prebuilt components that make authentication and user management easy. --- title: Verify OAuth access tokens in your Next.js application with Clerk description: Learn how to use Clerk's helpers to verify OAuth access tokens in your Next.js application. sdk: nextjs, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/guides/development/verifying-oauth-access-tokens lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react-router,tanstack-react-start notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/guides/development/verifying-oauth-access-tokens.mdx --- When building a resource server that needs to accept and verify OAuth access tokens issued by Clerk, it's crucial to verify these tokens on your backend to ensure the request is coming from an authenticated client. > \[!NOTE] > OAuth tokens are machine tokens. Machine token usage is free during our public beta period but will be subject to pricing once generally available. Pricing is expected to be competitive and below market averages. Clerk's Next.js SDK provides a built-in [`auth()`](/docs/reference/nextjs/app-router/auth) function that supports token validation via the `acceptsToken` parameter. This lets you specify which type(s) of token your API route should accept. You can also use the [`auth.protect()`](/docs/reference/nextjs/app-router/auth#auth-protect) method to check if a request includes a valid machine token (e.g. API key or OAuth token) and enforce access rules accordingly. By default, `acceptsToken` is set to `session_token`, which means OAuth tokens will **not** be accepted unless explicitly configured. You can pass either a **single token type** or an **array of token types** to `acceptsToken`. To learn more about the supported token types, see the [`auth()` parameters documentation](/docs/reference/nextjs/app-router/auth#parameters). Below are two examples of verifying OAuth access tokens in a Next.js API route using Clerk's SDK: ## Example 1: Accepting a single token type In the following example, the `acceptsToken` parameter is set to only accept `oauth_token`s. * If the token is invalid or missing, `auth()` will return `null` for `userId` and other properties, and the request will be rejected with a `401` response. * If the token is valid, `userId` is returned and the token claims are available for use in the application logic. ```tsx {{ filename: 'app/api/example/route.ts' }} import { auth } from '@clerk/nextjs/server' export async function GET() { const { isAuthenticated, claims, userId } = await auth({ acceptsToken: 'oauth_token' }) // If auth() returns null, the token is invalid if (!isAuthenticated) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } return NextResponse.json({ userId, claims }) } ``` ## Example 2: Accepting multiple token types In the following example, the `acceptsToken` option allows both `session_token`s and `oauth_token`s. * If the token is invalid or missing, `auth()` will return `false` for `isAuthenticated` and `null` for other properties, like `userId`. * If the token is an `oauth_token`, the code checks that it includes the required `'profile'` scope. If not, an error is thrown. * If the token is valid and the required scope is present, `isAuthenticated` is `true` and `userId` is returned and available for use in the application logic. This example includes pseudo-code that uses the `userId` to get data from a database. ```tsx {{ filename: 'app/api/example/route.ts' }} import { NextRequest, NextResponse } from 'next/server' import { auth } from '@clerk/nextjs/server' export async function POST(req: NextRequest) { // Accept both session_token and oauth_token types const { isAuthenticated, tokenType, userId, scopes } = await auth({ acceptsToken: ['session_token', 'oauth_token'], }) // If auth() returns null, the token is invalid if (!isAuthenticated) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } // Check if the token is an oauth_token and if it doesn't have the required scope if (tokenType === 'oauth_token' && !scopes?.includes('profile')) { return NextResponse.json({ error: 'OAuth token missing the "profile" scope' }, { status: 401 }) } // If the token includes the required scope, move forward with the application logic // This example includes pseudo-code for getting data from a database using the userId const data = db.select().from(user).where(eq(user.id, userId)) return NextResponse.json({ data }) } ``` You can also protect entire route groups using [`clerkMiddleware()`](/docs/reference/nextjs/clerk-middleware). See how to implement this in [the middleware docs](/docs/reference/nextjs/clerk-middleware#protect-routes-based-on-token-types). --- title: Build an MCP server in your application with Clerk description: Learn how to build an MCP server using Clerk's OAuth server in your application. sdk: nextjs, expressjs sdkScoped: "true" canonical: /docs/:sdk:/guides/development/mcp/build-mcp-server lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,expressjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/guides/development/mcp/build-mcp-server.mdx --- This guide demonstrates how to build an MCP server using Clerk's OAuth server in your Next.js app. This example is written for Next.js App Router, but **can be adapted for Next.js Pages Router**. It assumes that you have already integrated Clerk into your app by following the quickstart. > \[!IMPORTANT] > For most client implementations of MCP, [dynamic client registration](https://openid.net/specs/openid-connect-registration-1_0.html) is required. This allows MCP-compatible clients to automatically register themselves with your server during the OAuth flow. > Before proceeding, ensure you have toggled on the **Dynamic client registration** option in the [OAuth Applications](https://dashboard.clerk.com/~/oauth-applications) page in the Clerk Dashboard. ## Install dependencies To get started, this implementation requires the following packages to be installed in your project: * [`@vercel/mcp-adapter`](https://github.com/vercel/mcp-adapter): A utility library that simplifies building an MCP server by handling the core protocol logic for you. It also includes an authentication wrapper that allows you to plug in your own token validation - in this case, using Clerk's OAuth tokens. * [`@clerk/mcp-tools`](https://github.com/clerk/mcp-tools): A helper library built on top of the [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) used to connect Clerk OAuth with MCP easily. ```npm npm install @vercel/mcp-adapter @clerk/mcp-tools ``` ## Set up your app with Clerk and MCP imports The following code is the starting point for your MCP server. It includes the imports and setup needed to implement an MCP server with Clerk. 1. In your `app/` directory, create a `[transport]` folder. This dynamic segment allows the MCP server to support different transport protocols used by the LLM tool. Streamable HTTP is the recommended default transport in the [current MCP spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports), and uses `/mcp` as the base path. SSE is also supported, and uses `/sse` as the base path. 2. Inside this directory, create a `route.ts` file with the following code. ```ts {{ filename: 'app/[transport]/route.ts' }} import { verifyClerkToken } from '@clerk/mcp-tools/next' import { createMcpHandler, withMcpAuth } from '@vercel/mcp-adapter' import { auth, clerkClient } from '@clerk/nextjs/server' const clerk = await clerkClient() ``` ## Create your MCP server and define tools To let external LLM-powered tools securely interact with your app, you need to define an MCP server, and expose one or more [resources](https://modelcontextprotocol.io/docs/concepts/resources), [prompts](https://modelcontextprotocol.io/docs/concepts/prompts), and/or [tools](https://modelcontextprotocol.io/docs/concepts/tools). For this guide, you'll implement a single, example tool called `get_clerk_user_data` that retrieves information about the authenticated Clerk user. For more documentation on how to build MCP tools, see the [MCP documentation](https://modelcontextprotocol.io/docs/concepts/tools). Vercel's `createMcpHandler()` function is used to handle the connection and transports required by the MCP protocol. Within its callback function, you can define tools that external LLM-based apps can invoke using `server.tool()`. Each tool includes: * A name (`get-clerk-user-data`). * A description of what the tool does. * Input parameters (none in this case). * A function that represents the implementation of the tool. In this case, it extracts the user ID, which is provided by Clerk's OAuth authentication, and then fetches the user's data using Clerk's getUser() method. The response is then returned in MCP's expected response format. ```ts {{ filename: 'app/[transport]/route.ts', mark: [[7, 25]] }} import { verifyClerkToken } from '@clerk/mcp-tools/next' import { createMcpHandler, withMcpAuth } from '@vercel/mcp-adapter' import { auth, clerkClient } from '@clerk/nextjs/server' const clerk = await clerkClient() const handler = createMcpHandler((server) => { server.tool( 'get-clerk-user-data', 'Gets data about the Clerk user that authorized this request', {}, async (_, { authInfo }) => { const userId = authInfo!.extra!.userId! as string const userData = await clerk.users.getUser(userId) return { content: [{ type: 'text', text: JSON.stringify(userData) }], } }, ) }) ``` ## Secure your MCP server Now that your MCP server and tools are defined, the next step is to secure your endpoints with OAuth. This ensures only authenticated clients with valid Clerk-issued tokens can access your tools. Add the following code to your `route.ts` file. This uses Vercel's `withMcpAuth()` function to wrap the MCP handler in authentication logic and uses Clerk's [`auth()`](/docs/reference/nextjs/app-router/auth) helper to parse the incoming OAuth token and extract the session context. This data is then passed into Clerk's `verifyClerkToken()` helper method, which verifies the OAuth token, extracts key metadata, and makes the current user'd ID available to tool call functions. To learn more about verifying OAuth tokens in Next.js apps, see the dedicated guide. > \[!NOTE] > OAuth tokens are machine tokens. Machine token usage is free during our public beta period but will be subject to pricing once generally available. Pricing is expected to be competitive and below market averages. The `authHandler` is then exported for both `GET` and `POST` methods. The `GET` method is required for SSE support only - if you do not need to support SSE, you can export only `POST` (and the `[transport]` part of the route). ```ts {{ filename: 'app/[transport]/route.ts' }} // The rest of your code... const authHandler = withMcpAuth( handler, async (_, token) => { const clerkAuth = await auth({ acceptsToken: 'oauth_token' }) return verifyClerkToken(clerkAuth, token) }, { required: true, resourceMetadataPath: '/.well-known/oauth-protected-resource/mcp', }, ) export { authHandler as GET, authHandler as POST } ``` ## Expose MCP metadata endpoints To comply with the MCP specification, your server must expose [OAuth protected resource metadata](https://datatracker.ietf.org/doc/html/rfc9728#section-4.1) at a specific endpoint (`.well-known/oauth-protected-resource`). Older versions of the MCP spec required that you also expose [OAuth authorization server metadata](https://datatracker.ietf.org/doc/html/rfc8414) at a specific endpoint (`.well-known/oauth-authorization-server`). This is no longer required by the current MCP spec, but it may be necessary for some clients that only support older versions of the spec. These metadata endpoints allow clients to discover where to authenticate, and some details about how the authentication service works. Clerk provides prebuilt helpers via [`@clerk/mcp-tools`](https://github.com/clerk/mcp-tools) that handle this for you: * `protectedResourceHandlerClerk`: Next.js route handler that serves OAuth **protected resource metadata** in the format expected by MCP clients. This handler lets you define specific supported OAuth scopes to declare what access levels your resource requires. * `authServerMetadataHandlerClerk`: Next.js route handler that serves OAuth **authorization server metadata** in the format expected by MCP clients. * `metadataCorsOptionsRequestHandler`: Handles CORS preflight (`OPTIONS`) requests for OAuth metadata endpoints. Required to ensure public, browser-based MCP clients can access these endpoints. > \[!NOTE] > For a more in-depth explanation of these helpers, see the [MCP Next.js reference](https://github.com/clerk/mcp-tools/tree/main/next). To expose your MCP metadata endpoints: 1. In your `app/` directory, create a `.well-known` folder. 2. Inside this directory, create two subdirectories called `oauth-protected-resource` and `oauth-authorization-server`. 3. Inside the `oauth-protected-resource` directory, create a `mcp` subdirectory. 4. In the `mcp` subdirectory, create a `route.ts` file with the following code for that specific route. 5. In the `oauth-authorization-server` directory, create a `route.ts` file with the following code for that specific route. ```ts {{ filename: 'app/.well-known/oauth-authorization-server/route.ts' }} import { authServerMetadataHandlerClerk, metadataCorsOptionsRequestHandler, } from '@clerk/mcp-tools/next' const handler = authServerMetadataHandlerClerk() const corsHandler = metadataCorsOptionsRequestHandler() export { handler as GET, corsHandler as OPTIONS } ``` ```ts {{ filename: 'app/.well-known/oauth-protected-resource/mcp/route.ts' }} import { metadataCorsOptionsRequestHandler, protectedResourceHandlerClerk, } from '@clerk/mcp-tools/next' const handler = protectedResourceHandlerClerk({ // Specify which OAuth scopes this protected resource supports scopes_supported: ['profile', 'email'], }) const corsHandler = metadataCorsOptionsRequestHandler() export { handler as GET, corsHandler as OPTIONS } ``` 6. Your `.well-known` endpoints must be **publicly accessible** for MCP clients to discover OAuth metadata. When protecting routes, consider these paths and ensure they are not protected. For example, if you're using [`clerkMiddleware()` to protect all routes](/docs/reference/nextjs/clerk-middleware#protect-all-routes), you can exclude the `.well-known` endpoints like this: > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. ```ts {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isPublicRoute = createRouteMatcher([ '/.well-known/oauth-authorization-server(.*)', '/.well-known/oauth-protected-resource(.*)', ]) export default clerkMiddleware(async (auth, req) => { if (isPublicRoute(req)) return // Allow public access to .well-known endpoints await auth.protect() // Protect all other routes }) ``` ## Finished 🎉 Once this is complete, clients that support the latest MCP spec can now invoke the `get-clerk-user-data` tool to securely fetch user data from your app, assuming the request is authorized with a Clerk OAuth token. To test this out, [learn how to connect your client LLM to the MCP server](/docs/guides/development/mcp/connect-mcp-client). The next step is to replace the demo tool with your own tools, resources, and/or prompts that are relevant to your app. You can learn more about how to do this in the [MCP SDK documentation](https://modelcontextprotocol.io/docs/concepts/tools). --- title: Clerk Billing webhooks description: Clerk Billing webhooks allow you to track subscription lifecycles and monitor payment attempts. sdk: nextjs, react, expo, react-router, astro, tanstack-react-start, remix, nuxt, vue, js-frontend, expressjs, fastify, js-backend sdkScoped: "true" canonical: /docs/:sdk:/guides/development/webhooks/billing lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react,expo,react-router,astro,tanstack-react-start,remix,nuxt,vue,js-frontend,expressjs,fastify,js-backend notAvailableSdks: chrome-extension,android,ios,go,ruby activeSdk: nextjs sourceFile: /docs/guides/development/webhooks/billing.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing supports webhook events that allow you to track information like subscription lifecycles and payments. ## Subscriptions A subscription is a top-level container unique to each user or organization. Subscription events can help you track billing changes for each of your customers. | Event Name | Description | | - | - | | `subscription.created` | The top-level subscription is created. This usually happens when a user or organization is created. For existing users and organizations, a subscription will be created when Billing is enabled for the application. | | `subscription.updated` | The top-level subscription is updated. This event is triggered when any property of the subscription has changed, except for status changes. For example, when the subscription items for the payer change. | | `subscription.active` | The top-level subscription transitions to active from a non-active status. This happens when any subscription item is set to active, including items from the free default Plan. | | `subscription.pastDue` | The top-level subscription contains a subscription item that has become past due. | ## Subscription items A subscription item provides details about the relationship between the payer (user or Organization) and a Plan. A top-level subscription may contain multiple subscription items. There can only be one `active` subscription item per payer and Plan. In addition, the subscription item for the default Plan will always have the same `id` to allow easier tracking of which users and Organizations are not paid customers. | Event Name | Description | | - | - | | `subscriptionItem.updated` | The subscription item is updated. This event is triggered when a property of the subscription item has changed that does not result in a status change. For example, when a subscription item is renewed and the recurring monthly charge succeeds, the status doesn't change (remains `active`), but `period_start` and `period_end` are updated. This results in a `subscriptionItem.updated` event. | | `subscriptionItem.active` | The subscription item is set to active. For paid Plans, this happens on successful payment. | | `subscriptionItem.canceled` | The subscription item is canceled. The payer retains Plan features until the end of the current billing period. | | `subscriptionItem.upcoming` | The subscription item is set as upcoming after the current billing period. This can happen in the case of a deferred Plan change from a higher-priced to lower-priced Plan. In the case a paid Plan is canceled, the subscription item for the default, free Plan will be set as `upcoming`. | | `subscriptionItem.ended` | The subscription item has ended. | | `subscriptionItem.abandoned` | The subscription item is abandoned. This can happen to `upcoming` subscription items if the payer subscribes to another Plan, or re-subscribes to a currently canceled Plan. | | `subscriptionItem.incomplete` | The subscription item is incomplete. This means the payer has started a checkout for a Plan, but the payment hasn't been successfully processed yet. Once payment succeeds, the subscription item transitions to an `active` status. | | `subscriptionItem.pastDue` | The subscription item is past due because a recurring charge has failed. | | `subscriptionItem.freeTrialEnding` | The subscription item is a free trial and is ending soon. This event is sent three days before the trial ends. If the trial is shorter than three days, it's sent immediately. | ## Payment attempts Payment attempts allow you to track successful and failed payments, for both checkout and recurring charges. Payment attempt events contain a `type`, which can be either `checkout` or `recurring`. You can use these values to determine whether a payment attempt was for a checkout or a subscription item renewal's recurring charge. | Event Name | Description | | - | - | | `paymentAttempt.created` | A payment attempt has been created with `pending` status. It can either succeed or fail in the future. | | `paymentAttempt.updated` | A payment attempt has been updated to `paid` or `failed` status. | Looking for other webhook events? To find a list of all the events Clerk supports, navigate to the [**Webhooks**](https://dashboard.clerk.com/~/webhooks) page and select the **Event Catalog** tab. --- title: "``" description: The component provides session and user context to Clerk's hooks and components. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/clerk-provider lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/clerk-provider.mdx --- The `` component is required to integrate Clerk into your React application, providing session and user context to Clerk's hooks and components. The recommended approach is to wrap your entire app with `` at the entry point to make authentication globally accessible. If you only need authentication for specific routes or pieces of your application, render `` deeper in the component tree. This allows you to implement Clerk's functionality precisely where required without impacting the rest of your app. ## Example ```tsx {{ filename: 'app/layout.tsx' }} import React from 'react' import { ClerkProvider } from '@clerk/nextjs' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ```tsx {{ filename: '_app.tsx' }} import { ClerkProvider } from '@clerk/nextjs' import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return ( ) } export default MyApp ``` ## Properties | Property | Type | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`afterMultiSessionSingleSignOutUrl?` | null \| string | The full URL or path to navigate to after signing out the current user is complete. This option applies to [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). | | ~~`afterSignInUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl` or `signInForceRedirectUrl` instead. | | `afterSignOutUrl?` | null \| string | Full URL or path to navigate to after successful sign out. | | ~~`afterSignUpUrl?`~~ | null \| string | **Deprecated.** Use `signUpFallbackRedirectUrl` or `signUpForceRedirectUrl` instead. | | `allowedRedirectOrigins?` | (string \| RegExp)\[] | An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `allowedRedirectProtocols?` | string\[] | An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `appearance?` | [`Appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) | Optional object to style your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `clerkJSUrl?` | `string` | The URL that `@clerk/clerk-js` should be hot-loaded from. | | `clerkJSVariant?` | "" \| "headless" | If your web application only uses Control Components, you can set this value to `'headless'` and load a minimal ClerkJS bundle for optimal page performance. | | `clerkJSVersion?` | `string` | The npm version for `@clerk/clerk-js`. | | `domain?` | string \| (url: URL) => string | **Required if your application is a satellite application**. Sets the domain of the satellite application. | | `experimental?` | `Autocomplete`\<\{ commerce: boolean; persistClient: boolean; rethrowOfflineNetworkErrors: boolean; \}, `Record`\<`string`, `any`\>\> | Enable experimental flags to gain access to new features. These flags are not guaranteed to be stable and may change drastically in between patch or minor versions. | | `initialState?` | `Serializable`\<\{ actor: undefined \| \{ \[x: string]: unknown; sub: string; \}; factorVerificationAge: \[number, number]; organization: undefined \| OrganizationResource; orgId: undefined \| string; orgPermissions: undefined \| string\[]; orgRole: undefined \| string; orgSlug: undefined \| string; session: undefined \| SessionResource; sessionClaims: JwtPayload; sessionId: undefined \| string; sessionStatus: SessionStatusClaim; user: undefined \| UserResource; userId: undefined \| string; \}\> | Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `isSatellite?` | boolean \| (url: URL) => boolean | A boolean that indicates whether the application is a satellite application. | | `localization?` | [`LocalizationResource`](/docs/guides/customizing-clerk/localization) | Optional object to localize your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `newSubscriptionRedirectUrl?` | null \| string | The URL to navigate to after the user completes the checkout and clicks the "Continue" button. | | `nonce?` | `string` | This nonce value will be passed through to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. | | `proxyUrl?` | string \| (url: URL) => string \| (url: URL) => string | **Required for applications that run behind a reverse proxy**. The URL that Clerk will proxy requests to. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). | | `publishableKey` | `string` | The Clerk Publishable 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. | | ~~`redirectUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl`, `signInForceRedirectUrl`, `signUpFallbackRedirectUrl`, or `signUpForceRedirectUrl` instead. | | `routerPush?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "push" navigation. | | `routerReplace?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "replace" navigation. | | `sdkMetadata?` | \{ environment?: string; name: string; version: string; \} | Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `sdkMetadata.environment?` | `string` | Typically this will be the `NODE_ENV` that the SDK is currently running in. | | `sdkMetadata.name` | `string` | The npm package name of the SDK. | | `sdkMetadata.version` | `string` | The npm package version of the SDK. | | `selectInitialSession?` | (client: ClientResource) => null \| SignedInSessionResource | By default, the last signed-in session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. | | `signInFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signInForceRedirectUrl?` | null \| string | 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. | | `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. | | `signUpFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signUpForceRedirectUrl?` | null \| string | 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. | | `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. | | `standardBrowser?` | `boolean` | By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. | | `supportEmail?` | `string` | Optional support email for display in authentication screens. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `taskUrls?` | `Record`\<`"choose-organization"`, `string`\> | Customize the URL paths users are redirected to after sign-in or sign-up when specific session tasks need to be completed. When `undefined`, it uses Clerk's default task flow URLs. Defaults to `undefined`. | | `telemetry?` | false \| \{ debug?: boolean; disabled?: boolean; perEventSampling?: boolean; \} | Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. | | `touchSession?` | `boolean` | By default, the [Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/Sessions#operation/touchSession) is called during page focus to keep the last active session alive. This option allows you to disable this behavior. | | `waitlistUrl?` | `string` | The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). | ## SDK-specific properties ### Next.js * `dynamic` * `boolean` Indicates whether or not Clerk should make dynamic auth data available based on the current request. Defaults to `false`. Opts the application into dynamic rendering when `true`. For more information, see [Next.js rendering modes and Clerk](/docs/guides/development/rendering-modes). ### Chrome Extension * `syncHost` * `string` To enable, pass the URL of the web application that the extension will sync the authentication state from. See the dedicated guide for more information. --- title: Component Reference description: A list of Clerk's comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: react, nextjs, js-frontend, chrome-extension, expo, android, expressjs, fastify, react-router, remix, tanstack-react-start, go, astro, nuxt, vue, ruby, js-backend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/overview lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: react,nextjs,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend notAvailableSdks: ios activeSdk: nextjs sourceFile: /docs/reference/components/overview.mdx --- Clerk offers a comprehensive suite of components designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk components, you can easily customize the appearance of authentication components and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Authentication components * \ * \ * \ * \ * \ ## User components * \ * \ * \ ## Organization components * \ * \ * \ * \ ## Billing components * \ * \ * \ * \ ## Control components Control components manage authentication-related behaviors in your application. They handle tasks such as controlling content visibility based on user authentication status, managing loading states during authentication processes, and redirecting users to appropriate pages. Control components render at `` and `` states for assertions on the Clerk object. A common example is the \ component, which allows you to conditionally render content only when a user is authenticated. * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ * \ ## Unstyled components * \ * \ * \ * \ ## Customization guides * [Customize components with the `appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview) * [Localize components with the `localization` prop (experimental)](/docs/guides/customizing-clerk/localization) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/user-profile) * [Add pages to the `` component](/docs/guides/customizing-clerk/adding-items/organization-profile) ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk components. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`` component" description: The component renders a waitlist form that allows users to join for early access to your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/waitlist lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/authentication/waitlist.mdx --- ![The \ component renders a form that allows users to join for early access to your app.](/docs/images/ui-components/waitlist.png){{ style: { maxWidth: '460px' } }} In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. [Learn more about additional features available in **Waitlist** mode](/docs/guides/secure/restricting-access#waitlist). The `` component renders a form that allows users to join for early access to your app. > \[!NOTE] > If you're using Next.js, the`` component is available in `@clerk/nextjs@6.2.0` and above. ## Enable Waitlist mode Before using the `` component, you must enable **Waitlist** mode in the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. ## Example > \[!WARNING] > Before using the `` component, you must provide the `waitlistUrl` prop either in the \ or \ component to ensure proper functionality. The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/waitlist/[[...waitlist]]/page.tsx' }} import { Waitlist } from '@clerk/nextjs' export default function WaitlistPage() { return } ``` ## Properties All props are optional. * `afterJoinWaitlistUrl` * `string` The full URL or path to navigate to after joining the waitlist. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `signInUrl` * `string` The full URL or path to the sign in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. ## Customization To learn about how to customize Clerk components, see the [customization guide](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component renders a UI for signing up users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/authentication/sign-up.mdx --- ![The \ component renders a UI for signing up users.](/docs/images/ui-components/sign-up.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for signing up users. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. If you would like to create a dedicated `/sign-up` page in your Next.js application, there are a few requirements you must follow. See the dedicated guide for more information. ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { SignUp, useUser } from '@clerk/nextjs' export default function Home() { const { isSignedIn } = useUser() if (!isSignedIn) { return } return
Welcome!
} ```
## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `string` If provided, this URL will always be used as the redirect destination 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. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-up`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signInFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. Used for the 'Already have an account? Sign in' link that's rendered. 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. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signInUrl` * `string` The full URL or path to the sign-in page. Used for the 'Already have an account? Sign in' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for signing in users. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/authentication/sign-in.mdx --- ![The \ component renders a UI for signing in users.](/docs/images/ui-components/sign-in.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI to allow users to sign in or sign up by default. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). You can further customize your `` component by passing additional properties at the time of rendering. > \[!NOTE] > The `` and `` components cannot render when a user is already signed in, unless the application allows multiple sessions. If a user is already signed in and the application only allows a single session, Clerk will redirect the user to the Home URL instead. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. If you would like to create a dedicated `/sign-in` page in your Next.js application, there are a few requirements you must follow. See the dedicated guide for more information. ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { SignIn, useUser } from '@clerk/nextjs' export default function Home() { const { isSignedIn } = useUser() if (!isSignedIn) { return } return
Welcome!
} ```
## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `fallbackRedirectUrl` * `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. *** * `forceRedirectUrl` * `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. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/sign-in`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `signUpFallbackRedirectUrl` * `string` The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. Used for the 'Don't have an account? Sign up' link that's rendered. Defaults to `/`. 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 used as the redirect destination after the user signs up. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `signUpUrl` * `string` The full URL or path to the sign-up page. Used for the 'Don't have an account? Sign up' link that's rendered. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `transferable` * `boolean` Indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `waitlistUrl` * `string` Full URL or path to the waitlist page. Use this property to provide the target of the 'Waitlist' link that's rendered. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). If you've passed the `waitlistUrl` prop to the \ component, it will infer from that, and you can omit this prop. *** * `withSignUp` * `boolean` Opt into sign-in-or-up flow by setting this prop to `true`. When `true`, if a user does not exist, they will be prompted to sign up. If a user exists, they will be prompted to sign in. Defaults to `true` if the `CLERK_SIGN_IN_URL` environment variable is set. Otherwise, defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a UI for authenticating users with Google's One Tap API. sdk: astro, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/google-one-tap lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: chrome-extension,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/authentication/google-one-tap.mdx --- > \[!IMPORTANT] > To use Google One Tap with Clerk, you must [enable Google as a social connection in the Clerk Dashboard](/docs/guides/configure/auth-strategies/social-connections/google#configure-for-your-production-instance) and make sure to use custom credentials. The `` component renders the [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) UI so that users can use a single button to sign-up or sign-in to your Clerk application with their Google accounts. By default, this component will redirect users back to the page where the authentication flow started. However, you can override this with force redirect URL props or [force redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). > \[!TIP] > `` does not render if the user is already signed into your Clerk application, so there's no need to manually check if a user is signed in yourself before rendering it. ## Example The following example includes basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx' }} import { GoogleOneTap } from '@clerk/nextjs' export default function Page() { return } ``` ## Properties * `cancelOnTapOutside?` * `boolean` If `true`, the One Tap prompt closes automatically if the user clicks outside of the prompt. Defaults to `true`. *** * `itpSupport?` * `boolean` If `true`, enables the [ITP-specific UX](https://developers.google.com/identity/gsi/web/guides/itp) when One Tap is rendered on ITP browsers such as Chrome on iOS, Safari, and FireFox. Defaults to `true`. *** * `fedCmSupport?` * `boolean` If `true`, enables Google One Tap to use [the FedCM API](https://developers.google.com/privacy-sandbox/3pcd/fedcm) to sign users in. See Google's docs on [best practices when disabling FedCM support](https://developers.google.com/identity/gsi/web/guides/display-google-one-tap#do_not_cover_google_one_tap). Defaults to `true` *** * `signInForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs in, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). *** * `signUpForceRedirectUrl?` * `string` Useful if you want to redirect to a path specific to Google One Tap users. If provided, this URL will **always** be redirected to after the user signs up, overriding any \ redirect URL props or [redirect URL environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects). ## Limitations * If your application will use the Google API on behalf of your users, the `` component is not recommended, as Google does not provide Clerk with an access or refresh token that you can use. * Users with the 1Password browser extension may not be able to render the Google One Tap UI. They must disable this extension. * When testing in development, if you select the `X` button to close the Google One Tap UI, you may encounter [a cooldown](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown) that prevents you from rendering it again for a period of time. To bypass the cooldown, remove the `g_state` cookie. --- title: "`` component" description: Clerk's component renders a UI for resolving the `choose-organization` task. sdk: js-frontend, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/authentication/task-choose-organization lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: chrome-extension,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/authentication/task-choose-organization.mdx --- ![The \ component renders a UI for resolving the choose-organization session task.](/docs/images/ui-components/task-choose-organization.png){{ style: { maxWidth: '460px' } }} The `` component renders a UI for resolving the `choose-organization` session task. The functionality of the `` component is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/overview). You can further customize your `` component by passing additional properties at the time of rendering. > \[!IMPORTANT] > The `` component cannot render when a user doesn't have current session tasks. ## Example The following example demonstrates how to host the `` component on a custom page. ```tsx {{ filename: 'app/layout.tsx', mark: [7] }} import { ClerkProvider } from '@clerk/nextjs' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` The `` component must be used in conjunction with the `` component. See the dedicated guide on how to self-host the `` component. ```tsx {{ filename: 'app/onboarding/choose-organization/page.tsx' }} import { TaskChooseOrganization } from '@clerk/nextjs' export default function Page() { return } ``` ## Properties All props are optional. * `redirectUrlComplete` * `string` The full URL or path to navigate to after successfully completing all tasks. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`` component" description: Clerk's component renders a button that opens the checkout drawer for Plan subscriptions. sdk: react, nextjs, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/checkout-button lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react,nextjs,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/billing/checkout-button.mdx --- ![The \ component renders a button that opens the checkout drawer.](/docs/images/ui-components/checkout-button.png) The `` component renders a button that opens the checkout drawer when selected, allowing users to subscribe to a Plan for either their Personal Account or an Organization. It must be wrapped inside a \ component to ensure the user is authenticated. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. ## Usage `` must be wrapped inside a \ component to ensure the user is authenticated. ```tsx <> // ❌ This will throw an error // ✅ Correct usage ``` `` will throw an error if the `for` prop is set to `'organization'` and no Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. is set. ```tsx <> // ❌ This will throw an error if no Organization is active // ✅ Correct usage {auth.orgId ? : null} ``` `` preserves any click handlers attached to custom button elements, while maintaining the checkout drawer functionality. ```tsx ``` ### Examples ```tsx {{ filename: 'app/pricing/page.tsx' }} 'use client' import { SignedIn } from '@clerk/nextjs' import { CheckoutButton } from '@clerk/nextjs/experimental' export default function PricingPage() { return ( {/* Basic usage */} {/* Customizes the appearance of the checkout drawer */} {/* Custom button */} { console.log('Subscription completed!') }} newSubscriptionRedirectUrl="/dashboard" > ) } ``` ## Properties * `planId` * `string` The ID of the Plan to subscribe to. *** * `planPeriod?` * `'month' | 'annual'` The billing period for the subscription. *** * `for?` * `'user' | 'organization'` Determines whether the subscription is for the current user or Organization. Defaults to `'user'`. *** * `children?` * `React.ReactNode` A custom button element. If not provided, defaults to a button with the text "Checkout". *** * `onSubscriptionComplete?` * `() => void` A callback function that is called when a subscription is successfully completed. *** * `newSubscriptionRedirectUrl?` * `string` The URL to redirect to after a successful subscription. *** * `checkoutProps?` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. For example: ``. --- title: "`` component" description: Clerk's component renders a button that opens the Plan details drawer. sdk: react, nextjs, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/plan-details-button lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react,nextjs,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/billing/plan-details-button.mdx --- ![The \ component renders a button that opens the Plan details drawer.](/docs/images/ui-components/plan-details.png){{ style: { maxWidth: '460px' } }} The `` component renders a button that opens the Plan details drawer, allowing users to view detailed information about a specific Plan, including pricing, Features, and other Plan-specific details. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. ## Usage `` preserves any click handlers attached to custom button elements, while maintaining the Plan details drawer functionality. ```tsx ``` `` supports rendering the Plan details drawer in a custom portal container. ```tsx {{ prettier: false }} const portalRoot = document.getElementById('custom-portal') ``` ### Examples ```tsx {{ filename: 'app/pricing/page.tsx' }} 'use client' import { PlanDetailsButton } from '@clerk/nextjs/experimental' export default function PricingPage() { return (
{/* Basic usage with Plan ID */} {/* Customizes the appearance of the Plan details drawer */} {/* Custom button */}
) } ```
## Properties * `planId?` * `string` The ID of the Plan to display details for. It is required if `plan` is not provided. *** * `plan?` * BillingPlanResource The Plan to display details for. It is used as initial data until the Plan is fetched from the server. *** * `children?` * `React.ReactNode` Optional custom button element. If not provided, defaults to a button with the text "Plan details". *** * `initialPlanPeriod?` * `'month' | 'annual'` Optional prop to set the initial billing period view when the Plan details drawer opens. *** * `planDetailsProps?` * `{ appearance: Appearance }` Options for the Plan details drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. For example: ``. --- title: "``" description: Clerk's component displays a table of Plans and Features that users can subscribe to. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/pricing-table lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/billing/pricing-table.mdx --- ![The \ component displays a table of Plans and Features that users can subscribe to.](/docs/images/ui-components/pricing-table.png) The `` component displays a table of Plans and Features that users can subscribe to. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```tsx {{ filename: 'app/pricing/page.tsx' }} import { PricingTable } from '@clerk/nextjs' export default function Page() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `checkoutProps` * `{ appearance: Appearance }` Options for the checkout drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `collapseFeatures` * `boolean` A boolean that indicates whether the Features are collapsed. **Requires `layout` to be set to `'default'`**. Defaults to `false`. *** * `ctaPosition` * `'top' | 'bottom'` The placement of the CTA button. **Requires `layout` to be set to `'default'`**. Defaults to `'bottom'`. *** * `fallback` * `JSX` An optional UI to show when the pricing table is loading. *** * `for` * `'user' | 'organization'` A string that indicates whether the pricing table is for users or [Organizations](/docs/guides/organizations/overview). If `'user'`, the pricing table will display a list of Plans and Features that **users** can subscribe to. If `'organization'`, the pricing table will display a list of Plans and Features that **Organizations** can subscribe to. Defaults to `'user'`. *** * `newSubscriptionRedirectUrl` * `string` The URL to navigate to after the user completes the checkout and selects the "Continue" button. --- title: "`` component" description: Clerk's component renders a button that opens the subscription details drawer. sdk: react, nextjs, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/billing/subscription-details-button lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react,nextjs,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/billing/subscription-details-button.mdx --- ![The \ component renders a button that opens the subscription details drawer.](/docs/images/ui-components/subscription.png) The `` component renders a button that opens the subscription details drawer when selected, allowing users to view and manage their subscription details, whether for their Personal Account or Organization. It must be wrapped inside a \ component to ensure the user is authenticated. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. ## Usage `` must be wrapped inside a \ component to ensure the user is authenticated. ```tsx <> // ❌ This will throw an error // ✅ Correct usage ``` `` will throw an error if the `for` prop is set to `'organization'` and no Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. is set. ```tsx <> // ❌ This will throw an error if no Organization is active // ✅ Correct usage {auth.orgId ? : null} ``` ### Examples ```tsx {{ filename: 'app/billing/page.tsx' }} 'use client' import { SignedIn } from '@clerk/nextjs' import { SubscriptionDetailsButton } from '@clerk/nextjs/experimental' export default function BillingPage() { return ( {/* Basic usage */} {/* Customizes the appearance of the subscription details drawer */} {/* Custom button */} console.log('Subscription canceled')}> ) } ``` ## Properties All props are optional. * `for?` * `'user' | 'organization'` Determines whether to show subscription details for the current user or Organization. Defaults to `'user'`. *** * `children?` * `React.ReactNode` Optional custom button element. If not provided, defaults to a button with the text "Subscription details". *** * `onSubscriptionCancel?` * `() => void` A callback function that is called when a subscription is cancelled. *** * `subscriptionDetailsProps?` * `{ appearance: Appearance }` Options for the subscription details drawer. Accepts the following properties: * [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview): an object used to style your components. For example: ``. --- title: \RedirectCallback /> description: Clerk's `` component is used to implement custom OAuth flows. It handles the OAuth callback and completes the authentication process. sdk: astro, chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/authenticate-with-redirect-callback lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: expo,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/authenticate-with-redirect-callback.mdx --- The `` component is a crucial part of implementing custom OAuth flows in your application. It serves as the callback handler for the authentication process initiated by the `authenticateWithRedirect()` method. Render it on the route specified as the `redirectUrl` in your `authenticateWithRedirect()` call. This component automatically handles the OAuth callback, completing the authentication process and managing the user's session. It uses the handleRedirectCallback() method under the hood. ## Example For an example of how to use the `` component, see the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) guide. ## Properties All props are optional. * `continueSignUpUrl?` * `string | undefined | null` The full URL or path to navigate to if the sign up requires additional information. *** * `signInUrl?` * `string` The full URL or path where the `` component is mounted. *** * `signUpUrl?` * `string` The full URL or path where the `` component is mounted. *** * `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. *** * `firstFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if first factor verification is required. *** * `secondFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) is enabled. *** * `resetPasswordUrl?` * `string` The full URL or path to navigate to during sign in, if the user is required to reset their password. *** * `transferable?` * `boolean` A boolean that indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `verifyEmailAddressUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting email verification. *** * `verifyPhoneNumberUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting phone verification. --- title: "``" description: The component indicates that the Clerk object has failed to load. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-failed lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/clerk-failed.mdx --- The `` component indicates that the Clerk object has failed to load. This is useful for displaying an error message to the user. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'app/page.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/nextjs' export default function Page() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ``` ```tsx {{ filename: 'pages/index.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/nextjs' export default function Page() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The component indicates that Clerk is partially operational. sdk: nextjs, react, react-router, chrome-extension, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-degraded lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: nextjs,react,react-router,chrome-extension,remix,tanstack-react-start notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/clerk-degraded.mdx --- The `` component indicates that Clerk is partially operational. ## Example It's not recommended to wrap the entire app in control components; instead, only wrap the components that need access to the `Clerk` object, such as custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. ```tsx {{ filename: 'app/page.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/nextjs' export default function Page() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ``` ```tsx {{ filename: 'pages/index.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/nextjs' export default function Page() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "`` (deprecated)" description: The component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/redirect-to-create-organization.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToCreateOrganization() method instead. The `` component will navigate to the create Organization flow which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/page.tsx' }} import { SignedIn, SignedOut, RedirectToCreateOrganization } from '@clerk/nextjs' export default function Page() { return ( <> You need to sign in to create an Organization. ) } ``` --- title: "``" description: The Protect component protects content or even entire routes based on authentication, and optionally, authorization. It only renders its children when the current user is signed-in, and if performing authorization checks, if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan). sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/protect lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/protect.mdx --- The \ component protects content or even entire routes based on: * authentication: whether the user is signed-in or not. * authorization: whether the user has been granted a specific type of access control (Role, Permission, Feature, or Plan) `` **always** performs authentication checks. To perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., you can pass different props, like `role`, `permission`, `feature`, or `plan`. `` accepts a `fallback` prop that will be rendered if the user fails the authentication or authorization checks. `` can be used both client-side and server-side (in Server Components). > \[!CAUTION] > This component only **visually hides** its children when the current user is not authorized. The contents of its children remain accessible via the browser's source code even if the user fails the authorization check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Usage ### Authentication checks `` always performs authentication checks. It will render its children if the user is signed-in, and its `fallback` prop if the user is signed-out. ```tsx {{ filename: 'app/dashboard/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function Page() { return ( Users that are signed-out can see this.

}>

Users that are signed-in can see this.

) } ```
### Authorization checks To limit who is able to see the content that `` renders, you can pass **one** of the access control props: `permission`, `role`, `feature`, or `plan`. It's recommended to use **Permission-based** authorization over **Role-based** authorization, and **Feature-based** authorization over **Plan-based** authorization, as they are more flexible, easier to manage, and more secure. If you do not pass any of the access control props, `` will render its children if the user is signed in, regardless of their Role or its Permissions. For more complex authorization logic, pass conditional logic to the `condition` prop. ### Render content by Permissions The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:invoices:create` Permission. ```jsx {{ filename: 'app/protected/invoices/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function Page() { return ( You do not have the Permissions to create an invoice.

} >

Users with Permission org:invoices:create can see this.

) } ```
### Render content by Role While authorization by `permission` is **recommended**, for convenience, `` allows a `role` prop to be passed. The following example demonstrates how to use the `` component to protect content by checking if the user has the `org:billing` Role. ```jsx {{ filename: 'app/protected/billing/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function ProtectPage() { return ( Only a member of the Billing department can access this content.

} >

Users with Role org:billing can see this.

) } ```
### Render content by Plan The following example demonstrates how to use `` to protect content by checking if the user has a Plan. ```tsx {{ filename: 'app/protected/bronze/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function ProtectPage() { return ( Sorry, only subscribers to the Bronze plan can access this content.

} >

Welcome, Bronze subscriber!

) } ```
### Render content by Feature The following example demonstrates how to use `` to protect content by checking if the user has a Feature. ```tsx {{ filename: 'app/protected/premium-access/page.tsx' }} import { Protect } from '@clerk/nextjs' export default function Page() { return ( Sorry, only subscribers with the Premium Access feature can access this content.

} >

Congratulations! You have access to the Premium Access feature.

) } ```
### Render content conditionally The following example uses ``'s `condition` prop to conditionally render its children if the user has the correct Role. ```tsx {{ filename: 'app/dashboard/settings/page.tsx' }} import type { PropsWithChildren } from 'react' import { Protect } from '@clerk/nextjs' export default function Page() { return ( has({ role: 'org:admin' }) || has({ role: 'org:billing_manager' })} fallback={

Only an Admin or Billing Manager can access this content.

} >

The settings page.

) } ```
## Properties * `condition?` * `has => boolean` Optional conditional logic that renders the children if it returns `true`. *** * `fallback?` * `JSX` Optional UI to show when a user doesn't have the correct type of access control to access the protected content. *** * `feature?` * `string` Optional string corresponding to a [Feature](/docs/guides/billing/overview). *** * `plan?` * `string` Optional string corresponding to a [Plan](/docs/guides/billing/overview). *** * `permission?` * `string` Optional string corresponding to a [Permission](/docs/guides/organizations/roles-and-permissions) in the format `org::` *** * `role?` * `string` Optional string corresponding to a [Role](/docs/guides/organizations/roles-and-permissions) in the format `org:` *** * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "``" description: The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loading lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/clerk-loading.mdx --- The `` renders its children while Clerk is loading, and is helpful for showing a custom loading state. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/page.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/nextjs' export default function Page() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ``` ```tsx {{ filename: 'pages/index.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/nextjs' export default function Page() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "``" description: The `` component guarantees that the Clerk object has loaded and will be available under `window.Clerk`. This allows you to wrap child components to access the Clerk object without the need to check it exists. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/clerk-loaded lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/clerk-loaded.mdx --- The `` component guarantees that the Clerk object has loaded (the `status` is `'ready'` or `'degraded'`) and will be available under `window.Clerk`. This allows you to wrap child components to access the `Clerk` object without the need to check it exists. ## Example It's not recommended to wrap the entire app in the `` component; instead, only wrap the components that need access to the `Clerk` object. ```tsx {{ filename: 'app/page.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/nextjs' export default function Page() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ``` ```tsx {{ filename: 'pages/index.tsx' }} import { ClerkLoaded, ClerkLoading, ClerkDegraded, ClerkFailed } from '@clerk/nextjs' export default function Page() { return ( <>

Clerk is loading...

Clerk has loaded (ready or degraded)

Clerk is experiencing issues. Please try again later.

Something went wrong with Clerk. Please contact support.

) } ```
--- title: "`` (deprecated)" description: The component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/redirect-to-organization-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToOrganizationProfile() method instead. The `` component will navigate to the Organization profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/page.tsx' }} import { SignedIn, SignedOut, RedirectToOrganizationProfile } from '@clerk/nextjs' export default function Page() { return ( <> You need to sign in to view your Organization profile. ) } ``` --- title: "``" description: The component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/redirect-to-sign-in.mdx --- The `` component will navigate to the sign in URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/page.tsx' }} import { SignedIn, SignedOut, RedirectToSignIn, UserButton } from '@clerk/nextjs' export default function Page() { return ( <> ) } ``` --- title: "``" description: The component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/redirect-to-sign-up.mdx --- The `` component will navigate to the sign up URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. ## Example ```tsx {{ filename: 'app/page.tsx' }} import { SignedIn, SignedOut, RedirectToSignUp, UserButton } from '@clerk/nextjs' export default function Page() { return ( <> ) } ``` --- title: "``" description: The component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: chrome-extension, nextjs, nuxt, react, react-router, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-tasks lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,nextjs,nuxt,react,react-router,tanstack-react-start,vue notAvailableSdks: js-frontend,expo,android,ios,expressjs,fastify,remix,go,astro,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/redirect-to-tasks.mdx --- The `` component will navigate to the tasks flow which has been configured in your application instance when users have pending session tasks**Session tasks** are requirements that users must fulfill in order to complete the authentication process, such as choosing an Organization.. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. The `` component is primarily intended for use in custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. If you're using prebuilt components, you typically won't need to use `` as these components manage task redirection internally. [See the guide on handling session tasks outside of prebuilt components](/docs/guides/configure/session-tasks#redirecting-to-tasks). ## Example ```tsx {{ filename: 'app/layout.tsx' }} import { SignedOut, RedirectToTasks } from '@clerk/nextjs' export default function Layout({ children }: { children: React.ReactNode }) { return ( <> {children} ) } ``` --- title: "``" description: Conditionally render content only when a user is signed in. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/signed-in.mdx --- ## Overview The `` component offers authentication checks as a cross-cutting concern. Any children components wrapped by a `` component will be rendered only if there's a user with an active session signed in your application. > \[!CAUTION] > This component only **visually hides** its children when the current user is not authenticated. The contents of its children remain accessible via the browser's source code even if the user fails the authentication check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). on the server before sending the data to the client. ## Example ```tsx {{ filename: 'app/page.tsx' }} import { SignedIn } from '@clerk/nextjs' export default function Page() { return ( <>
You are signed in.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` (deprecated)" description: The component will navigate to the user profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. sdk: nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/redirect-to-user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/redirect-to-user-profile.mdx --- > \[!WARNING] > This feature is deprecated. Please use the redirectToUserProfile() method instead. The `` component will navigate to the Account Portal User Profile URL which has been configured in your application instance. The behavior will be just like a server-side (3xx) redirect, and will override the current location in the history stack. To find your User Profile URL: 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Under **User profile**, select the **Visit** icon. ## Example ```tsx {{ filename: 'app/page.tsx' }} import { SignedIn, SignedOut, RedirectToUserProfile } from '@clerk/nextjs' function Page() { return ( <>

You need to sign in to view your user profile.

) } ```
--- title: "``" description: Conditionally render content only when a user is signed out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/control/signed-out lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/control/signed-out.mdx --- The `` component offers authentication checks as a cross-cutting concern. Any child nodes wrapped by a `` component will be rendered only if there's no User signed in to your application. ## Example ```tsx {{ filename: 'app/page.tsx' }} import { SignedOut } from '@clerk/nextjs' export default function Page() { return ( <>
You are signed out.

This content is always visible.

) } ```
## Properties * `treatPendingAsSignedOut?` * `boolean` A boolean that indicates whether to treat pending sessions as signed out. Defaults to `true`. --- title: "`` component" description: Clerk's component is used to render an Organization creation UI that allows users to create brand new Organizations within your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/organization/create-organization.mdx --- ![The \ component renders an Organization creation UI that allows users to create brand new organizations within your application.](/docs/images/ui-components/create-organization.png){{ style: { maxWidth: '492px' } }} The `` component is used to render an Organization creation UI that allows users to create brand new Organizations in your application. ## Example The following example includes a basic implementation of the `` component. You can use this as a starting point for your own implementation. ```jsx {{ filename: 'app/create-organization/[[...create-organization]]/page.tsx' }} import { CreateOrganization } from '@clerk/nextjs' export default function CreateOrganizationPage() { return } ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterCreateOrganizationUrl` * `string` Full URL or path to navigate to after creating a new organization. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/create-organization`. *** * `skipInvitationScreen` * `boolean` Hides the screen for sending invitations after an Organization is created. When left undefined, Clerk will automatically hide the screen if the number of max allowed members is equal to 1 *** * `hideSlug` * `boolean` Hides the optional slug field in the Organization creation screen. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to display Organization related memberships, invitations, and suggestions for the user. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/organization/organization-list.mdx --- ![The \ component displays Organization-related memberships and automatic invitations and suggestions for the user.](/docs/images/ui-components/organization-list.png){{ style: { maxWidth: '460px' } }} The `` component displays Organization-related memberships and automatic [invitations](/docs/guides/organizations/verified-domains#automatic-invitations) and [suggestions](/docs/guides/organizations/verified-domains#automatic-suggestions) for the user. ## Example ```jsx {{ filename: 'app/organizations/page.tsx' }} import { OrganizationList } from '@clerk/nextjs' export default function OrganizationListPage() { return ( ) } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after creating a new Organization. *** * `afterSelectOrganizationUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting an Organization. Defaults to `undefined`. *** * `afterSelectPersonalUrl` * ((org: Organization) => string) | string The full URL or path to navigate to after selecting the [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts). Defaults to `undefined`. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. Defaults to `false`. *** * `skipInvitationScreen` * `boolean | undefined` A boolean that controls whether the screen for sending invitations after an Organization is created is hidden. When `undefined`, Clerk will automatically hide the screen if the number of max allowed members is equal to 1. Defaults to `false`. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [org-ref]: /docs/reference/javascript/organization --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured Organization management UI that allows users to manage their Organization profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-profile lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/organization/organization-profile.mdx --- ![The \ component allows users to manage their Organization membership and security settings.](/docs/images/ui-components/organization-profile.png) The `` component allows users to manage their Organization membership, security, and billing settings. This component's **General** tab displays the Organization's information and the **Leave organization** button. Admins will be able to see the **Update profile** button, **Verified domains** section, and **Delete organization** button. The **Members** tab shows the Organization's members along with their join dates and Roles. Admins will have the ability to invite a member, change a member's Role, or remove them from the Organization. Admins will have tabs within the **Members** tab to view the Organization's [invitations](/docs/guides/organizations/overview#organization-invitations) and [requests](/docs/guides/organizations/verified-domains#membership-requests). The **Billing** tab displays the Plans and Features that are available to the Organization, as well as the user's billing information, such as their invoices and payment methods. ## Example The `` component must be embedded using the [Next.js optional catch-all route](https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes#optional-catch-all-routes) in order for the routing to work. ```jsx {{ filename: 'app/organization-profile/[[...organization-profile]]/page.tsx' }} import { OrganizationProfile } from '@clerk/nextjs' export default function OrganizationProfilePage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after leaving an Organization. *** * `customPages` * `CustomPages[]` An array of custom pages to add to the Organization profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/organization-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash- and virtual-based routing.
For example: `/organization-profile`. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages.
Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React.
## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages](/docs/guides/customizing-clerk/adding-items/organization-profile) documentation. --- title: "`` component" description: Clerk's component is used to enable the ability to switch between available Organizations the user may be part of in your application. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/organization/organization-switcher lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/organization/organization-switcher.mdx --- ![The \ component allows a user to switch between their account types - their Personal Account and their joined Organizations.](/docs/images/ui-components/organization-switcher.png){{ style: { maxWidth: '436px' } }} The `` component allows a user to switch between their joined Organizations. If [Personal Accounts are enabled](/docs/guides/organizations/overview#allow-personal-accounts), users can also switch to their Personal Account. This component is useful for applications that have a multi-tenant architecture, where users can be part of multiple Organizations. It handles all Organization-related flows, including full Organization management for admins. Learn more about [Organizations](/docs/guides/organizations/overview). ## Example ```jsx {{ filename: 'app/organization-switcher/[[...organization-switcher]]/page.tsx' }} import { OrganizationSwitcher } from '@clerk/nextjs' export default function OrganizationSwitcherPage() { return } ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterCreateOrganizationUrl` * `string` The full URL or path to navigate to after creating a new Organization. *** * `afterLeaveOrganizationUrl` * `string` The full URL or path to navigate to after the user leaves the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `afterSelectOrganizationUrl` * `string` The full URL or path to navigate to after a successful Organization switch. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `createOrganizationMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the "Create organization" button will cause the \ component to open as a modal, or if the browser will navigate to the `createOrganizationUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `createOrganizationUrl` * `string` The full URL or path where the ``]createorg-ref component is mounted. *** * `defaultOpen` * `boolean` A boolean that controls the default state of the `` component. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. *** * `hidePersonal` * `boolean` A boolean that controls whether `` will include the user's [Personal Account](/docs/guides/organizations/overview#allow-personal-accounts) in the Organization list. Setting this to `true` will hide the Personal Account option, and users will only be able to switch between Organizations. Defaults to `false`. *** * `hideSlug` * `boolean` A boolean that controls whether the optional slug field in the Organization creation screen is hidden. *** * `organizationProfileMode` * `'modal' | 'navigation'` A boolean that controls whether clicking the **Manage organization** button will cause the \ component to open as a modal, or if the browser will navigate to the `organizationProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `organizationProfileProps` * `object` Specify options for the underlying \ component. For example: `{appearance: {...}}` *** * `organizationProfileUrl` * `string` The full URL or path where the \ component is mounted. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). [createorg-ref]: /docs/reference/components/organization/create-organization [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "``" description: The component is a button that links to the sign-in page or displays the sign-in modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/unstyled/sign-in-button.mdx --- The `` component is a button that, by default, links to your app's sign-in page. Your sign-in page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-in page. ## Usage ### Basic usage ```jsx {{ filename: 'app/page.tsx' }} import { SignInButton } from '@clerk/nextjs' export default function Home() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```jsx {{ filename: 'pages/index.js' }} import { SignInButton } from '@clerk/nextjs' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-in route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'`. *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignInInitialValues The values used to prefill the sign-in fields with. --- title: "``" description: The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. sdk: expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-in-with-metamask lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,chrome-extension,android,ios,expressjs,fastify,go,astro,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/unstyled/sign-in-with-metamask.mdx --- The `` component is used to complete a one-click, cryptographically-secure sign-in flow using MetaMask. ## Usage ### Basic usage ```jsx {{ filename: 'app/page.tsx' }} import { SignInWithMetamaskButton } from '@clerk/nextjs' export default function Home() { return } ``` ### Custom usage In some cases, you will want to use your own button, or button text. You can do that by wrapping your button in the `` component. ```jsx {{ filename: 'pages/index.js' }} import { SignInWithMetamaskButton } from '@clerk/nextjs' export default function Home() { return ( ) } ``` --- title: "``" description: The `` component is a button that signs a user out. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-out-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/unstyled/sign-out-button.mdx --- The `` component is a button that signs a user out. By default, it is a ` ) } ``` ### Multi-session usage #### Sign out of all sessions Clicking the `` component signs the user out of all sessions. This is the default behavior. #### Sign out of a specific session You can sign out of a specific session by passing in a `sessionId` to the `sessionId` prop. This is useful for signing a single account out of a [multi-session application](/docs/guides/secure/session-options#multi-session-applications). In the following example, the `sessionId` is retrieved from the useAuth() hook. If the user is not signed in, the `sessionId` will be `null`, and the user is shown the \ component. If the user is signed in, the user is shown the `` component, which when clicked, signs the user out of that specific session. ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { SignInButton, SignOutButton, useAuth } from '@clerk/nextjs' export default function Home() { const { sessionId } = useAuth() if (!sessionId) { return } return } ``` ## Properties * `redirectUrl?` * `string` The full URL or path to navigate after successful sign-out. *** * `sessionId?` * `string` The ID of a specific session to sign out of. Useful for [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. --- title: "``" description: The component is a button that links to the sign-up page or displays the sign-up modal. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue sdkScoped: "true" canonical: /docs/:sdk:/reference/components/unstyled/sign-up-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/unstyled/sign-up-button.mdx --- The `` component is a button that, by default, links to your app's sign-up page. Your sign-up page will be hosted by Clerk using the [Account Portal](/docs/guides/customizing-clerk/account-portal) unless you have set up a dedicated sign-up page. ## Usage ### Basic usage ```jsx {{ filename: 'app/page.tsx' }} import { SignUpButton } from '@clerk/nextjs' export default function Home() { return } ``` ### Custom usage You can create a custom button by wrapping your own button, or button text, in the `` component. ```jsx {{ filename: 'app/page.tsx' }} import { SignUpButton } from '@clerk/nextjs' export default function Home() { return ( ) } ``` ## Properties * `forceRedirectUrl?` * `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. *** * `fallbackRedirectUrl?` * `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. *** * `oauthFlow` * `"redirect" | "popup" | "auto"` Determines how OAuth authentication is performed. Accepts the following properties: * `"redirect"`: Redirect to the OAuth provider on the current page. * `"popup"`: Open a popup window. * `"auto"`: Choose the best method based on whether the current domain typically requires the `"popup"` flow to correctly perform authentication. Defaults to `"auto"`. *** * `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. *** * `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. *** * `mode?` * `'redirect' | 'modal'` Determines what happens when a user clicks on the ``. Setting this to `'redirect'` will redirect the user to the sign-up route. Setting this to `'modal'` will open a modal on the current route. Defaults to `'redirect'` *** * `children?` * `React.ReactNode` Children you want to wrap the `` in. *** * `initialValues` * SignUpInitialValues The values used to prefill the sign-up fields with. *** * `unsafeMetadata` * SignUpUnsafeMetadata Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). --- title: "`` component" description: Clerk's component is used to render the familiar user avatar on its own. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-avatar lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/user/user-avatar.mdx --- ![The \ component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications.](/docs/images/ui-components/user-avatar.png) The `` component renders the authenticated user's avatar on its own, a common UI element found across many websites and applications. ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar. ```tsx {{ filename: 'layout.tsx' }} import { ClerkProvider, SignedIn, SignedOut, SignInButton, UserAvatar } from '@clerk/nextjs' function Header() { return (

My App

) } export default function RootLayout({ children }: { children: React.ReactNode }) { return (
{children} ) } ``` ```tsx {{ filename: 'pages/_app.tsx' }} import { ClerkProvider, SignedIn, SignedOut, SignInButton, UserAvatar } from '@clerk/nextjs' import type { AppProps } from 'next/app' function Header() { return (

My App

) } function MyApp({ pageProps, Component }: AppProps) { return (
) } export default MyApp ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `rounded?` * `boolean` Determines whether the user avatar is displayed with rounded corners. *** * `appearance?` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `fallback?` * `ReactNode` Optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). --- title: "`` component" description: Clerk's component is used to render the familiar user button UI popularized by Google. search: rank: 1 sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/user/user-button.mdx --- ![The \ component renders the familiar user button UI popularized by Google.](/docs/images/ui-components/user-button.png){{ style: { maxWidth: '436px' } }} The `` component renders the familiar user button UI popularized by Google. When selected, it opens a dropdown menu with options to manage account settings and sign out. The "Manage account" option launches the \ component, providing access to profile and security settings. For users that have [multi-session](/docs/guides/secure/session-options#multi-session-applications) enabled, the `` also allows users to sign into multiple accounts at once and instantly switch between them without the need for a full page reload. Learn more [here](/docs/guides/secure/session-options#multi-session-applications). ## Example In the following example, `` is mounted inside a header component, which is a common pattern on many websites and applications. When the user is signed in, they will see their avatar and be able to open the popup menu. ```tsx {{ filename: 'layout.tsx', mark: [8] }} import { ClerkProvider, SignedIn, SignedOut, SignInButton, UserButton } from '@clerk/nextjs' function Header() { return (

My App

) } export default function RootLayout({ children }: { children: React.ReactNode }) { return (
{children} ) } ``` ```tsx {{ filename: 'pages/_app.tsx', mark: [9] }} import { ClerkProvider, SignedIn, SignedOut, SignInButton, UserButton } from '@clerk/nextjs' import type { AppProps } from 'next/app' function Header() { return (

My App

) } function MyApp({ pageProps, Component }: AppProps) { return (
) } export default MyApp ``` ## Properties The `` component accepts the following properties, all of which are **optional**: * `afterMultiSessionSingleSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterMultiSessionSingleSignOutUrl` to \.** The full URL or path to navigate to after signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` (deprecated) * `string` **Deprecated. Move `afterSignOutUrl` to \.** The full URL or path to navigate to after a successful sign-out. *** * `afterSwitchSessionUrl` * `string` The full URL or path to navigate to after a successful account change in a multi-session app. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `defaultOpen` * `boolean` Controls whether the `` should open by default during the first render. *** * `showName` * `boolean` Controls if the user name is displayed next to the user image button. *** * `signInUrl` * `string` The full URL or path to navigate to when the **Add another account** button is clicked. It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. *** * `userProfileMode` * `'modal' | 'navigation'` Controls whether selecting the **Manage your account** button will cause the \ component to open as a modal, or if the browser will navigate to the `userProfileUrl` where `` is mounted as a page. Defaults to: `'modal'`. *** * `userProfileProps` * `object` Specify options for the underlying \ component. For example: `{additionalOAuthScopes: {google: ['foo', 'bar'], github: ['qux']}}`. *** * `userProfileUrl` * `string` The full URL or path leading to the user management interface. *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). You can also [add custom actions and links to the `` menu](/docs/guides/customizing-clerk/adding-items/user-button). --- title: "`` component" description: Clerk's component is used to render a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: astro, chrome-extension, expo, nextjs, nuxt, react, react-router, remix, tanstack-react-start, vue, js-frontend sdkScoped: "true" canonical: /docs/:sdk:/reference/components/user/user-profile lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,nuxt,react,react-router,remix,tanstack-react-start,vue,js-frontend notAvailableSdks: android,ios,expressjs,fastify,go,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/components/user/user-profile.mdx --- ![The \ component renders a full-featured account management UI that allows users to manage their profile and security settings.](/docs/images/ui-components/user-profile.png){{ style: { maxWidth: '100%' } }} The `` component is used to render a beautiful, full-featured account management UI that allows users to manage their profile, security, and billing settings. ## Example The `` component must be embedded using the [Next.js optional catch-all route](https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes#optional-catch-all-routes) in order for the routing to work. ```jsx {{ filename: 'app/user-profile/[[...user-profile]]/page.tsx' }} import { UserProfile } from '@clerk/nextjs' const UserProfilePage = () => export default UserProfilePage ``` ## Properties All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `routing` * `'hash' | 'path'` The [routing](/docs/guides/how-clerk-works/routing) strategy for your pages. Defaults to `'path'` for frameworks that handle routing, such as Next.js and Remix. Defaults to `hash` for all other SDK's, such as React. *** * `path` * `string` The path where the component is mounted on when `routing` is set to `path`. It is ignored in hash-based routing. For example: `/user-profile`. *** * `additionalOAuthScopes` * `object` Specify additional scopes per OAuth provider that your users would like to provide if not already approved. For example: `{google: ['foo', 'bar'], github: ['qux']}`. *** * `customPages` * CustomPage\[] An array of custom pages to add to the user profile. Only available for the JavaScript SDK. To add custom pages with React-based SDK's, see the [dedicated guide](/docs/guides/customizing-clerk/adding-items/user-profile). *** * `fallback?` * `ReactNode` An optional element to be rendered while the component is mounting. ## Customization To learn about how to customize Clerk components, see the [customization documentation](/docs/guides/customizing-clerk/appearance-prop/overview). In addition, you also can add custom pages and links to the `` navigation sidenav. For more information, refer to the [Custom Pages documentation](/docs/guides/customizing-clerk/adding-items/user-profile). --- title: useAuth() description: Access and manage authentication state in your application with Clerk's useAuth() hook. sdk: astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-auth.mdx --- The `useAuth()` hook provides access to the current user's authentication state and methods to manage the active session. > \[!NOTE] > To access auth data server-side, see the Auth object reference doc. By default, Next.js opts all routes into static rendering. If you need to opt a route or routes into dynamic rendering because you need to access the authentication data at request time, you can create a boundary by passing the `dynamic` prop to ``. See the [guide on rendering modes](/docs/guides/development/rendering-modes) for more information, including code examples. ## Parameters | Parameter | Type | Description | | ---------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `initialAuthStateOrOptions?` | null \| Record\ \| \{ treatPendingAsSignedOut?: boolean; \} | An object containing the initial authentication state or options for the `useAuth()` hook. If not provided, the hook will attempt to derive the state from the context. `treatPendingAsSignedOut` is a boolean that indicates whether pending sessions are considered as signed out or not. Defaults to `true`. | ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `undefined` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has` | `undefined` | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `undefined` | The ID of the user's active organization. | | `orgRole` | `undefined` | The current user's role in their active organization. | | `orgSlug` | `undefined` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `undefined` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `undefined` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `undefined` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | `null` | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (params: CheckAuthorizationParamsWithCustomPermissions) => false | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `null` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `null` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `null` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `null` | The ID of the user's active organization. | | `orgRole` | `null` | The current user's role in their active organization. | | `orgSlug` | `null` | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `actor` | null \| \{ \[x: string]: unknown; sub: string; \} | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `getToken()` | (options?: GetTokenOptions) => Promise\ | A function that retrieves the current user's session token or a custom JWT template. Returns a promise that resolves to the token. See the reference doc. | | `has()` | (isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean | A function that checks if the user has specific permissions or roles. See the reference doc. | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that indicates whether a user is currently signed in. | | `orgId` | `string` | The ID of the user's active organization. | | `orgRole` | `string` | The current user's role in their active organization. | | `orgSlug` | null \| string | The URL-friendly identifier of the user's active organization. | | `sessionClaims` | `JwtPayload` | The current user's [session claims](/docs/guides/sessions/session-tokens). | | `sessionId` | `string` | The ID for the current session. | | `signOut()` | \{ (options?: SignOutOptions): Promise\; (signOutCallback?: SignOutCallback, options?: SignOutOptions): Promise\; \} | A function that signs out the current user. Returns a promise that resolves when complete. See the reference doc. | | `userId` | `string` | The ID of the current user. | ## Example The following example demonstrates how to use the `useAuth()` hook to access the current auth state, like whether the user is signed in or not. It also includes a basic example for using the `getToken()` method to retrieve a session token for fetching data from an external resource. ```tsx {{ filename: 'app/external-data/page.tsx' }} 'use client' import { useAuth } from '@clerk/nextjs' export default function Page() { const { userId, sessionId, getToken, isLoaded, isSignedIn } = useAuth() const fetchExternalData = async () => { const token = await getToken() // Fetch data from an external API const response = await fetch('https://api.example.com/data', { headers: { Authorization: `Bearer ${token}`, }, }) return response.json() } // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

Hello, {userId}! Your current active session is {sessionId}.

) } ```
--- title: useClerk() description: Access and manage the Clerk object in your React application with Clerk's useClerk() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-clerk lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-clerk.mdx --- > \[!WARNING] > This hook should only be used for advanced use cases, such as building a completely custom OAuth flow or as an escape hatch to access to the `Clerk` object. The `useClerk()` hook provides access to the Clerk object, allowing you to build alternatives to any Clerk Component. ## Returns Clerk — The `useClerk()` hook returns the `Clerk` object, which includes all the methods and properties listed in the Clerk reference. ## Example The following example uses the `useClerk()` hook to access the `clerk` object. The `clerk` object is used to call the openSignIn() method to open the sign-in modal. ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { useClerk } from '@clerk/nextjs' export default function Page() { const clerk = useClerk() return } ``` --- title: Hooks Reference description: A list of Clerk's comprehensive suite of hooks for managing authentication, sessions, sign-in and sign-up flows, Organizations, and reverification. sdk: astro, chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro,chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/overview.mdx --- Clerk offers a comprehensive suite of hooks that expose low-level access to authentication, session management, and multi-tenancy. With Clerk hooks, you can access and manage user data, handle sign-in and sign-up flows, control session management, and implement advanced flows like session reverification for sensitive actions. By using these hooks, you can extend or replace Clerk's built-in components and customize how authentication behaves in your application. ## Hooks * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`useOrganizationList()`" description: Access and manage the current user's Organization list in your React application with Clerk's useOrganizationList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-organization-list.mdx --- The `useOrganizationList()` hook provides access to the current user's Organization memberships, invitations, and suggestions. It also includes methods for creating new Organizations and managing the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganizationList()` accepts a single object with the following properties: | Property | Type | Description | | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`userInvitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`userMemberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & object & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • Any of the properties described in Shared properties.
| |
`userSuggestions?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "pending" \| "accepted" \| ("pending" \| "accepted")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the suggestions by the provided status.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `userMemberships`, `userInvitations`, and `userSuggestions` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | ## Returns | Property | Type | Description | | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createOrganization` | undefined \| (CreateOrganizationParams: CreateOrganizationParams) => Promise\<OrganizationResource\> | A function that returns a `Promise` which resolves to the newly created `Organization`. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization and there is an authenticated user. Initially `false`, becomes `true` once Clerk loads with a user. | | `setActive` | undefined \| (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. | | `userInvitations` | PaginatedResourcesWithDefault\<UserOrganizationInvitationResource\> \| PaginatedResources\<UserOrganizationInvitationResource, T\["userInvitations"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization invitations. | | `userMemberships` | PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["userMemberships"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of the user's organization memberships. | | `userSuggestions` | PaginatedResourcesWithDefault\<OrganizationSuggestionResource\> \| PaginatedResources\<OrganizationSuggestionResource, T\["userSuggestions"] *extends* \{ infinite: true; \} ? true : false\> | Returns `PaginatedResources` which includes a list of suggestions for organizations that the user can join. | ### `CreateOrganizationParams` | Property | Type | Description | | ------------------------- | -------- | ----------------------------- | | `name` | `string` | The name of the organization. | | `slug?` | `string` | The slug of the organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expanding and paginating attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. So by default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // userMemberships.data will never be populated const { userMemberships } = useOrganizationList() // Use default values to fetch userMemberships, such as initialPage = 1 and pageSize = 10 const { userMemberships } = useOrganizationList({ userMemberships: true, }) // Pass your own values to fetch userMemberships const { userMemberships } = useOrganizationList({ userMemberships: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `userMemberships` attribute will be populated with the first page of the user's Organization memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```tsx {{ filename: 'components/JoinedOrganizations.tsx' }} 'use client' import { useOrganizationList } from '@clerk/nextjs' export const JoinedOrganizations = () => { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, }) // Handle loading state if (!isLoaded) return
Loading...
return ( <>
    {userMemberships.data?.map((mem) => (
  • {mem.organization.name}
  • ))}
) } ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `userInvitations` attribute will be populated with the first page of invitations. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of invitations. Notice the difference between this example's pagination and the infinite pagination example above. ```tsx {{ filename: 'components/UserInvitationsTable.tsx' }} 'use client' import { useOrganizationList } from '@clerk/nextjs' export const UserInvitationsTable = () => { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { infinite: true, keepPreviousData: true, }, }) // Handle loading state if (!isLoaded || userInvitations.isLoading) return
Loading...
return ( <> {userInvitations.data?.map((inv) => ( ))}
Email Org name
{inv.emailAddress} {inv.publicOrganizationData.name}
) } ```
## Related guides * [Build a custom Organization switcher](/docs/guides/development/custom-flows/organizations/organization-switcher) * Use Clerk's API to build a custom flow for switching between Organizations *** * [Create Organizations](/docs/guides/development/custom-flows/organizations/create-organizations) * Use Clerk's API to build a custom flow for creating Organizations *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: "`useCheckout()`" description: Clerk's useCheckout() hook provides state and methods to manage a Subscription checkout flow. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-checkout lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-checkout.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `useCheckout()` hook is used to create, manage, and confirm a checkout session for a user or an Organization's Subscription Plan. It provides the state of the current checkout process, such as its status and any errors, along with methods to initiate and complete the checkout. There are two ways to use `useCheckout()`: 1. In conjunction with \ to create a shared checkout context. All child components inside the provider can then use `useCheckout()` to access or update the same checkout state. 2. On its own by passing configuration options directly to it. This is ideal for self-contained components that handle their own checkout flow without needing a shared context. ## Parameters | Parameter | Type | Description | | ---------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `options?` | `PropsWithChildren`\<`UseCheckoutOptions`\> | An object containing the configuration for the checkout flow. **Required** if the hook is used without a `` wrapping the component tree. | ### `UseCheckoutOptions` | Property | Type | Description | | ------------------------------------ | ------------------------------------- | ----------------------------------------------------------------------- | |
`for?` | "user" \| "organization" | Specifies if the checkout is for an organization. Defaults to `'user'`. | | `planId` | `string` | The ID of the subscription plan to check out (e.g. `cplan_xxx`). | | `planPeriod` | "month" \| "annual" | The billing period for the plan. | ## Returns `useCheckout()` returns a `{ checkout }` object. The `checkout` object contains the following properties. They are `null` until the checkout process is started by calling the `start()` method. | Property | Type | Description | | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `clear` | () => void | A function that clears the current checkout state from the cache. | | `confirm` | (params: ConfirmCheckoutParams) => Promise\<\{ data: BillingCheckoutResource; error: null; \} \| \{ data: null; error: ClerkAPIResponseError; \}\> | A function that confirms and finalizes the checkout process, usually after the user has provided and validated payment information. | | `error` | null \| ClerkAPIResponseError | Returns an error object if any part of the checkout process fails. | | `externalClientSecret` | null \| string | A client secret from an external payment provider (such as Stripe) used to complete the payment on the client-side. | | `externalGatewayId` | null \| string | The identifier for the external payment gateway used for this checkout session. | | `fetchStatus` | "error" \| "idle" \| "fetching" | The data fetching status. | | `finalize` | (params?: \{ navigate?: SetActiveNavigate; \}) => void | A function that finalizes the checkout process. Can optionally accept a `navigate()` function to redirect the user after completion. | | `freeTrialEndsAt?` | null \| Date | Unix timestamp (milliseconds) of when the free trial ends. | | `id` | null \| string | The unique identifier for the checkout session. | | `isConfirming` | `boolean` | A boolean that indicates if the `confirm()` method is in progress. | | `isImmediatePlanChange` | null \| boolean | Whether the plan change will take effect immediately after checkout. | | `isStarting` | `boolean` | A boolean that indicates if the `start()` method is in progress. | | `needsPaymentMethod` | null \| boolean | Whether a payment method is required for this checkout. | | `payer` | null \| BillingPayerResource | The payer associated with the checkout. | | `paymentMethod?` | null \| BillingPaymentMethodResource | The payment method being used for the checkout, such as a credit card or bank account. | | `plan` | null \| BillingPlanResource | The subscription plan details for the checkout. | | `planPeriod` | null \| "month" \| "annual" | The billing period for the plan. | | `planPeriodStart?` | null \| number | The start date of the plan period, represented as a Unix timestamp. | | `start` | () => Promise\<\{ data: BillingCheckoutResource; error: null; \} \| \{ data: null; error: ClerkAPIResponseError; \}\> | A function that initializes the checkout process by creating a checkout resource on the server. | | `status` | "needs\_confirmation" \| "completed" \| "needs\_initialization" | The current status of the checkout session. The following statuses are possible:
  • `needs_initialization`: The checkout hasn't started but the hook is mounted. Call `start()` to continue.
  • `needs_confirmation`: The checkout has been initialized and is awaiting confirmation. Call `confirm()` to continue.
  • `completed`: The checkout has been successfully confirmed. Call `finalize()` to complete the checkout.
| |
`totals` | null \| BillingCheckoutTotals | The total costs, taxes, and other pricing details for the checkout. | ## `` The `` component is a wrapper that provides a checkout context to its children, allowing checkout state to be shared across multiple components. Child components can access the checkout context by calling `useCheckout()`. ### Properties The `` component accepts the following props: | Property | Type | Description | | ------------------------------------ | ------------------------------------- | ----------------------------------------------------------------------- | | `for?` | "user" \| "organization" | Specifies if the checkout is for an organization. Defaults to `'user'`. | | `planId` | `string` | The ID of the subscription plan to check out (e.g. `cplan_xxx`). | | `planPeriod` | "month" \| "annual" | The billing period for the plan. | ## Usage For the best user experience and to prevent potential errors, always wrap components using `useCheckout()` with both `` and `` components. This ensures that the user is properly authenticated and Clerk is fully initialized before accessing checkout functionality. ```tsx function CheckoutPage() { return ( ) } ``` ### Examples The `useCheckout()` hook can be used with a context provider for managing state across multiple components or as a standalone hook for more isolated use cases. ", "Standalone Hook"]}> The following example shows the basic structure for a checkout flow. A parent component, ``, sets up the `` and renders the checkout flow. A child component, ``, uses the `useCheckout()` hook to access the checkout state. ", ""]}> ```tsx {{ filename: 'src/components/SubscriptionPage.tsx', collapsible: true }} import { CheckoutProvider } from '@clerk/nextjs/experimental' import { ClerkLoaded } from '@clerk/nextjs' import { CheckoutFlow } from './CheckoutFlow' export default function SubscriptionPage() { // `` sets the context for the checkout flow. // Any child component can now call `useCheckout()` to access this context. return (

Upgrade Your Plan

You are about to subscribe to our monthly plan

) } ```
```tsx {{ filename: 'src/components/CheckoutFlow.tsx', collapsible: true }} 'use client' import { useCheckout } from '@clerk/nextjs/experimental' import { useState } from 'react' import { useRouter } from 'next/navigation' export function CheckoutFlow() { const { checkout } = useCheckout() const { status } = checkout if (status === 'needs_initialization') { return } return (
) } function CheckoutInitialization() { const { checkout } = useCheckout() const { start, fetchStatus } = checkout return ( ) } function PaymentSection() { const { checkout } = useCheckout() const { isConfirming, confirm, finalize, error } = checkout const [isProcessing, setIsProcessing] = useState(false) const [paymentMethodId, setPaymentMethodId] = useState(null) const router = useRouter() const submitSelectedMethod = async () => { if (isProcessing || !paymentMethodId) return setIsProcessing(true) try { // Confirm checkout with payment method await confirm({ paymentSourceId: paymentMethodId, }) // Calling `.finalize` enables you to sync the client-side state with the server-side state of your users. // It revalidates all authorization checks computed within server components. await finalize({ navigate: () => router.push('/dashboard'), }) } catch (error) { console.error('Payment failed:', error) } finally { setIsProcessing(false) } } return ( <> {/* A component that lists a user's payment methods and allows them to select one. See an example: https://clerk.com/docs/reference/hooks/use-payment-methods#examples */} {error &&
{error.message}
} ) } function CheckoutSummary() { const { checkout } = useCheckout() const { plan, totals } = checkout return (

Order Summary

{plan?.name} {totals?.totalDueNow.currencySymbol} {totals?.totalDueNow.amountFormatted}
) } ```
For simple, self-contained components, you can use `useCheckout()` by passing the configuration options directly to the hook. This avoids the need to wrap the component in a provider. The following example shows an `` component that manages its own checkout flow. ```tsx {{ filename: 'src/components/UpgradeButton.tsx' }} 'use client' import { useCheckout } from '@clerk/nextjs/experimental' export function UpgradeButton({ planId, planPeriod, }: { planId: string planPeriod: 'month' | 'annual' }) { // Pass options directly to the hook when not using a provider. const { checkout } = useCheckout({ planId, planPeriod, for: 'user', }) const { start, status, isStarting, error } = checkout const handleStartCheckout = async () => { try { await start() // In a real app, you would now use the `externalClientSecret` // from the checkout object to render a payment form. console.log('Checkout started! Status:', checkout.status) } catch (e) { console.error('Error starting checkout:', e) } } return (
{error &&

Error: {error.errors[0].message}

}
) } ```
## Related guides * [Checkout flow with a new payment method](/docs/guides/development/custom-flows/billing/checkout-new-payment-method) * Prompt users to add a new payment method during checkout *** * [Checkout flow for returning users](/docs/guides/development/custom-flows/billing/checkout-existing-payment-method) * Prompt users to select an existing payment method during checkout --- title: "`usePaymentMethods()`" description: Access and manage payment methods in your React application with Clerk's usePaymentMethods() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-payment-methods lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-payment-methods.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `usePaymentMethods()` hook provides access to the payment methods associated with a user or Organization. It returns a paginated list of payment methods and includes methods for managing them. ## Parameters `usePaymentMethods()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | ## Returns `usePaymentMethods()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | BillingPaymentMethodResource\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `CacheSetter`\<undefined \| ClerkPaginatedResponse\<BillingPaymentMethodResource\>\> | A function that allows you to set the data manually. | ## Examples ### Basic usage The following example demonstrates how to fetch and display a user's payment methods. ```tsx {{ filename: 'app/billing/payment-methods/page.tsx' }} 'use client' import { usePaymentMethods } from '@clerk/nextjs/experimental' export default function PaymentMethodsList() { const { data, isLoading } = usePaymentMethods({ for: 'user', pageSize: 10, }) if (isLoading) { return
Loading payment methods...
} if (!data || data.length === 0) { // Code for how to add a new payment method: https://clerk.com/docs/guides/development/custom-flows/billing/add-new-payment-method return
No payment methods found. Please add a payment method to your account.
} return (
    {data?.map((method) => (
  • {method.cardType} **** {method.last4} {method.isDefault ? ' (Default)' : null}
  • ))}
) } ```
### Infinite pagination The following example demonstrates how to implement infinite scrolling with payment methods. ```tsx {{ filename: 'app/billing/payment-methods/page.tsx' }} 'use client' import { usePaymentMethods } from '@clerk/nextjs/experimental' export default function InfinitePaymentMethods() { const { data, isLoading, hasNextPage, fetchNext } = usePaymentMethods({ for: 'user', infinite: true, pageSize: 20, }) if (isLoading) { return
Loading...
} if (!data || data.length === 0) { // Code for how to add a new payment method: https://clerk.com/docs/guides/development/custom-flows/billing/add-new-payment-method return
No payment methods found. Please add a payment method to your account.
} return (
    {data?.map((method) => (
  • {method.cardType} ending in {method.last4} {method.status === 'expired' ? ' (Expired)' : null} {method.status === 'disconnected' ? ' (Disconnected)' : null}
  • ))}
{hasNextPage && }
) } ```
### With checkout flow The following example demonstrates how to use `usePaymentMethods()` in a checkout flow to select an existing payment method. For more information on how to build a checkout flow with an existing payment method, see [Build a custom checkout flow](/docs/guides/development/custom-flows/billing/checkout-new-payment-method). ```tsx {{ filename: 'app/billing/checkout/page.tsx' }} 'use client' import { usePaymentMethods, useCheckout } from '@clerk/nextjs/experimental' import { useRouter } from 'next/navigation' export default function CheckoutPaymentSelection() { const { data, isLoading } = usePaymentMethods({ for: 'user' }) const { checkout } = useCheckout() const { confirm, finalize } = checkout const router = useRouter() const handlePaymentSubmit = async (paymentMethodId: string) => { try { // Confirm checkout with selected payment method await confirm({ paymentSourceId: paymentMethodId }) // Complete checkout and redirect await finalize({ navigate: () => router.push('/dashboard'), }) } catch (error) { console.error('Payment failed:', error) } if (isLoading) { return
Loading payment methods...
} if (!data || data.length === 0) { // Code for how to add a new payment method: https://clerk.com/docs/guides/development/custom-flows/billing/checkout-new-payment-method return
No payment methods found. Please add a payment method to your account.
} return (

Select a payment method

{data?.map((method) => ( ))}
) } } ```
## Related guides * [Add a new payment method during checkout](/docs/guides/development/custom-flows/billing/checkout-new-payment-method) * Build a custom checkout flow that allows users to add a new payment method during checkout *** * [Add a new payment method outside of a checkout flow](/docs/guides/development/custom-flows/billing/add-new-payment-method) * Build a custom user interface that allows users to add a new payment method to their account --- title: "`usePaymentAttempts()`" description: Access and manage payment attempts in your React application with Clerk's usePaymentAttempts() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-payment-attempts lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-payment-attempts.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `usePaymentAttempts()` hook provides access to the payment attempts associated with a user or Organization. It returns a paginated list of payment attempts and includes methods for managing them. ## Parameters `usePaymentAttempts()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | ## Returns `usePaymentAttempts()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | BillingPaymentResource\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `CacheSetter`\<undefined \| ClerkPaginatedResponse\<BillingPaymentResource\>\> | A function that allows you to set the data manually. | ## Examples ### Basic usage The following example demonstrates how to fetch and display a user's payment attempts. ```tsx {{ filename: 'app/billing/payment-attempts/page.tsx' }} 'use client' import { usePaymentAttempts } from '@clerk/nextjs/experimental' export default function PaymentAttemptsList() { const { data, isLoading } = usePaymentAttempts({ for: 'user', pageSize: 10, }) if (isLoading) { return
Loading payment attempts...
} if (!data || data.length === 0) { return
No payment attempts found.
} return (
    {data?.map((attempt) => (
  • Payment #{attempt.id} - {attempt.status}
    Amount: {attempt.amount.amountFormatted} on {new Date(attempt.updatedAt).toLocaleString()}
  • ))}
) } ```
### Infinite pagination The following example demonstrates how to implement infinite scrolling with payment attempts. ```tsx {{ filename: 'app/billing/payment-attempts/page.tsx' }} 'use client' import { usePaymentAttempts } from '@clerk/nextjs/experimental' export default function InfinitePaymentAttempts() { const { data, isLoading, hasNextPage, fetchNext } = usePaymentAttempts({ for: 'user', infinite: true, pageSize: 20, }) if (isLoading) { return
Loading...
} if (!data || data.length === 0) { return
No payment attempts found.
} return (
    {data?.map((attempt) => (
  • Payment attempt for {attempt.amount.amountFormatted}
    Status: {attempt.status}
    {attempt.status === 'failed' && attempt.failedAt && ( Failed At: {new Date(attempt.failedAt).toLocaleString()} )}
  • ))}
{hasNextPage && }
) } ```
### Payment attempts history table The following example demonstrates how to use `usePaymentAttempts()` to display a detailed payment history table. ```tsx {{ filename: 'app/billing/payment-attempts-history/page.tsx', collapsible: true }} 'use client' import { usePaymentAttempts } from '@clerk/nextjs/experimental' export default function PaymentAttemptsHistory() { const { data, isLoading } = usePaymentAttempts({ for: 'user' }) if (isLoading) { return
Loading payment attempts...
} if (!data || data.length === 0) { return
No payment attempts found.
} const getStatusColor = (status: string) => { switch (status) { case 'paid': return 'green' case 'failed': return 'red' case 'pending': return 'orange' default: return 'gray' } } return ( {data?.map((attempt) => ( ))}
Payment ID Amount Status Date Payment Method
{attempt.id} {attempt.amount.amountFormatted} {attempt.status} {attempt.paidAt ? new Date(attempt.paidAt).toLocaleDateString() : '-'} {attempt.paymentSource.cardType} ****{attempt.paymentSource.last4}
) } ```
--- title: useOrganization() description: Access and manage the currently active Organization in your React application with Clerk's useOrganization() hook. search: rank: 1 sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-organization.mdx --- The `useOrganization()` hook retrieves attributes of the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## Parameters `useOrganization()` accepts a single object with the following optional properties: | Property | Type | Description | | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`domains?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ enrollmentMode?: "manual\_invitation" \| "automatic\_invitation" \| "automatic\_suggestion"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `enrollmentMode`: A string that filters the domains by the provided [enrollment mode](/docs/guides/organizations/verified-domains#enrollment-mode).
  • Any of the properties described in Shared properties.
| |
`invitations?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: ("expired" \| "pending" \| "accepted" \| "revoked")\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the invitations by the provided status.
  • Any of the properties described in Shared properties.
| |
`membershipRequests?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ status?: "expired" \| "pending" \| "accepted" \| "revoked"; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `status`: A string that filters the membership requests by the provided status.
  • Any of the properties described in Shared properties.
| |
`memberships?` | true \| \{ initialPage?: number; pageSize?: number; \} & \{ query?: string; role?: string\[]; \} & \{ infinite?: boolean; keepPreviousData?: boolean; \} | If set to `true`, all default properties will be used.
Otherwise, accepts an object with the following optional properties:
  • `role`: An array of OrganizationCustomRoleKey.
  • `query`: A string that filters the memberships by the provided string.
  • Any of the properties described in Shared properties.
| > \[!WARNING] > By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes aren't populated. To fetch and paginate the data, you must pass `true` or an object with the desired properties. ### Shared properties Optional properties that are shared across the `invitations`, `membershipRequests`, `memberships`, and `domains` properties. | Property | Type | Description | | --------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | | Name | Type | Description | | ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | > \[!NOTE] > These attributes are updating automatically and will re-render their respective components whenever you set a different Organization using the setActive(\{ organization }) method or update any of the memberships or invitations. No need for you to manage updating anything manually. ## Returns | Property | Type | Description | | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `domains` | null \| PaginatedResourcesWithDefault\<OrganizationDomainResource\> \| PaginatedResources\<OrganizationDomainResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's domains. | | `invitations` | null \| PaginatedResourcesWithDefault\<OrganizationInvitationResource\> \| PaginatedResources\<OrganizationInvitationResource, T\["invitations"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's invitations. | | `isLoaded` | `boolean` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `membership` | undefined \| null \| OrganizationMembershipResource | The current organization membership. | | `membershipRequests` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipRequestResource\> \| PaginatedResources\<OrganizationMembershipRequestResource, T\["membershipRequests"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's membership requests. | | `memberships` | null \| PaginatedResourcesWithDefault\<OrganizationMembershipResource\> \| PaginatedResources\<OrganizationMembershipResource, T\["memberships"] *extends* \{ infinite: true; \} ? true : false\> | Includes a paginated list of the organization's memberships. | | `organization` | undefined \| null \| OrganizationResource | The currently active organization. | ### `PaginatedResources` | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | T\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `Infinite` *extends* `true` ? `CacheSetter`\<(undefined \| ClerkPaginatedResponse\)\[]\> : `CacheSetter`\<undefined \| ClerkPaginatedResponse\\> | A function that allows you to set the data manually. | To see the different Organization features integrated into one application, take a look at our [Organizations demo repository](https://github.com/clerk/organizations-demo). ## Examples ### Expand and paginate attributes To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data. ```jsx // invitations.data will never be populated. const { invitations } = useOrganization() // Use default values to fetch invitations, such as initialPage = 1 and pageSize = 10 const { invitations } = useOrganization({ invitations: true, }) // Pass your own values to fetch invitations const { invitations } = useOrganization({ invitations: { pageSize: 20, initialPage: 2, // skips the first page }, }) // Aggregate pages in order to render an infinite list const { invitations } = useOrganization({ invitations: { infinite: true, }, }) ``` ### Infinite pagination The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list. ```tsx {{ filename: 'app/organization/members/page.tsx' }} 'use client' import { useOrganization } from '@clerk/nextjs' export default function Page() { const { memberships } = useOrganization({ memberships: { infinite: true, // Append new data to the existing list keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
### Simple pagination The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `memberships` attribute will be populated with the first page of the Organization's memberships. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of memberships. Notice the difference between this example's pagination and the infinite pagination example above. ```tsx {{ filename: 'app/members/page.tsx' }} 'use client' import { useOrganization } from '@clerk/nextjs' export default function Page() { const { memberships } = useOrganization({ memberships: { keepPreviousData: true, // Persist the cached data until the new data has been fetched }, }) // Handle loading state if (!memberships) return
Loading...
return (

Organization members

    {memberships.data?.map((membership) => (
  • {membership.publicUserData?.firstName} {membership.publicUserData?.lastName} < {membership.publicUserData?.identifier}> :: {membership.role}
  • ))}
) } ```
## Related guides * [Update an Organization](/docs/guides/development/custom-flows/organizations/update-organizations) * Use Clerk's API to build a custom flow for updating an Organization *** * [Manage Roles in an Organization](/docs/guides/development/custom-flows/organizations/manage-roles) * Use Clerk's API to build a custom flow for managing Roles in an Organization *** * [Manage an Organization's membership requests](/docs/guides/development/custom-flows/organizations/manage-membership-requests) * Use Clerk's API to build a custom flow for managing an Organization's membership requests *** * [Manage a user's Organization invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations) * Use Clerk's API to build a custom flow for managing user's Organization invitations --- title: "`usePaymentElement()`" description: Clerk's usePaymentElement() hook provides methods and state for interacting with a payment form. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-payment-element lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-payment-element.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `usePaymentElement()` hook is used to control the payment form rendered by the \ component. It provides the necessary state and methods to submit payment details to a payment provider like Stripe. This hook must be used within a component that is a descendant of the `` component. It is typically used in a checkout flow that prompts a user to add a new payment method, or for adding a new payment method outside of a checkout. ## Parameters `usePaymentElement()` doesn't accept any parameters. It derives its state and configuration from the nearest \. ## Returns `usePaymentElement()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`isFormReady` | `boolean` | A boolean that indicates if the payment form UI has been rendered and is ready for user input. This is useful for disabling a submit button until the form is interactive. | | `isProviderReady` | `boolean` | A boolean that indicates if the underlying payment provider (e.g. Stripe) has been fully initialized. | | `provider` | undefined \| \{ name: "stripe"; \} | An object containing information about the initialized payment provider. It is `undefined` until `isProviderReady` is `true`. | | `reset` | () => Promise\ | A function that resets the payment form to its initial, empty state. | | `submit` | () => Promise\<\{ data: \{ gateway: "stripe"; paymentToken: string; \}; error: null; \} \| \{ data: null; error: PaymentElementError; \}\> | A function that submits the payment form data to the payment provider. It returns a promise that resolves with either a `data` object containing a payment token on success, or an `error` object on failure. | ## Payment element components The `usePaymentElement()` hook works in conjunction with the `` and `` components. ### `` The `` component sets up the context for the payment element. It fetches all the necessary data from the payment provider (e.g., Stripe) and makes it available to its children. #### Properties | Property | Type | Description | | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `checkout?` | BillingCheckoutResource \| UseCheckoutReturn | An optional checkout resource object. When provided, the payment element is scoped to the specific checkout session. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `paymentDescription?` | `string` | An optional description to display to the user within the payment element UI. | | `stripeAppearance?` | `internalStripeAppearance` | An optional object to customize the appearance of the Stripe Payment Element. This allows you to match the form's styling to your application's theme. | ### `` This component renders the actual payment form from the provider (e.g., the Stripe Payment Element). It should be rendered as a child of ``. #### Properties | Property | Type | Description | | --------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------- | | `fallback?` | `ReactNode` | Optional fallback content, such as a loading skeleton, to display while the payment form is being initialized. | ## Example The following example demonstrates how to create a billing page where a user can add a new payment method. It is split into two components: * **``**: Sets up the ``, which specifies that the payment actions within its children are `for` the `user`. * **``**: Renders the payment form and handles the submission logic. It uses `usePaymentElement()` to get the `submit` function and `useUser()` to get the `user` object. When the form is submitted, it first creates a payment token and then attaches it to the user. ", ""]}> ```tsx {{ filename: 'app/user/billing/page.tsx' }} import { ClerkLoaded } from '@clerk/nextjs' import { PaymentElementProvider } from '@clerk/nextjs/experimental' import { AddPaymentMethodForm } from './AddPaymentMethodForm' export default function Page() { return (

Billing Settings

) } ``` ```tsx {{ filename: 'app/user/billing/AddPaymentMethodForm.tsx', collapsible: true }} 'use client' import { useUser } from '@clerk/nextjs' import { usePaymentElement, PaymentElement } from '@clerk/nextjs/experimental' import { useState } from 'react' export function AddPaymentMethodForm() { const { user } = useUser() const { submit, isFormReady } = usePaymentElement() const [isSubmitting, setIsSubmitting] = useState(false) const [error, setError] = useState(null) const handleAddPaymentMethod = async (e: React.FormEvent) => { e.preventDefault() if (!isFormReady || !user) { return } setError(null) setIsSubmitting(true) try { // 1. Submit the form to the payment provider to get a payment token const { data, error } = await submit() // Usually a validation error from stripe that you can ignore. if (error) { setIsSubmitting(false) return } // 2. Use the token to add the payment source to the user await user.addPaymentSource(data) // 3. Handle success (e.g., show a confirmation, clear the form) alert('Payment method added successfully!') } catch (err: any) { setError(err.message || 'An unexpected error occurred.') } finally { setIsSubmitting(false) } } return (

Add a new payment method

{error &&

{error}

} ) } ```
## Related guides * [Use PaymentElement in a checkout flow](/docs/guides/development/custom-flows/billing/checkout-new-payment-method) * Add a new payment method during checkout *** * [Use PaymentElement outside of a checkout flow](/docs/guides/development/custom-flows/billing/add-new-payment-method) * Add a new payment method outside of a checkout flow --- title: "`usePlans()`" description: Access Plans in your React application with Clerk's usePlans() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-plans lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-plans.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `usePlans()` hook provides access to the Subscription Plans available in your application. It returns a paginated list of Plans and includes methods for managing them. ## Parameters `usePlans()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | ## Returns `usePlans()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | BillingPlanResource\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `CacheSetter`\<undefined \| ClerkPaginatedResponse\<BillingPlanResource\>\> | A function that allows you to set the data manually. | ## Examples ### Basic usage The following example shows how to fetch and display available Plans. ```tsx {{ filename: 'app/billing/plans/page.tsx' }} 'use client' import { usePlans } from '@clerk/nextjs/experimental' export default function PlansList() { const { data, isLoading, hasNextPage, fetchNext, hasPreviousPage, fetchPrevious } = usePlans({ for: 'user', pageSize: 10, }) if (isLoading) { return
Loading plans...
} return (
    {data?.map((plan) => (
  • {plan.name}

    {plan.description}

    Is free plan: {!plan.hasBaseFee ? 'Yes' : 'No'}

    Price per month: {plan.currency} {plan.amountFormatted}

    Price per year: {plan.currency} {plan.annualAmountFormatted} equivalent to{' '} {plan.currency} {plan.annualMonthlyAmountFormatted} per month

    Features:

      {plan.features.map((feature) => (
    • {feature.name}
    • ))}
  • ))} {hasNextPage && } {hasPreviousPage && }
) } ```
### Infinite pagination The following example demonstrates how to implement infinite scrolling with Plans. ```tsx {{ filename: 'app/billing/plans/page.tsx' }} 'use client' import { usePlans } from '@clerk/nextjs/experimental' export default function InfinitePlansList() { const { data, isLoading, hasNextPage, fetchNext } = usePlans({ for: 'user', infinite: true, pageSize: 2, }) if (isLoading) { return
Loading plans...
} return (
    {data?.map((plan) => (
  • {plan.name}

    {plan.description}

    Is free plan: {!plan.hasBaseFee ? 'Yes' : 'No'}

    Price per month: {plan.currency} {plan.amountFormatted}

    Price per year: {plan.currency} {plan.annualAmountFormatted} equivalent to{' '} {plan.currency} {plan.annualMonthlyAmountFormatted} per month

    Features:

      {plan.features.map((feature) => (
    • {feature.name}
    • ))}
  • ))}
{hasNextPage && }
) } ```
## Related guides * [Checkout flow with a new payment method](/docs/guides/development/custom-flows/billing/checkout-new-payment-method) * Prompt users to add a new payment method during checkout *** * [Checkout flow for returning users](/docs/guides/development/custom-flows/billing/checkout-existing-payment-method) * Prompt users to select an existing payment method during checkout --- title: useReverification() description: Clerk's useReverification() hook enhances a fetcher function to handle a session's reverification flow. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-reverification lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,remix,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-reverification.mdx --- > \[!WARNING] > > Depending on the SDK you're using, this feature requires `@clerk/nextjs@6.12.7` or later, `@clerk/clerk-react@5.25.1` or later, `@clerk/clerk-js@5.57.1` or later and `@clerk/clerk-sdk-ruby@3.3.0` or later. Reverification allows you to prompt a user to verify their credentials before performing sensitive actions, even if they're already authenticated. For example, in a banking application, transferring money is considered a "sensitive action." Reverification can be used to confirm the user's identity. The `useReverification()` hook is used to handle a session's reverification flow. If a request requires reverification, a modal will display, prompting the user to verify their credentials. Upon successful verification, the original request will automatically retry. If you'd like to build a custom UI, you can use the onNeedsReverification option. When using reverification, a user's credentials are valid for 10 minutes. Once stale, a user will need to reverify their credentials. This time duration can be customized by using the `has()` helper on the server-side. See the [guide on reverification](/docs/guides/secure/reverification) for more information. ## Parameters | Parameter | Type | Description | | ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `fetcher` | `Fetcher extends (...args: any[]) => Promise` | A function that returns a promise. | | `options?` | `Options` | Optional configuration object extending UseReverificationOptions. | ### `UseReverificationOptions` The optional options object. | Property | Type | Description | | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | |
`onNeedsReverification?` | (properties: NeedsReverificationParameters) => void | Handler for the reverification process. Opts out of using the default UI. Use this to build a custom UI. | ### `NeedsReverificationParameters` | Property | Type | Description | | -------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `cancel` | () => void | Marks the reverification process as cancelled and rejects the original request. | | `complete` | () => void | Marks the reverification process as complete and retries the original request. | | `level` | undefined \| "first\_factor" \| "second\_factor" \| "multi\_factor" | The verification level required for the reverification process. | ## Examples The `useReverification()` hook displays a prebuilt UI when the user needs to reverify their credentials. You can also build a custom UI to handle the reverification process yourself. Use the following tabs to see examples of either option. ### Handle reverification for an action The following example demonstrates how to use the `useReverification()` hook to require a user to reverify their credentials before being able to update their primary email address. It also demonstrates how to handle the cancellation of the reverification process. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} 'use client' import { useReverification, useUser } from '@clerk/nextjs' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/nextjs/errors' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification((emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {email.id !== user?.primaryEmailAddress?.id && ( )}
  • ))}
) } ```
### Handle reverification for a fetcher function The following example demonstrates how to use the `useReverification()` hook to enhance a fetcher function that fetches data from a route that requires reverification. For examples on how to set up a route that requires reverification, see the [guide on reverification](/docs/guides/secure/reverification). ```tsx {{ filename: 'components/AccountBalance.tsx' }} 'use client' import { useReverification } from '@clerk/nextjs' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/nextjs/errors' import { useState } from 'react' export function AccountBalance() { const [balance, setBalance] = useState(null) const accountBalance = useReverification(async () => { const response = await fetch('/api/balance') return await response.json() }) const handleClick = async () => { try { const accountBalanceResponse = await accountBalance() setBalance(accountBalanceResponse.amount) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your account balance is {balance ? `$${balance}` : '$******'}
) } ```
The following example demonstrates how to build a custom UI when using the `useReverification()` hook. In the example, the `useReverification()` hook is used to require a user to reverify their credentials before being able to update their primary email address. It requires two components: the `` component displays the list of email addresses to choose from and it renders the second component, ``, which handles the reverification process. The example handles first factor verification using an email code, so you will need to have the [**Email verification code**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) setting enabled for your application. But you can adapt this example to handle any type of verification level or strategy. The `` component uses `useReverification()` to enhance the `update()` method, requiring the user to reverify their credentials before being able to update their primary email address. The `useReverification()` hook provides the `onNeedsReverification` option, which is a handler for building a custom UI. It provides four properties: `level`, `complete`, `cancel`, and `inProgress`. The example tracks these using the `verificationState` state variable. * The `level` property determines the verification level required for the reverification process. This example only handles first factor verification, which is done in the `` component. * The `complete` and `cancel` properties are the steps of the reverification process, which is also done in the `` component. * The `inProgress` property is used to track the state of the reverification process. When the user selects the "Make primary" button, it triggers the reverification process and sets the `inProgress` property is `true`, which displays the `` component. ```tsx {{ filename: 'components/UpdateUserEmail.tsx', collapsible: true }} 'use client' import { useReverification, useUser } from '@clerk/nextjs' import { isClerkRuntimeError, isReverificationCancelledError } from '@clerk/nextjs/errors' import { useState } from 'react' import { SessionVerificationLevel } from '@clerk/types' import { VerificationComponent } from './VerificationComponent' export function UpdateUserEmail() { // Use `useUser()` to get the current user's `User` object // `User` includes the `update()` method to update the user's primary email address const { user } = useUser() // TODO: Update to use exported type once available const [verificationState, setVerificationState] = useState< | { complete: () => void cancel: () => void level: SessionVerificationLevel | undefined inProgress: boolean } | undefined >(undefined) // Use `useReverification()` to enhance the `update()` method // to handle the reverification process const changePrimaryEmail = useReverification( (emailAddressId: string) => user?.update({ primaryEmailAddressId: emailAddressId }), { onNeedsReverification: ({ complete, cancel, level }) => { setVerificationState({ complete, cancel, level, inProgress: true, }) }, }, ) const handleClick = async (emailAddressId: string) => { try { await changePrimaryEmail(emailAddressId) } catch (e) { // Handle if user cancels the reverification process if (isClerkRuntimeError(e) && isReverificationCancelledError(e)) { console.error('User cancelled reverification', e.code) } // Handle other errors // See https://clerk.com/docs/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(e, null, 2)) } } return (
Your primary email address is {user?.primaryEmailAddress?.emailAddress}
    {user?.emailAddresses.map((email) => (
  • {email.emailAddress} {user?.primaryEmailAddressId !== email.id && ( )}
  • ))}
{verificationState?.inProgress && ( { verificationState.complete() setVerificationState(undefined) }} onCancel={() => { verificationState.cancel() setVerificationState(undefined) }} /> )}
) } ```
The `` component handles the reverification process. It uses the `level` property to determine the verification level, which is set to `first_factor`. First, it finds the determined starting first factor from the supported first factors. Then, it prepares the first factor verification using the `strategy` (`email_code` in this case) and `emailAddressId` properties. Finally, it attempts to verify the session with email code provided by the user. If the verification is successful, the `onComplete()` handler is called to complete the reverification process. ```tsx {{ filename: 'components/VerificationComponent.tsx', collapsible: true }} 'use client' import { useEffect, useRef, useState } from 'react' import { useSession } from '@clerk/nextjs' import { EmailCodeFactor, SessionVerificationLevel, SessionVerificationResource, } from '@clerk/types' export function VerificationComponent({ level = 'first_factor', onComplete, onCancel, }: { level: SessionVerificationLevel | undefined onComplete: () => void onCancel: () => void }) { const { session } = useSession() const [code, setCode] = useState('') const reverificationRef = useRef(undefined) const [determinedStartingFirstFactor, setDeterminedStartingFirstFactor] = useState< EmailCodeFactor | undefined >() useEffect(() => { if (reverificationRef.current) { return } session?.startVerification({ level }).then(async (response) => { reverificationRef.current = response await prepareEmailVerification(response) }) }, []) const prepareEmailVerification = async (verificationResource: SessionVerificationResource) => { // To simplify the example we will only handle the first factor verification if (verificationResource.status === 'needs_first_factor') { // Determine the starting first factor from the supported first factors const determinedStartingFirstFactor = verificationResource.supportedFirstFactors?.filter( (factor) => factor.strategy === 'email_code', )[0] if (determinedStartingFirstFactor) { setDeterminedStartingFirstFactor(determinedStartingFirstFactor) // Prepare the first factor verification with the determined starting first factor await session?.prepareFirstFactorVerification({ strategy: determinedStartingFirstFactor.strategy, emailAddressId: determinedStartingFirstFactor?.emailAddressId, }) } } } const handleVerificationAttempt = async () => { try { // Attempt to verify the session with the provided code await session?.attemptFirstFactorVerification({ strategy: 'email_code', code, }) onComplete() } catch (e) { // Any error from the attempt to verify the session can be handled here console.error('Error verifying session', e) } } if (!determinedStartingFirstFactor) { return null } return (

Enter verification code sent to {determinedStartingFirstFactor.safeIdentifier || ''}

setCode(e.target.value)} />
) } ```
## Related guides See the custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). guides for examples of how to use the `useReverification()` hook, such as the [Add a phone number to a user's account](/docs/guides/development/custom-flows/account-updates/add-phone) guide. --- title: useSession() description: Access and manage the current user's session in your React application with Clerk's useSession() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-session.mdx --- The `useSession()` hook provides access to the current user's Session object, as well as helpers for setting the active session. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that indicates whether a user is currently signed in. | | `session` | `undefined` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that indicates whether a user is currently signed in. | | `session` | `null` | The current session for the user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `boolean` | A boolean that indicates whether a user is currently signed in. | | `session` | SignedInSessionResource | The current session for the user. | ## Example ### Access the `Session` object The following example uses the `useSession()` hook to access the `Session` object, which has the `lastActiveAt` property. The `lastActiveAt` property is a `Date` object used to show the time the session was last active. ```tsx {{ filename: 'app/home/page.tsx' }} 'use client' import { useSession } from '@clerk/nextjs' export default function Page() { const { isLoaded, session, isSignedIn } = useSession() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return (

This session has been active since {session.lastActiveAt.toLocaleString()}

) } ```
--- title: useSessionList() description: Access and manage the current user's session list in your React application with Clerk's useSessionList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-session-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-session-list.mdx --- The `useSessionList()` hook returns an array of Session objects that have been registered on the client device. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | `undefined` | A list of sessions that have been registered on the client device. | | `setActive` | `undefined` | A function that sets the active session and/or organization. See the reference doc. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `sessions` | SessionResource\[] | A list of sessions that have been registered on the client device. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session and/or organization. See the reference doc. | ## Example ### Get a list of sessions The following example uses `useSessionList()` to get a list of sessions that have been registered on the client device. The `sessions` property is used to show the number of times the user has visited the page. ```tsx {{ filename: 'app/home/page.tsx' }} 'use client' import { useSessionList } from '@clerk/nextjs' export default function Page() { const { isLoaded, sessions } = useSessionList() // Handle loading state if (!isLoaded) return
Loading...
return (

Welcome back. You've been here {sessions.length} times before.

) } ```
--- title: useSignIn() description: Access and manage the current user's sign-in state in your React application with Clerk's useSignIn() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-in lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-sign-in.mdx --- The `useSignIn()` hook provides access to the SignIn object, which allows you to check the current state of a sign-in attempt and manage the sign-in flow. You can use this to create a [custom sign-in flow](/docs/guides/development/custom-flows/overview#sign-in-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signIn` | `undefined` | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signIn` | SignInResource | An object that contains the current sign-in attempt status and methods to create a new sign-in attempt. | ## Examples ### Check the current state of a sign-in The following example uses the `useSignIn()` hook to access the SignIn object, which contains the current sign-in attempt status and methods to create a new sign-in attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'app/sign-in/page.tsx' }} 'use client' import { useSignIn } from '@clerk/nextjs' export default function Page() { const { isLoaded, signIn } = useSignIn() // Handle loading state if (!isLoaded) return
Loading...
return
The current sign-in attempt status is {signIn?.status}.
} ```
### Create a custom sign-in flow with `useSignIn()` The `useSignIn()` hook can also be used to build fully custom sign-in flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-in flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignIn()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: useSignUp() description: Access and manage the current user's sign-up state in your React application with Clerk's useSignUp() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-sign-up lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-sign-up.mdx --- The `useSignUp()` hook provides access to the SignUp object, which allows you to check the current state of a sign-up attempt and manage the sign-up flow. You can use this to create a [custom sign-up flow](/docs/guides/development/custom-flows/overview#sign-up-flow). ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive` | `undefined` | A function that sets the active session. See the reference doc. | | `signUp` | `undefined` | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `setActive()` | (setActiveParams: SetActiveParams) => Promise\ | A function that sets the active session. See the reference doc. | | `signUp` | SignUpResource | An object that contains the current sign-up attempt status and methods to create a new sign-up attempt. | ## Examples ### Check the current state of a sign-up The following example uses the `useSignUp()` hook to access the SignUp object, which contains the current sign-up attempt status and methods to create a new sign-up attempt. The `isLoaded` property is used to handle the loading state. ```tsx {{ filename: 'app/sign-up/page.tsx' }} 'use client' import { useSignUp } from '@clerk/nextjs' export default function Page() { const { isLoaded, signUp } = useSignUp() // Handle loading state if (!isLoaded) return
Loading...
return
The current sign-up attempt status is {signUp?.status}.
} ```
### Create a custom sign-up flow with `useSignUp()` The `useSignUp()` hook can also be used to build fully custom sign-up flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-up flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `useSignUp()` hook to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`useStatements()`" description: Access and manage statements in your React application with Clerk's useStatements() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-statements lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-statements.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `useStatements()` hook provides access to the statements associated with a user or Organization. It returns a paginated list of statements and includes methods for managing them. ## Parameters `useStatements()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch for the current user or organization. Defaults to `'user'`. | | `infinite?` | `boolean` | If `true`, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to `false`. | | `initialPage?` | `number` | A number that specifies which page to fetch. For example, if `initialPage` is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to `1`. | | `keepPreviousData?` | `boolean` | If `true`, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | | `pageSize?` | `number` | A number that specifies the maximum number of results to return per page. Defaults to `10`. | ## Returns `useStatements()` returns an object with the following properties: | Property | Type | Description | | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `count` | `number` | The total count of data that exist remotely. | | `data` | BillingStatementResource\[] | An array that contains the fetched data. For example, for the `memberships` attribute, data will be an array of OrganizationMembership objects. | | `error` | null \| ClerkAPIResponseError | Clerk's API response error object. | | `fetchNext` | () => void | A function that triggers the next page to be loaded. This is the same as `fetchPage(page => Math.min(pageCount, page + 1))`. | | `fetchPage` | `ValueOrSetter`\<`number`\> | A function that triggers a specific page to be loaded. | | `fetchPrevious` | () => void | A function that triggers the previous page to be loaded. This is the same as `fetchPage(page => Math.max(0, page - 1))`. | | `hasNextPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `hasPreviousPage` | `boolean` | A boolean that indicates if there are available pages to be fetched. | | `isError` | `boolean` | A boolean that indicates the request failed. | | `isFetching` | `boolean` | A boolean that is `true` if there is an ongoing request or a revalidation. | | `isLoading` | `boolean` | A boolean that is `true` if there is an ongoing request and there is no fetched data. | | `page` | `number` | The current page. | | `pageCount` | `number` | The total amount of pages. It is calculated based on `count`, `initialPage`, and `pageSize`. | | `revalidate` | () => Promise\ | A function that triggers a revalidation of the current page. | | `setData` | `CacheSetter`\<undefined \| ClerkPaginatedResponse\<BillingStatementResource\>\> | A function that allows you to set the data manually. | ## Examples ### Basic usage The following example demonstrates how to fetch and display a user's statements. ```tsx {{ filename: 'app/billing/statements/page.tsx' }} 'use client' import { useStatements } from '@clerk/nextjs/experimental' export default function StatementsList() { const { data, isLoading } = useStatements({ for: 'user', pageSize: 10, }) if (isLoading) { return
Loading statements...
} if (!data || data.length === 0) { return
No statements found.
} return (
    {data?.map((statement) => (
  • Statement ID: {statement.id} - {statement.status}
    Date: {statement.timestamp.toLocaleDateString()}
  • ))}
) } ```
### Infinite pagination The following example demonstrates how to implement infinite scrolling with statements. ```tsx {{ filename: 'app/billing/statements/page.tsx' }} 'use client' import { useStatements } from '@clerk/nextjs/experimental' export default function InfiniteStatements() { const { data, isLoading, hasNextPage, fetchNext } = useStatements({ for: 'user', infinite: true, pageSize: 20, }) if (isLoading) { return
Loading...
} if (!data || data.length === 0) { return
No statements found.
} return (
    {data?.map((statement) => (
  • Statement ID: {statement.id}
    Amount: {statement.totals.grandTotal.amountFormatted}
    Status: {statement.status}
  • ))}
{hasNextPage && }
) } ```
--- title: useUser() description: Access and manage the current user's data in your React application with Clerk's useUser() hook. sdk: chrome-extension, expo, nextjs, react, react-router, tanstack-react-start sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension,expo,nextjs,react,react-router,tanstack-react-start notAvailableSdks: js-frontend,android,ios,expressjs,fastify,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-user.mdx --- The `useUser()` hook provides access to the current user's User object, which contains all the data for a single user in your application and provides methods to manage their account. This hook also allows you to check if the user is signed in and if Clerk has loaded and initialized. ## Returns There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `false` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `undefined` | A boolean that returns `true` if the user is signed in. | | `user` | `undefined` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `false` | A boolean that returns `true` if the user is signed in. | | `user` | `null` | The `User` object for the current user. | | Name | Type | Description | | ------ | ------ | ------ | | `isLoaded` | `true` | A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads. | | `isSignedIn` | `true` | A boolean that returns `true` if the user is signed in. | | `user` | UserResource | The `User` object for the current user. | ## Examples ### Get the current user The following example uses the `useUser()` hook to access the User object, which contains the current user's data such as their full name. The `isLoaded` and `isSignedIn` properties are used to handle the loading state and to check if the user is signed in, respectively. ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { useUser } from '@clerk/nextjs' export default function Page() { const { isSignedIn, user, isLoaded } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
return
Hello {user.firstName}!
} ```
### Update user data The following example uses the `useUser()` hook to access the User object, which calls the update() method to update the current user's information. ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { useUser } from '@clerk/nextjs' export default function Page() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { await user.update({ firstName: 'John', lastName: 'Doe', }) } return ( <>

user.firstName: {user.firstName}

user.lastName: {user.lastName}

) } ```
### Reload user data The following example uses the `useUser()` hook to access the User object, which calls the reload() method to get the latest user's information. ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { useUser } from '@clerk/nextjs' export default function Page() { const { isSignedIn, isLoaded, user } = useUser() // Handle loading state if (!isLoaded) return
Loading...
// Protect the page from unauthenticated users if (!isSignedIn) return
Sign in to view this page
const updateUser = async () => { // Update data via an API endpoint const updateMetadata = await fetch('/api/updateMetadata', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role: 'admin', }), }) // Check if the update was successful if ((await updateMetadata.json()).message !== 'success') { throw new Error('Error updating') } // If the update was successful, reload the user data await user.reload() } return ( <>

user role: {user.publicMetadata.role}

) } ```
--- title: "`useSubscription()`" description: Access Subscription information in your React application with Clerk's useSubscription() hook. sdk: nextjs, react sdkScoped: "true" canonical: /docs/:sdk:/reference/hooks/use-subscription lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs,react notAvailableSdks: js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/hooks/use-subscription.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `useSubscription()` hook provides access to Subscription information for users or Organizations in your application. It returns the current Subscription data and includes methods for managing it. > \[!WARNING] > The `useSubscription()` hook should only be used for accessing and displaying subscription information. For authorization purposes (i.e., controlling access to Features or content), use the [`has()`](/docs/guides/secure/authorization-checks#use-has-for-authorization-checks) helper or the \ component instead. ## Parameters `useSubscription()` accepts a single optional object with the following properties: | Property | Type | Description | | ------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------- | |
`enabled?` | `boolean` | If `true`, a request will be triggered when the hook is mounted. Defaults to `true`. | | `for?` | "user" \| "organization" | Specifies whether to fetch the subscription for an organization or a user. Defaults to `'user'`. | | `keepPreviousData?` | `boolean` | If true, the previous data will be kept in the cache until new data is fetched. Defaults to `false`. | ## Returns `useSubscription()` returns an object with the following properties: | Property | Type | Description | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | `data` | undefined \| null \| BillingSubscriptionResource | The subscription object, `undefined` before the first fetch, or `null` if no subscription exists. | | `error` | undefined \| Error | Any error that occurred during the data fetch, or `undefined` if no error occurred. | | `isFetching` | `boolean` | A boolean that indicates whether any request is still in flight, including background updates. | | `isLoading` | `boolean` | A boolean that indicates whether the initial data is still being fetched. | | `revalidate` | () => void \| Promise\ | Function to manually revalidate or refresh the subscription data. | ## Examples ### Basic usage The following example shows how to fetch and display subscription information. ```tsx {{ filename: 'app/pricing/subscription-details/page.tsx' }} 'use client' import { useSubscription } from '@clerk/nextjs/experimental' export default function SubscriptionInfo() { const { data, isLoading, error } = useSubscription() if (isLoading) { return
Loading subscription...
} if (error) { return
Error loading subscription: {error.message}
} if (!data) { return
No subscription found
} return (

Your Subscription

{/* Display subscription details */}
) } ```
### Organization subscription The following example shows how to fetch an Organization's subscription. ```tsx {{ filename: 'app/pricing/organization-subscription-details/page.tsx' }} 'use client' import { useSubscription } from '@clerk/nextjs/experimental' export default function OrganizationSubscription() { const { data, isLoading, revalidate } = useSubscription({ for: 'organization', keepPreviousData: true, }) const handleSubscriptionUpdate = async () => { // After making changes to the subscription await revalidate() } if (isLoading) { return
Loading Organization subscription...
} return (

Organization Subscription

{/* Display Organization subscription details */}
) } ```
### With error handling The following example shows how to handle subscription data with proper error states. ```tsx {{ filename: 'app/pricing/subscription-details/page.tsx', collapsible: true }} 'use client' import { useSubscription } from '@clerk/nextjs/experimental' export function SubscriptionDetails() { const { data: subscription, isLoading } = useSubscription() if (isLoading) { return
Loading subscription...
} if (!subscription) { return
No subscription
} return (

Subscription Details

Status: {subscription.status}

Active since: {subscription.activeAt.toLocaleDateString()}

{subscription.pastDueAt && (

Past due since: {subscription.pastDueAt.toLocaleDateString()}

)}
{subscription.nextPayment && (

Next Payment

Amount: {subscription.nextPayment.amount.amountFormatted}

Due: {subscription.nextPayment.date.toLocaleDateString()}

)}

Subscription Items

    {subscription.subscriptionItems.map((item) => (
  • {/* Display subscription item details */}
  • ))}
) } export default function Page() { const { data, isLoading, error, isFetching, revalidate } = useSubscription() if (error) { return (

Failed to load subscription

{error.message}

) } return (
{isLoading ? (
Loading...
) : ( <>
{isFetching && Refreshing...}
{data ? :
No active subscription
} )}
) } ```
--- title: Core concepts description: Learn about the main concepts and objects that drive Clerk's powerful authentication and user management system. lastUpdated: 2025-11-21T22:25:46.000Z sdkScoped: "false" canonical: /docs/getting-started/core-concepts sourceFile: /docs/getting-started/core-concepts.mdx --- Before building your application, it's important to understand the core concepts and objects that drive Clerk's powerful authentication and user management system. This page walks through integration options, prebuilt components, configuration steps, and the key objects you'll use as you build your application. ## Ways to implement Clerk Clerk provides three ways to integrate authentication into your application, depending on the level of control and customization you need: 1. **[Account Portal](/docs/guides/customizing-clerk/account-portal) (default)**: Uses Clerk's prebuilt components on dedicated pages that are hosted on Clerk servers. Every Clerk application has this enabled by default, providing a complete user management interface out of the box. 2. **Prebuilt components**: All-in-one UI components that can be integrated into your application. They are fully customizable to match your application's branding and design. This is the recommended approach for most use cases. 3. **Custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). using the Clerk API**: Build your own UI using the Clerk API. This option provides maximum flexibility and control over the user experience but requires more development effort. Clerk offers a comprehensive suite of prebuilt components designed to seamlessly integrate authentication and multi-tenancy into your application. Components, like ``, ``, and ``, are all-in-one solutions that handle the full lifecycle of the user experience, from sign-up/sign-in to user profile and Organization management. The Account Portal uses these components on dedicated pages that are hosted on Clerk servers. These pages cannot be customized beyond the options provided in the [Clerk Dashboard](https://dashboard.clerk.com/~/account-portal). For more control and customization, you can migrate away from the Account Portal and embed the prebuilt components directly into your own application pages. While they are [fully customizable](/docs/guides/customizing-clerk/appearance-prop/overview) to match your application's branding and design using CSS or special props, the HTML structure and the logic/ordering of the authentication flow remain fixed. If the prebuilt components don't meet your specific needs or if you need complete control over the logic, you can rebuild the existing Clerk flows using the Clerk API. However, this is more advanced and it's recommended to use the prebuilt components whenever possible. > \[!TIP] > Most applications usually progress from the Account Portal to prebuilt components as they grow, with custom flows used for advanced cases. ## Configuring your application Configuring your application is done through the [Clerk Dashboard](https://dashboard.clerk.com). The Clerk Dashboard is where you, as the application owner, can manage your application's settings, users, and organizations. For example, you can: * Enable phone number authentication or multi-factor authentication. * Add social providers like Google. * Delete users or create Organizations. * Invite other users to your [workspace](/docs/guides/dashboard/overview#workspaces) to help configure and manage your application. To get started, see the [configuration docs](/docs/guides/configure/auth-strategies/sign-up-sign-in-options), which include dedicated guides for specific configuration options. ## Building your application ### Session token When a user is authenticated in your application, Clerk generates a short-lived session token that you can use to authenticate requests to your backend. This token is a JSON Web Token (JWT) that contains information about the user and their session. Read more about Clerk session tokens and how they work in [the guide on how Clerk works](/docs/guides/how-clerk-works/overview). ### Key Clerk objects The Clerk JavaScript SDK, or ClerkJS, is where Clerk all started. It is the core SDK that powers all other JavaScript SDKs, including React and Next.js. As you build, you'll likely interact with the following objects. #### Clerk The Clerk class is the main entry point for the Clerk JavaScript SDK. All other objects are accessible from the `Clerk` object. As you're building your application, you'll likely interact with these objects, either directly or through helpers provided by the other SDKs, like React hooks or Vue composables. #### Client A client represents the current device or software accessing an application such as your web browser, native application, or Chrome Extension. It is represented by the Client object. #### Session A session is a secure representation of the authentication state of the current user. Each client can hold multiple sessions on the same device. It is represented by the Session object. #### User The User object represents the current user of the session. It holds all the basic user information such as the user's name, email addresses, and phone numbers, and including their public, private, and unsafe metadata. #### Organization Organizations are a flexible and scalable way to manage users and their access to resources within your Clerk application. With Organizations, you can assign specific Roles and Permissions to users, making them useful for managing projects, coordinating teams, or facilitating partnerships. Users can belong to many Organizations. One of them will be the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. of the session. It is represented by the Organization object. To learn about Organizations, see the [dedicated guide](/docs/guides/organizations/overview). #### Sign in The SignIn object holds the state of the current sign-in and provides helper methods to navigate and complete the sign-in process. It is used to manage the sign-in lifecycle, including the first and second factor verification, and the creation of a new session. #### Sign up The SignUp object holds the state of the current sign-up and provides helper methods to navigate and complete the sign-up process. Once a sign-up is complete, a new user is created. ## Deep dive For a deeper dive into how Clerk works, like how our authentication model works, see the [dedicated guide](/docs/guides/how-clerk-works/overview). --- title: Set up your Clerk account description: Set up a new Clerk account and integrate it into a new application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/getting-started/quickstart/setup-clerk sourceFile: /docs/getting-started/quickstart/setup-clerk.mdx --- Before you can start integrating Clerk into your application, you need to create a Clerk account and set up a new application in the Clerk Dashboard. This guide will walk you through those steps. > \[!NOTE] > If you're migrating from another platform, see the [migration guides](/docs/guides/development/migrating/overview) to learn how to move your data to Clerk. ## Sign into Clerk [Create a Clerk account](https://dashboard.clerk.com/sign-up) or [sign into the Clerk Dashboard](https://dashboard.clerk.com/). ## Create a Clerk application If you've just created an account for the first time, you'll be taken directly to the interactive authentication setup form. Otherwise, you'll be redirected to the [Clerk Dashboard](https://dashboard.clerk.com/). To create a new app, select the **Create application** card. You'll be redirected to the interactive authentication setup form. ## Select identifiers and social providers Once you are in the interactive authentication setup form, you will be asked to build your authentication flow. Here, Clerk provides various options for setting up your sign-up and sign-in flows. You can choose authentication options like email, phone, username, or social authentication providers. [Learn more about sign-up and sign-in options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options). ## Integrate Clerk into your application Now that your application is created in the Clerk Dashboard, you can integrate it into your codebase. To integrate Clerk into your application, use one of our [quickstarts](/docs/getting-started/quickstart/overview). --- title: Quickstarts description: See the getting started guides and tutorials. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/getting-started/quickstart/overview sourceFile: /docs/getting-started/quickstart/overview.mdx --- ## Full Stack * [Next.js](/docs/nextjs/getting-started/quickstart) * Easily add secure, beautiful, and fast authentication to your Next.js application with Clerk. * *** * [Astro](/docs/astro/getting-started/quickstart) * Easily add secure and SSR-friendly authentication to your Astro application with Clerk. * *** * [Nuxt](/docs/nuxt/getting-started/quickstart) * Easily add secure, beautiful, and fast authentication to Nuxt with Clerk. * *** * [React Router (Beta)](/docs/react-router/getting-started/quickstart) * The Clerk React Router SDK provides prebuilt components, hooks, and stores to make it easy to integrate authentication and user management in your React Router app. * *** * [Remix](/docs/remix/getting-started/quickstart) * Easily add secure, edge- and SSR-friendly authentication to your Remix application with Clerk. * *** * [TanStack React Start (beta)](/docs/tanstack-react-start/getting-started/quickstart) * Easily add secure and SSR-friendly authentication to your TanStack React Start application with Clerk. * ## Frontend * [React](/docs/react/getting-started/quickstart) * Easily add secure, beautiful, and fast authentication to your React application with Clerk. * *** * [Chrome Extension](/docs/chrome-extension/getting-started/quickstart) * Use the Chrome Extension SDK to authenticate users in your Chrome extension. * *** * [Expo](/docs/expo/getting-started/quickstart) * Use Clerk with Expo to authenticate users in your React Native application. * *** * [Android](/docs/android/getting-started/quickstart) * Use the Clerk Android SDK to authenticate users in your native Android applications. * *** * [iOS](/docs/ios/getting-started/quickstart) * Use the Clerk iOS SDK to authenticate users in your native Apple applications. * *** * [JavaScript](/docs/js-frontend/getting-started/quickstart) * Easily add secure, beautiful, and fast authentication to your JavaScript application with Clerk. * *** * [Vue](/docs/vue/getting-started/quickstart) * Easily add secure, beautiful, and fast authentication to your Vue application with Clerk. * ## Backend * [Express](/docs/expressjs/getting-started/quickstart) * Easily add secure, beautiful, and fast authentication to your Express application with Clerk. * *** * [Fastify](/docs/fastify/getting-started/quickstart) * Easily add secure, beautiful, and fast authentication to your Fastify application with Clerk. * * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: Next.js Quickstart (Pages Router) description: Add authentication and user management to your Next.js app with Clerk. sdk: nextjs sdkScoped: "true" canonical: /docs/getting-started/quickstart/pages-router lastUpdated: 2025-11-21T23:37:11.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/getting-started/quickstart/pages-router.mdx --- ## Install `@clerk/nextjs` The [Clerk Next.js SDK](/docs/reference/nextjs/overview) gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Run the following command to install the SDK: ```npm npm install @clerk/nextjs ``` ## Set your Clerk API keys Add the following keys to your `.env` file. These keys can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys){{ track: 'exp_create_account_nextjs_quickstart' }} page. 2. In the **Quick Copy** section, copy your Clerk Publishable and Secret Keys. 3. Paste your keys into your `.env` file. The final result should resemble the following: ```env {{ filename: '.env' }} NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} ``` ## Add `clerkMiddleware()` to your app [`clerkMiddleware()`](/docs/reference/nextjs/clerk-middleware) grants you access to user authentication state throughout your app, on any route or page. It also allows you to protect specific routes from unauthenticated users. To add `clerkMiddleware()` to your app, follow these steps: 1. Create a `middleware.ts` file. * If you're using the `/src` directory, create `middleware.ts` in the `/src` directory. * If you're not using the `/src` directory, create `middleware.ts` in the root directory alongside `.env`. 2. In your `middleware.ts` file, export the `clerkMiddleware()` helper: ```tsx {{ filename: 'middleware.ts' }} import { clerkMiddleware } from '@clerk/nextjs/server' export default clerkMiddleware() export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` 3. By default, `clerkMiddleware()` will not protect any routes. All routes are public and you must opt-in to protection for routes. See the [`clerkMiddleware()` reference](/docs/reference/nextjs/clerk-middleware) to learn how to require authentication for specific routes. ## Add `` and Clerk components to your app The \ component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with `` to make authentication globally accessible. See the reference docs for other configuration options. You can control which content signed-in and signed-out users can see with Clerk's prebuilt control components. Create a header using the following components: * \: Children of this component can only be seen while **signed in**. * \: Children of this component can only be seen while **signed out**. * \: Shows the signed-in user's avatar. Selecting it opens a dropdown menu with account management options. * \: 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: 'pages/_app.tsx', mark: [2, [7, 18], 20] }} import '@/styles/globals.css' import { ClerkProvider, SignInButton, SignedIn, SignedOut, UserButton } from '@clerk/nextjs' import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return ( ) } export default MyApp ``` ## Update `globals.css` In the previous step, the `cssLayerName` property is set on the `` component. Now, you need to **add the following line to the top of your `globals.css` file** in order to include the layer you named in the `cssLayerName` property. The example names the layer `clerk` but you can name it anything you want. These steps are necessary for v4 of Tailwind as it ensures that Tailwind's utility styles are applied after Clerk's styles. ```css {{ filename: 'globals.css' }} + @layer theme, base, clerk, components, utilities; @import 'tailwindcss'; ``` ## Create your first user 1. Run your project with the following command: ```npm npm run dev ``` 2. Visit your app's homepage at [http://localhost:3000](http://localhost:3000). 3. Click "Sign up" in the header and authenticate to create your first user. ## Next steps * [Create a custom sign-in or sign-up page](/docs/nextjs/guides/development/custom-sign-in-or-up-page) * This tutorial gets you started with Clerk's `` component, which uses the Account Portal. If you don't want to use the Account Portal, read this guide about creating a custom authentication page. *** * [Add custom onboarding to your authentication flow](/docs/guides/development/add-onboarding-flow) * If you need to collect additional information about users that Clerk's Account Portal or prebuilt components don't collect, read this guide about adding a custom onboarding flow to your authentication flow. *** * [Protect specific routes](/docs/reference/nextjs/clerk-middleware) * This tutorial taught you that by default, `clerkMiddleware()` will not protect any routes. Read this reference doc to learn how to protect specific routes from unauthenticated users. *** * [Protect content and read user data](/docs/nextjs/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your Next.js app. *** * [Next.js SDK Reference](/docs/reference/nextjs/overview) * Learn more about the Clerk Next.js SDK and how to use it. *** * [Deploy to Production](/docs/guides/development/deployment/production) * Learn how to deploy your Clerk app to production. --- title: SDK References description: Learn about the Clerk and community SDK's available for integrating Clerk into your application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/reference/overview sourceFile: /docs/reference/overview.mdx --- {/* TODO: Keep aligned with /index */} ## Frontend SDKs * [Next.js](/docs/reference/nextjs/overview) * Easily add secure, beautiful, and fast authentication to Next.js with Clerk. * *** * [React](/docs/reference/react/overview) * Get started installing and initializing Clerk in a new React + Vite app. * *** * [Astro](/docs/reference/astro/overview) * Easily add secure and SSR-friendly authentication to your Astro application with Clerk. * *** * [Chrome Extension](/docs/reference/chrome-extension/overview) * Use the Chrome Extension SDK to authenticate users in your Chrome extension. * *** * [Expo](/docs/reference/expo/overview) * Use Clerk with Expo to authenticate users in your React Native application. * *** * [iOS](/docs/reference/ios/overview) * Use the Clerk iOS SDK to authenticate users in your native Apple applications. * *** * [JavaScript](/docs/reference/javascript/overview) * The Clerk JavaScript SDK gives you access to prebuilt components and helpers to make user authentication easier. * *** * [Nuxt](/docs/reference/nuxt/overview) * Easily add secure, beautiful, and fast authentication to Nuxt with Clerk. * *** * [React Router](/docs/reference/react-router/overview) * Easily add secure, edge- and SSR-friendly authentication to React Router with Clerk. * *** * [Remix](/docs/reference/remix/overview) * Easily add secure, edge- and SSR-friendly authentication to Remix with Clerk. * *** * [TanStack React Start (beta)](/docs/reference/tanstack-react-start/overview) * Easily add secure and SSR-friendly authentication to your TanStack React Start application with Clerk. * *** * [Vue](/docs/reference/vue/overview) * Get started installing and initializing Clerk in a new Vue + Vite app. * ## Backend SDKs * [JS Backend SDK](/docs/reference/backend/overview) * The Javascript Backend SDK exposes our Backend API resources and low-level authentication utilities for JavaScript environments. * *** * [C#](https://github.com/clerk/clerk-sdk-csharp/blob/main/README.md) * The Clerk C# SDK is a wrapper around our Backend API to make it easier to integrate Clerk into your backend. * *** * [Express](/docs/reference/express/overview) * Quickly add authentication and user management to your Express application. * *** * [Go](/docs/reference/go/overview) * The Clerk Go SDK is a wrapper around the Backend API written in Golang to make it easier to integrate Clerk into your backend. * *** * [Fastify](/docs/reference/fastify/overview) * Build secure authentication and user management flows for your Fastify server. * *** * [Python](https://github.com/clerk/clerk-sdk-python/blob/main/README.md) * The Clerk Python SDK is a wrapper around the Backend API written in Python to make it easier to integrate Clerk into your backend. * *** * [Ruby on Rails](/docs/reference/ruby/overview) * Integrate authentication and user management into your Ruby application. * ## Build with community-maintained SDKs * [Angular](https://github.com/anagstef/ngx-clerk?tab=readme-ov-file#ngx-clerk) * Visit the community-maintained repository to learn how to integrate Clerk into your Angular application. * { } *** * [Elysia](https://github.com/wobsoriano/elysia-clerk) * Visit the community-maintained plugin for integrating Clerk with Elysia. * {} *** * [Hono](https://github.com/honojs/middleware/tree/main/packages/clerk-auth) * Visit the community-maintained repository to learn how to integrate Clerk into your Hono application. * {} *** * [Koa](https://github.com/dimkl/clerk-koa/blob/main/README.md) * Visit the community-maintained repository to learn how to integrate Clerk into your Koa application. * {} *** * [SolidJS](https://github.com/spirit-led-software/clerk-solidjs) * Visit the community-maintained repository to learn how to integrate Clerk into your SolidJS application. * {} *** * [Svelte](https://github.com/wobsoriano/svelte-clerk) * Visit the community-maintained adapter for integrating Clerk with SvelteKit. * {} *** * [Rust](https://github.com/DarrenBaldwin07/clerk-rs) * Visit the community-maintained Rust SDK to integrate Clerk with Rust. * {} * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`authenticateRequest()`" description: Use Clerk's JS Backend SDK to verify a token passed from the frontend. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/authenticate-request lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/authenticate-request.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/tokens/request.ts#L62 */} Authenticates a token passed from the frontend. Networkless if the `jwtKey` is provided. Otherwise, performs a network call to retrieve the JWKS from the [Backend API](/docs/reference/backend-api/tag/jwks/get/jwks){{ target: '_blank' }}. ```ts function authenticateRequest( request: Request, options: AuthenticateRequestOptions, ): Promise ``` ## Parameters * `request` * `Request` `Request` object *** * `options?` * [`AuthenticateRequestOptions`](#authenticate-request-options) Optional options to configure the authentication. ## `AuthenticateRequestOptions` It is recommended to set these options as [environment variables](/docs/guides/development/clerk-environment-variables#api-and-sdk-configuration) where possible, and then pass them to the function. For example, you can set the `secretKey` option using the `CLERK_SECRET_KEY` environment variable, and then pass it to the function like this: `createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })`. > \[!WARNING] > You must provide either `jwtKey` or `secretKey`. > > For better security, it's highly recommended to explicitly set the `authorizedParties` option when authorizing requests. The value should be a list of domains that are allowed to make requests to your application. Not setting this value can open your application to [CSRF attacks](https://owasp.org/www-community/attacks/csrf). | Property | Type | Description | | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`acceptsToken?` | "api\_key" \| "session\_token" \| "m2m\_token" \| "oauth\_token" \| ("api\_key" \| "session\_token" \| "m2m\_token" \| "oauth\_token")\[] \| "any" | The type of token to accept. Defaults to `'session_token'`. | | `afterSignInUrl?` | `string` | Full URL or path to navigate to after successful sign in. Defaults to `'/'`. | | `afterSignUpUrl?` | `string` | Full URL or path to navigate to after successful sign up. Defaults to `'/'`. | | `apiUrl?` | `string` | The [Clerk Backend API](/docs/reference/backend-api){{ target: '_blank' }} endpoint. Defaults to `'https://api.clerk.com'`. | | `apiVersion?` | `string` | The version passed to the Clerk API. Defaults to `'v1'`. | | `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. Example: `['http://localhost:3000', 'https://example.com']`. | | `clockSkewInMs?` | `number` | Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to `5000`. | | `domain?` | `string` | The domain of a [satellite application](/docs/guides/dashboard/dns-domains/satellite-domains) in a multi-domain setup. | | `isSatellite?` | `boolean` | Whether the instance is a satellite domain in a multi-domain setup. Defaults to `false`. | | ~~`jwksCacheTtlInMs?`~~ | `number` | **Deprecated.** This cache TTL will be removed in the next major version. Specifying a cache TTL is a no-op. | | `jwtKey?` | `string` | Used to verify the session token in a networkless manner. Supply the PEM public key from the **[**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page -> Show JWT public key -> PEM Public Key** section in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). | | `machineSecretKey?` | `string` | The machine secret key to use when verifying machine-to-machine tokens. This will override the Clerk secret key. | | `organizationSyncOptions?` | \{ organizationPatterns?: string\[]; personalAccountPatterns?: string\[]; \} | Used to activate a specific [organization](/docs/guides/organizations/overview) or [personal account](/docs/guides/dashboard/overview) based on URL path parameters. If there's a mismatch between the active organization in the session (e.g., as reported by `auth()`) and the organization indicated by the URL, an attempt to activate the organization specified in the URL will be made. If the activation can't be performed, either because an organization doesn't exist or the user lacks access, the active organization in the session won't be changed. Ultimately, it's the responsibility of the page to verify that the resources are appropriate to render given the URL and handle mismatches appropriately (e.g., by returning a 404). | | `organizationSyncOptions.organizationPatterns?` | string\[] | 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). If the organization can't be activated—either because it doesn't exist or the user lacks access—the previously 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 \. Examples: `["/orgs/:slug",, "/orgs/:slug/(.*)"]`, `["/orgs/:id",, "/orgs/:id/(.*)"]`, `["/app/:any/orgs/:slug",, "/app/:any/orgs/:slug/(.*)"]`. | | `organizationSyncOptions.personalAccountPatterns?` | string\[] | URL patterns for resources that exist within the context of a [Clerk Personal Account](/docs/guides/dashboard/overview) (user-specific, outside any organization). If the route also matches the `organizationPattern` prop, the `organizationPattern` prop takes precedence. Examples: `["/user",, "/user/(.*)"]`, `["/user/:any",, "/user/:any/(.*)"]`. | | `proxyUrl?` | `string` | The proxy URL from a multi-domain setup. | | `publishableKey?` | `string` | The Clerk Publishable Key from the [**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard. | | `secretKey?` | `string` | The Clerk Secret Key from the [**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard. | | `signInUrl?` | `string` | The sign-in URL from a multi-domain setup. | | `signUpUrl?` | `string` | The sign-up URL from a multi-domain setup. | | `skipJwksCache?` | `boolean` | A flag to ignore the JWKS cache and always fetch JWKS before each JWT verification. | ## Returns * `isAuthenticated` * `boolean` A boolean that indicates whether the incoming request is authenticated. Initially `false`, becomes `true` once the request is authenticated. *** * `isSignedIn` (deprecated) * `boolean` **Deprecated. Use `isAuthenticated` instead.** Indicates whether the incoming request is authenticated. *** * `status` * `'signed-in' | 'signed-out' | 'handshake'` The authentication state. *** * `reason` * `string | null` The error code or reason for the current state. When there is a signed-in user, the value will be `null`. *** * `message` * `string | null` The full error message or additional context. When there is a signed-in user, the value will be `null`. *** * `tokenType` * `'session_token' | 'oauth_token' | 'm2m_token' | 'api_key'` The type of token. *** * `token` * `string` The value of the token. *** * `headers` * [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) A `Headers` object containing debug or status headers. *** * `toAuth()` * `function` A function that returns the `Auth` object. This JavaScript object contains important information like the current user's session ID, user ID, and Organization ID. Learn more about the [`Auth` object](/docs/reference/backend/types/auth-object){{ target: '_blank' }}. ## Examples If you are using the [JS Backend SDK](/docs/js-backend/getting-started/quickstart) on its own, you need to provide the `secretKey` and `publishableKey` to `createClerkClient()` so that it is passed to `authenticateRequest()`. You can set these values as [environment variables](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys) and then pass them to the function. ```tsx import { createClerkClient } from '@clerk/backend' export async function GET(req: Request) { const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY, publishableKey: process.env.CLERK_PUBLISHABLE_KEY, }) const { isAuthenticated } = await clerkClient.authenticateRequest(req, { authorizedParties: ['https://example.com'], }) if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` `authenticateRequest()` requires `publishableKey` to be set. If you are importing `clerkClient` from a higher-level SDK, such as Next.js, then `clerkClient` infers the `publishableKey` from your [environment variables](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys). **The following example uses Next.js, but you can use the comments in the example to help you adapt it to other SDKs.** ```tsx import { clerkClient } from '@clerk/nextjs/server' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const client = await clerkClient() export async function GET(req: Request) { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await client.authenticateRequest(req, { authorizedParties: ['https://example.com'], }) // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` ### Machine authentication By default, `authenticateRequest()` will authenticate a session request. To authenticate a machine request, you need to set the `acceptsToken` option to a machine token type, such as `'api_key'`, `'oauth_token'` or `'m2m_token'`. ```tsx import { createClerkClient } from '@clerk/backend' export async function GET(request: Request) { // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY, publishableKey: process.env.CLERK_PUBLISHABLE_KEY, }) // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await clerkClient.authenticateRequest(request, { acceptsToken: 'oauth_token', }) // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a machine-to-machine reply' }) } ``` **This example uses Next.js, but you can use the comments in the example to help you adapt it to other SDKs.** ```tsx import { clerkClient } from '@clerk/nextjs/server' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const client = await clerkClient() export async function GET(req: Request) { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await client.authenticateRequest(request, { acceptsToken: 'oauth_token', }) // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a machine-to-machine reply' }) } ``` ### Networkless token verification The following example uses the `authenticateRequest()` method with the [JS Backend SDK](/docs/js-backend/getting-started/quickstart) to verify the token passed by the frontend, and performs a networkless authentication by passing `jwtKey`. This will verify if the user is signed into the application or not. ```tsx {{ filename: 'app/api/example/route.ts' }} import { clerkClient } from '@clerk/nextjs/server' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const client = await clerkClient() export async function GET(req: Request) { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await client.authenticateRequest(req, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import { clerkClient } from '@clerk/astro/server' import type { APIRoute } from 'astro' export const GET: APIRoute = async (context) => { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await clerkClient(context).authenticateRequest(context.request, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` ```js {{ filename: 'index.js' }} import { createClerkClient } from '@clerk/express' import express from 'express' const app = express() const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) app.get('/user', async (req, res) => { const { isAuthenticated } = await clerkClient.authenticateRequest(req, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) if (!isAuthenticated) { res.status(401).json({ error: 'User not authenticated' }) } // Add logic to perform protected actions // Return the Backend User object res.json({ message: 'This is a reply' }) }) ``` If you are using the [JS Backend SDK](/docs/js-backend/getting-started/quickstart) on its own, you need to provide the `secretKey` and `publishableKey` to `createClerkClient()` so that it is passed to `authenticateRequest()`. You can set these values as [environment variables](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys) and then pass them to the function. ```tsx import { createClerkClient } from '@clerk/backend' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY, publishableKey: process.env.CLERK_PUBLISHABLE_KEY, }) export async function GET(req: Request) { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await clerkClient.authenticateRequest(req, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { redirect } from 'react-router' import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' export async function loader(args: Route.LoaderArgs) { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await clerkClient(args).authenticateRequest(args.request, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { createFileRoute } from '@tanstack/react-router' import { clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { GET: async ({ request }) => { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await clerkClient().authenticateRequest(request, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) }, }, }, }) ``` --- title: Clerk's JavaScript Backend SDK description: The Clerk JavaScript Backend SDK exposes Clerk's Backend API resources and low-level authentication utilities for JavaScript environments. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/overview.mdx --- Clerk's JavaScript Backend SDK exposes the [Backend API](/docs/reference/backend-api){{ target: '_blank' }} resources and low-level authentication utilities for JavaScript environments, making it easier to integrate Clerk into your server-side applications. ## Installation Follow the instructions in the quickstart to add the JS Backend SDK to your project. ## Resources The SDK is organized around resources, such as **Users** and **Organizations**. Each resource provides a set of operations (for example, creating, listing, or updating) that map directly to the Backend API. Each section below highlights the primary resources available in the SDK. For a complete list of resources and operations, see the [Backend API reference](/docs/reference/backend-api){{ target: '_blank' }}. ### Users The **User** resource provides operations for creating, retrieving, and managing users within your application. Most operations return, or work directly with, the Backend [`User`](/docs/reference/backend/types/backend-user) object, which represents a user who has successfully signed up to your application. It holds information about a user, such as their unique identifier, name, email addresses, phone numbers, and more. ### Organizations The **Organization** resource provides operations for creating, retrieving, and managing Organizations within your application. Most operations return, or work directly with, the following Backend objects: * [`Organization`](/docs/reference/backend/types/backend-organization) object holds information about an Organization. * [`OrganizationInvitation`](/docs/reference/backend/types/backend-organization-invitation) object is the model around an Organization invitation. * [`OrganizationMembership`](/docs/reference/backend/types/backend-organization-membership) object is the model around an Organization membership entity and describes the relationship between users and Organizations. ### Billing The **Billing** resource provides operations for creating and managing Subscription Plans and Features within your application. Most operations return, or work directly with, the following Backend objects: * [`CommerceSubscription`](/docs/reference/backend/types/commerce-subscription) object holds information about a Subscription, as well as methods for managing it. * [`CommerceSubscriptionItem`](/docs/reference/backend/types/commerce-subscription-item) object holds information about a Subscription Item, as well as methods for managing it. * [`CommercePlan`](/docs/reference/backend/types/commerce-plan) object holds information about a Plan, as well as methods for managing it. * [`Feature`](/docs/reference/backend/types/feature) object represents a Feature of a Subscription Plan. ### Allowlist identifiers The **Allowlist Identifier** resource allows you to control who can sign up or sign in to your application, by restricting access based on the user's email address or phone number. Most operations return, or work directly with, the Backend [`AllowlistIdentifier`](/docs/reference/backend/types/backend-allowlist-identifier) object, which represents an identifier that has been added to the allowlist of your application. ### Domains The **Domain** resource allows you to manage the domains associated with your Clerk instance. Each domain contains information about the URLs where Clerk operates and the required CNAME targets. ### Sessions The **Session** resource provides operations for creating, retrieving, and managing sessions within your application. Sessions are created when a user successfully goes through the sign-in or sign-up flows. Most operations return, or work directly with, the Backend [`Session`](/docs/reference/backend/types/backend-session) object, which is an abstraction over an HTTP session and models the period of information exchange between a user and the server. ### Clients The **Client** resource provides operations for creating, retrieving, and managing clients within your application. Most operations return, or work directly with, the Backend [`Client`](/docs/reference/backend/types/backend-client) object, which tracks authenticated sessions for a given device or software accessing your application, such as your web browser, native application, or Chrome Extension. ### Invitations The **Invitation** resource allows you to manage invitations for your application. Invitations allow you to invite someone to sign up to your application, via email. Most operations return, or work directly with, the Backend [`Invitation`](/docs/reference/backend/types/backend-invitation) object, which represents an invitation that has been sent to a potential user. ### Redirect URLs The **Redirect URL** resource allows you to manage the redirect URLs associated with your Clerk instance. Redirect URLs are whitelisted URLs that facilitate secure authentication flows in native applications, such as React Native or Expo. In these contexts, Clerk ensures that security-critical nonces are passed only to the whitelisted URLs. Most operations return, or work directly with, the Backend [`RedirectURL`](/docs/reference/backend/types/backend-redirect-url) object, which holds information about a redirect URL. ### Email addresses The **Email Address** resource allows you to manage email addresses associated with your users. Email addresses are one of the identifiers used to provide identification for users. They must be verified to ensure that they are assigned to their rightful owners. Most operations return, or work directly with, the Backend [`EmailAddress`](/docs/reference/backend/types/backend-email-address) object, which holds all necessary state around the verification process. ### Phone numbers The **Phone Number** resource allows you to manage phone numbers associated with your users. Phone numbers can be used as a proof of identification for users, or simply as a means of contacting users. They must be verified to ensure that they are assigned to the rightful owners. Most operations return, or work directly with, the Backend [`PhoneNumber`](/docs/reference/backend/types/backend-phone-number) object, which holds all necessary state around the verification process. ### SAML connections The **SAML Connection** resource allows you to manage SAML connections associated with your Organizations. A SAML Connection holds configuration data required for facilitating a SAML SSO flow between your Clerk Instance (SP) and a particular SAML IdP. Most operations return, or work directly with, the Backend [`SamlConnection`](/docs/reference/backend/types/backend-saml-connection) object, which holds information about a SAML connection for an Organization. ### Sign-in tokens The **Sign-in Token** resource allows you to create and manage sign-in tokens for your application. Sign-in tokens are JWTs that can be used to sign in to an application without specifying any credentials. A sign-in token can be used at most once and can be consumed from the Frontend API using the `ticket` strategy. ### Testing tokens The **Testing Token** resource allows you to create and manage [testing tokens](/docs/guides/development/testing/overview#testing-tokens) for your application. Testing tokens allow you to bypass bot detection mechanisms that protect Clerk applications from malicious bots, ensuring your end-to-end test suites run smoothly. Without Testing tokens, you may encounter "Bot traffic detected" errors in your requests. ### M2M tokens The **M2M Token** resource allows you to create and manage [machine-to-machine (M2M) tokens](/docs/guides/development/machine-auth/m2m-tokens) for your application. M2M tokens allow you to manage authentication between machines. It is intended primarily as a method for authenticating requests between different backend services within your own infrastructure. ### OAuth applications The **OAuth Application** resource allows you to create and manage OAuth applications for your Clerk instance. OAuth applications contain data for clients using Clerk as an OAuth2 identity provider. Most operations return, or work directly with, the Backend [`OAuthApplication`](/docs/reference/backend/types/backend-oauth-application) object, which holds information about an OAuth application. ## Authentication utilities In addition to the resources listed above, the JS Backend SDK also provides low-level authentication utilities that can be used to verify Clerk-generated tokens and authenticate requests from your frontend: * [`authenticateRequest()`](/docs/reference/backend/authenticate-request): Authenticates a token passed from the frontend. * [`verifyToken()`](/docs/reference/backend/verify-token): Verifies a Clerk-generated token signature. * [`verifyWebhook()`](/docs/reference/backend/verify-webhook): Verifies the authenticity of a webhook request using Svix. --- title: "`verifyToken()`" description: Use Clerk's JS Backend SDK to verify a token signature. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/verify-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/verify-token.mdx --- > \[!WARNING] > This is a lower-level method intended for more advanced use-cases. It's recommended to use [`authenticateRequest()`](/docs/reference/backend/authenticate-request), which fully authenticates a token passed from the `request` object. ```ts function verifyToken( token: string, options: { apiUrl?: string; apiVersion?: string; audience?: string | string[]; authorizedParties?: string[]; clockSkewInMs?: number; jwksCacheTtlInMs?: number; jwtKey?: string; secretKey?: string; skipJwksCache?: boolean; }, ): Promise>; ``` Verifies a Clerk-generated token signature. Networkless if the `jwtKey` is provided. Otherwise, performs a network call to retrieve the JWKS from the [Backend API](/docs/reference/backend-api/tag/JWKS#operation/GetJWKS){{ target: '_blank' }}. ## Parameters | Parameter | Type | Description | | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `token` | `string` | The token to verify. | | `options` | \{ apiUrl?: string; apiVersion?: string; audience?: string \| string\[]; authorizedParties?: string\[]; clockSkewInMs?: number; jwksCacheTtlInMs?: number; jwtKey?: string; secretKey?: string; skipJwksCache?: boolean; \} | Options for verifying the token. It is recommended to set these options as [environment variables](/docs/guides/development/clerk-environment-variables#api-and-sdk-configuration) where possible, and then pass them to the function. For example, you can set the `secretKey` option using the `CLERK_SECRET_KEY` environment variable, and then pass it to the function like this: `verifyToken(token, { secretKey: process.env.CLERK_SECRET_KEY })`. | | `options.apiUrl?` | `string` | The [Clerk Backend API](/docs/reference/backend-api){{ target: '_blank' }} endpoint. Defaults to `'https://api.clerk.com'`. | | `options.apiVersion?` | `string` | The version passed to the Clerk API. Defaults to `'v1'`. | | `options.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. | | `options.authorizedParties?` | string\[] | An allowlist of origins to verify against, to protect your application from the subdomain cookie leaking attack. Example: `['http://localhost:3000', 'https://example.com']`. | | `options.clockSkewInMs?` | `number` | Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to `5000`. | | `options.jwksCacheTtlInMs?` | `number` | **Deprecated.** This cache TTL will be removed in the next major version. Specifying a cache TTL is a no-op. | | `options.jwtKey?` | `string` | Used to verify the session token in a networkless manner. Supply the PEM public key from the **[**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page -> Show JWT public key -> PEM Public Key** section in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). | | `options.secretKey?` | `string` | The Clerk Secret Key from the [**API keys**](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard. | | `options.skipJwksCache?` | `boolean` | A flag to ignore the JWKS cache and always fetch JWKS before each JWT verification. | ## Example The following example demonstrates how to use the [JavaScript Backend SDK](/docs/reference/backend/overview) to verify the token signature. In the following example: 1. The **JWKS Public Key** from the Clerk Dashboard is set in the environment variable `CLERK_JWT_KEY`. 2. The session token is retrieved from the `__session` cookie or the Authorization header. 3. The token is verified in a networkless manner by passing the `jwtKey` prop. 4. The `authorizedParties` prop is passed to verify that the session token is generated from the expected frontend application. 5. If the token is valid, the response contains the verified token. ```ts import { verifyToken } from "@clerk/backend"; import { cookies } from "next/headers"; export async function GET(request: Request) { const cookieStore = cookies(); const sessToken = cookieStore.get("__session")?.value; const bearerToken = request.headers .get("Authorization") ?.replace("Bearer ", ""); const token = sessToken || bearerToken; if (!token) { return Response.json( { error: "Token not found. User must sign in." }, { status: 401 }, ); } try { const verifiedToken = await verifyToken(token, { jwtKey: process.env.CLERK_JWT_KEY, authorizedParties: ["http://localhost:3001", "api.example.com"], // Replace with your authorized parties }); return Response.json({ verifiedToken }); } catch (error) { return Response.json({ error: "Token not verified." }, { status: 401 }); } } ``` If the token is valid, the response will contain a JSON object that looks something like this: ```json { "verifiedToken": { "azp": "http://localhost:3000", "exp": 1687906422, "iat": 1687906362, "iss": "https://magical-marmoset-51.clerk.accounts.dev", "nbf": 1687906352, "sid": "sess_2Ro7e2IxrffdqBboq8KfB6eGbIy", "sub": "user_2RfWKJREkjKbHZy0Wqa5qrHeAnb" } } ``` --- title: "`verifyWebhook()`" description: Use Clerk's JS Backend SDK to verify a webhook signature. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/verify-webhook lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/verify-webhook.mdx --- Verifies the authenticity of a webhook request using Standard Webhooks. Returns a promise that resolves to the verified webhook event data. ```ts function verifyWebhook( request: Request, options: { signingSecret?: string }, ): Promise; ``` ## Parameters | Parameter | Type | Description | | ------------------------ | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `request` | `Request` | The request object. | | `options` | \{ signingSecret?: string; \} | Optional configuration object. | | `options.signingSecret?` | `string` | The signing secret for the webhook. It's recommended to use the [`CLERK_WEBHOOK_SIGNING_SECRET` environment variable](/docs/guides/development/clerk-environment-variables#webhooks) instead. | ## Example See the [guide on syncing data](/docs/guides/development/webhooks/syncing) for more comprehensive and framework-specific examples that you can copy and paste into your app. ```ts import { verifyWebhook } from "@clerk/backend/webhooks"; export async function POST(request: Request) { try { const evt = await verifyWebhook(request); // Access the event data const { id } = evt.data; const eventType = evt.type; // Handle specific event types if (evt.type === "user.created") { console.log("New user created:", evt.data.id); // Handle user creation } return new Response("Success", { status: 200 }); } catch (err) { console.error("Webhook verification failed:", err); return new Response("Webhook verification failed", { status: 400 }); } } ``` --- title: "`createAllowlistIdentifier()`" description: Use Clerk's JS Backend SDK to add a new identifier to the allowlist. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/allowlist/create-allowlist-identifier lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/allowlist/create-allowlist-identifier.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/AllowlistIdentifierApi.ts#L22 */} Adds a new identifier to the allowlist. Returns the created [`AllowlistIdentifier`](/docs/reference/backend/types/backend-allowlist-identifier) object. ```ts function createAllowlistIdentifier( params: AllowlistIdentifierCreateParams, ): Promise ``` ## `AllowlistIdentifierCreateParams` * `identifier` * `string` The identifier to be added in the allowlist. Can be an email address, a phone number in international [E.164](https://en.wikipedia.org/wiki/E.164) format, a domain, or a Web3 wallet address. *** * `notify` * `boolean` Whether the given identifier will receive an invitation to join the application. Note that this only works for email address and phone number identifiers. Not available for wildcard identifiers or Web3 wallet addresses. Defaults to `true`. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.allowlistIdentifiers.createAllowlistIdentifier({ identifier: 'test@example.com', notify: false, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/allowlist-identifiers`. See the [BAPI reference](/docs/reference/backend-api/tag/allow-list-block-list/post/allowlist_identifiers){{ target: '_blank' }} for more information. --- title: "`deleteAllowlistIdentifier()`" description: Use Clerk's JS Backend SDK to delete an allowlist identifier. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/allowlist/delete-allowlist-identifier lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/allowlist/delete-allowlist-identifier.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/AllowlistIdentifierApi.ts#L30 */} Deletes an [`AllowlistIdentifier`](/docs/reference/backend/types/backend-allowlist-identifier). ```ts function deleteAllowlistIdentifier(allowlistIdentifierId: string): Promise ``` ## Parameters * `allowlistIdentifierId` * `string` The ID of the allowlist identifier to delete. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const allowlistIdentifierId = 'alid_123' const response = await clerkClient.allowlistIdentifiers.deleteAllowlistIdentifier(allowlistIdentifierId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/allowlist-identifiers/{identifier_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/allow-list-block-list/delete/allowlist_identifiers/\{identifier_id}){{ target: '_blank' }} for more information. --- title: "`getAllowlistIdentifierList()`" description: Use Clerk's JS Backend SDK to retrieve a list of allowlist identifiers. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/allowlist/get-allowlist-identifier-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/allowlist/get-allowlist-identifier-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/AllowlistIdentifierApi.ts#L14 */} Retrieves the list of all allowlist identifiers. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`AllowlistIdentifier`](/docs/reference/backend/types/backend-allowlist-identifier) objects, and a `totalCount` property that indicates the total number of allowlist identifiers in the system. ```ts function getAllowlistIdentifierList(): Promise> ``` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.allowlistIdentifiers.getAllowlistIdentifierList() ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/allowlist-identifiers`. See the [BAPI reference](/docs/reference/backend-api/tag/allow-list-block-list/get/allowlist_identifiers){{ target: '_blank' }} for more information. --- title: "`getPlanList()`" description: Use Clerk's JS Backend SDK to retrieve a list of Billing Plans. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/billing/get-plan-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/billing/get-plan-list.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/BillingApi.ts */} Retrieves a list of Billing Plans. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`CommercePlan`](/docs/reference/backend/types/commerce-plan) objects, and a `totalCount` property that indicates the total number of Billing Plans. ```ts function getPlanList( params?: GetOrganizationListParams, ): Promise> ``` ## `GetOrganizationListParams` * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. Defaults to `0`. *** * `payerType?` * `'org' | 'user'` Filter Plans by payer type. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const { data, totalCount } = await clerkClient.billing.getPlanList({ payerType: 'org' }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET /commerce/plans`. See the [BAPI reference](https://clerk.com/docs/reference/backend-api/tag/commerce/get/commerce/plans){{ target: '_blank' }} for more information. --- title: "`getOrganizationBillingSubscription()`" description: Use Clerk's JS Backend SDK to retrieve an Organization's Billing Subscription. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/billing/get-organization-billing-subscription lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/billing/get-organization-billing-subscription.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/BillingApi.ts */} Retrieves an Organization's Billing Subscription. Returns a [`CommerceSubscription`](/docs/reference/backend/types/commerce-subscription). ```ts function getOrganizationBillingSubscription(organizationId: string): Promise ``` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const organizationId = 'org_123' const subscription = await clerkClient.billing.getOrganizationBillingSubscription(organizationId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET /organizations/{organization_id}/billing/subscription`. See the [BAPI reference](https://clerk.com/docs/reference/backend-api/tag/billing/get/organizations/%7Borganization_id%7D/billing/subscription){{ target: '_blank' }} for more information. --- title: "`cancelSubscriptionItem()`" description: Use Clerk's JS Backend SDK to cancel a subscription item. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/billing/cancel-subscription-item lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/billing/cancel-subscription-item.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/BillingApi.ts */} Cancels a subscription item. Returns the updated [`CommerceSubscriptionItem`](/docs/reference/backend/types/commerce-subscription-item). ```ts function cancelSubscriptionItem( subscriptionItemId: string, params?: CancelSubscriptionItemParams, ): Promise ``` ## `CancelSubscriptionItemParams` * `endNow?` * `boolean` If `true`, the subscription item will be canceled immediately. If `false` or omitted, it will be canceled at the end of the current billing period. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.billing.cancelSubscriptionItem('subi_123', { endNow: true }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE /commerce/subscription_items/{id}`. See the [BAPI reference](https://clerk.com/docs/reference/backend-api/tag/commerce/delete/commerce/subscription_items/%7Bsubscription_item_id%7D){{ target: '_blank' }} for more information. --- title: "`getUserBillingSubscription()`" description: Use Clerk's JS Backend SDK to retrieve a user's Billing Subscription. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/billing/get-user-billing-subscription lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/billing/get-user-billing-subscription.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/BillingApi.ts */} Retrieves a user's Billing Subscription. Returns a [`CommerceSubscription`](/docs/reference/backend/types/commerce-subscription). ```ts function getUserBillingSubscription(userId: string): Promise ``` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const subscription = await clerkClient.billing.getUserBillingSubscription(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET /users/{user_id}/billing/subscription`. See the [BAPI reference](/docs/reference/backend-api/tag/billing/get/users/%7Buser_id%7D/billing/subscription){{ target: '_blank' }} for more information. --- title: "`deleteDomain()`" description: Use Clerk's JS Backend SDK to delete a satellite domain for the instance. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/domains/delete-domain lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/domains/delete-domain.mdx --- Deletes a satellite domain for the instance. It is currently not possible to delete the instance's primary domain. Returns a DeletedObjectResource. ```ts function deleteDomain(id: string): Promise ``` ## Parameters * `id` * `string` The ID of the domain that will be deleted. Must be a satellite domain. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const id = 'test_123' const response = await clerkClient.users.deleteDomain(id) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/domains/{domain_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/domains/delete/domains/\{domain_id}){{ target: '_blank' }} for more information. --- title: "`getClientList()` (deprecated)" description: Retrieves the list of clients. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/client/get-client-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/client/get-client-list.mdx --- > \[!CAUTION] > This method is now deprecated. ```tsx const clients = await clerkClient.clients.getClientList() ``` --- title: "`getClient()`" description: Use Clerk's JS Backend SDK to retrieve a single client by its ID. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/client/get-client lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/client/get-client.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/ClientApi.ts#L19 */} Retrieves a single Client. ```ts function getClient(clientId: string): Promise ``` ## Parameters * `clientId` * `string` The ID of the client to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const clientId = 'client_123' const response = await clerkClient.clients.getClient(clientId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/clients/{client_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/clients/get/clients/\{client_id}){{ target: '_blank' }} for more information. --- title: "`verifyClient()`" description: Use Clerk's JS Backend SDK to retrieve a client for a given session token, if the session is active. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/client/verify-client lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/client/verify-client.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/ClientApi.ts#L27 */} Verifies the Client in the provided token. ```ts function verifyClient(token: string): Promise ``` ## Parameters * `token` * `string` The session token to verify. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const token = 'my-session-token' const response = await clerkClient.clients.verifyClient(token) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/clients/verify`. See the [BAPI reference](/docs/reference/backend-api/tag/clients/post/clients/verify){{ target: '_blank' }} for more information. --- title: "`createEmailAddress()`" description: Use Clerk's JS Backend SDK to create an email address for the specified user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/email-addresses/create-email-address lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/email-addresses/create-email-address.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/EmailAddressApi.ts#L29 */} Creates an EmailAddress for the specified user. ```ts function createEmailAddress(params: CreateEmailAddressParams): Promise ``` ## `CreateEmailAddressParams` * `userId` * `string` The ID of the user to create the email address for. *** * `emailAddress` * `string` The email address to assign to the specified user. *** * `primary?` * `boolean` Whether or not to set the email address as the user's primary email address. Defaults to `false`, unless it is the first email address. *** * `verified?` * `boolean` Whether or not the email address is verified. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.emailAddresses.createEmailAddress({ userId: 'user_123', emailAddress: 'testclerk123@gmail.com', primary: true, verified: true, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/email_addresses`. See the [BAPI reference](/docs/reference/backend-api/tag/email-addresses/post/email_addresses){{ target: '_blank' }} for more information. --- title: "`deleteEmailAddress()`" description: Use Clerk's JS Backend SDK to delete an email address. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/email-addresses/delete-email-address lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/email-addresses/delete-email-address.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/EmailAddressApi.ts#L47 */} Deletes an EmailAddress. ```ts function deleteEmailAddress(emailAddressId: string): Promise ``` ## Parameters * `emailAddressId` * `string` The ID of the email address to delete. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const emailAddressId = 'idn_123' const response = await clerkClient.emailAddresses.deleteEmailAddress(emailAddressId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/email_addresses/{email_address_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/email-addresses/delete/email_addresses/\{email_address_id}){{ target: '_blank' }} for more information. --- title: "`updateEmailAddress()`" description: Use Clerk's JS Backend SDK to update an email address. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/email-addresses/update-email-address lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/email-addresses/update-email-address.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/EmailAddressApi.ts#L37 */} Updates an EmailAddress. ```ts function updateEmailAddress( emailAddressId: string, params: UpdateEmailAddressParams, ): Promise ``` ## `UpdateEmailAddressParams` * `primary?` * `boolean` Whether or not to set the email address as the user's primary email address. *** * `verified?` * `boolean` Whether or not the email address is verified. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx {{ mark: [[12, 13]] }} const emailAddressId = 'idn_123' const params = { verified: false } const response = await clerkClient.emailAddresses.updateEmailAddress(emailAddressId, params) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/email_addresses/{email_address_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/email-addresses/patch/email_addresses/\{email_address_id}){{ target: '_blank' }} for more information. --- title: "`getEmailAddress()`" description: Use Clerk's JS Backend SDK to retrieve a single email address by its ID. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/email-addresses/get-email-address lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/email-addresses/get-email-address.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/EmailAddressApi.ts#L20 */} Retrieves a single EmailAddress. ```ts function getEmailAddress(emailAddressId: string): Promise ``` ## Parameters * `emailAddressId` * `string` The ID of the email address to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const emailAddressId = 'idn_123' const response = await clerkClient.emailAddresses.getEmailAddress(emailAddressId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/email_addresses/{email_address_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/email-addresses/get/email_addresses/\{email_address_id}){{ target: '_blank' }} for more information. --- title: "`createInvitationBulk()`" description: Use Clerk's JS Backend SDK to create multiple invitations for the given email addresses, and send the invitation emails. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/invitations/create-invitation-bulk lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/invitations/create-invitation-bulk.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/InvitationApi.ts#L69 */} Creates multiple [`Invitation`](/docs/reference/backend/types/backend-invitation)s in bulk for the given email addresses and sends the invitation emails. If an email address has already been invited or already exists in your application, trying to create a new invitation will return an error. To bypass this error and create a new invitation anyways, set `ignoreExisting` to `true`. ```ts function createInvitationBulk(params: CreateBulkParams): Promise ``` ## Parameters * `params` * [`CreateBulkParams[]`](#create-bulk-params) An array of objects, each representing a single invitation. ## `CreateBulkParams` * `emailAddress` * `string` The email address of the user to invite. *** * `redirectUrl?` * `string` The full URL or path where the user is redirected upon visiting the invitation link, where they can accept the invitation. Required if you have implemented a [custom flow for handling application invitations](/docs/guides/development/custom-flows/authentication/application-invitations). *** * `publicMetadata?` * UserPublicMetadata Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API. Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. *** * `notify?` * `boolean` Whether an email invitation should be sent to the given email address. Defaults to `true`. *** * `ignoreExisting?` * `boolean` Whether an invitation should be created if there is already an existing invitation for this email address, or if the email address already exists in the application. Defaults to `false`. *** * `expiresInDays?` * `number` The number of days the invitation will be valid for. By default, the invitation expires after 30 days. *** * `templateSlug?` * `'invitation' | 'waitlist_invitation'` The slug of the email template to use for the invitation email. Defaults to `invitation`. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx // Each object in the array represents a single invitation const params = [ { emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, }, { emailAddress: 'invite2@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, }, ] const response = await clerkClient.invitations.createInvitationBulk(params) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/invitations/bulk`. See the [BAPI reference](/docs/reference/backend-api/tag/invitations/post/invitations/bulk){{ target: '_blank' }} for more information. --- title: "`getInvitationList()`" description: Use Clerk's JS Backend SDK to retrieve a list of non-revoked invitations for your application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/invitations/get-invitation-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/invitations/get-invitation-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/InvitationApi.ts#L34 */} Retrieves a list of non-revoked invitations for your application, sorted by descending creation date. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`Invitation`](/docs/reference/backend/types/backend-invitation) objects, and a `totalCount` property that indicates the total number of invitations in the system. ```ts function getInvitationList( params: GetInvitationListParams, ): Promise> ``` ## `GetInvitationListParams` * `status?` * `accepted | pending | revoked` Filter by invitation status. *** * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. ## Examples ### Basic > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.invitations.getInvitationList() ``` ### Filter by invitation status Retrieves list of invitations that have been revoked. ```tsx // get all revoked invitations const response = await clerkClient.invitations.getInvitationList({ status: 'revoked' }) ``` ### Limit the number of results Retrieves list of invitations that have been revoked that is filtered by the number of results. ```tsx const { data, totalCount } = await clerkClient.invitations.getInvitationList({ status: 'revoked', // returns the first 10 results limit: 10, }) ``` ### Skip results Retrieves list of invitations that have been revoked that is filtered by the number of results to skip. ```tsx const { data, totalCount } = await clerkClient.invitations.getInvitationList({ status: 'revoked', // skips the first 10 results offset: 10, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/invitations`. See the [BAPI reference](/docs/reference/backend-api/tag/invitations/get/invitations){{ target: '_blank' }} for more information. --- title: "`createInvitation()`" description: Use Clerk's JS Backend SDK to create a new invitation for the given email address, and send the invitation email. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/invitations/create-invitation lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/invitations/create-invitation.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/InvitationApi.ts#L42 */} Creates a new [`Invitation`](/docs/reference/backend/types/backend-invitation) for the given email address and sends the invitation email. If an email address has already been invited or already exists in your application, trying to create a new invitation will return an error. To bypass this error and create a new invitation anyways, set `ignoreExisting` to `true`. ```ts function createInvitation(params: CreateParams): Promise ``` ## `CreateParams` * `emailAddress` * `string` The email address of the user to invite. *** * `redirectUrl?` * `string` The full URL or path where the user is redirected upon visiting the invitation link, where they can accept the invitation. Required if you have implemented a [custom flow for handling application invitations](/docs/guides/development/custom-flows/authentication/application-invitations). *** * `publicMetadata?` * UserPublicMetadata Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API. Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. *** * `notify?` * `boolean` Whether an email invitation should be sent to the given email address. Defaults to `true`. *** * `ignoreExisting?` * `boolean` Whether an invitation should be created if there is already an existing invitation for this email address, or if the email address already exists in the application. Defaults to `false`. *** * `expiresInDays?` * `number` The number of days the invitation will be valid for. By default, the invitation expires after 30 days. *** * `templateSlug?` * `'invitation' | 'waitlist_invitation'` The slug of the email template to use for the invitation email. Defaults to `invitation`. ## Usage > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.invitations.createInvitation({ emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, }) ``` ## Example ```ts {{ filename: 'app/api/example/route.ts' }} import { clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function POST() { const client = await clerkClient() const invitation = await client.invitations.createInvitation({ emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, }) return NextResponse.json({ message: 'Invitation created', invitation }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' import { clerkClient } from '@clerk/astro/server' export const POST: APIRoute = async (context) => { await clerkClient(context).invitations.createInvitation({ emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, }) return new Response(JSON.stringify({ success: true }), { status: 200 }) } ``` ```ts {{ filename: 'public.ts' }} import { getAuth, clerkClient } from '@clerk/express' app.post('/createUser', async (req, res) => { await clerkClient.invitations.createInvitation({ emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, password: 'password', }) res.status(200).json({ success: true }) }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' import { json } from 'react-router-dom' export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() const emailAddress = formData.get('emailAddress') const redirectUrl = formData.get('redirectUrl') const publicMetadata = formData.get('publicMetadata') await clerkClient.invitations.createInvitation({ emailAddress: emailAddress, redirectUrl: redirectUrl, publicMetadata: publicMetadata, }) return json({ success: true }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { POST: async () => { await clerkClient().invitations.createInvitation({ emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, }) return json({ success: true }) }, }, }, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/invitations`. See the [BAPI reference](/docs/reference/backend-api/tag/invitations/post/invitations){{ target: '_blank' }} for more information. Here's an example of making a request directly to the endpoint using cURL. Replace the email address with the email address you want to invite. Your Clerk Secret Key is already injected into the code snippet. Replace the email address with the email address you want to invite. Update `YOUR_SECRET_KEY` with your Clerk Secret Key which can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ```bash {{ filename: 'terminal' }} curl https://api.clerk.com/v1/invitations -X POST -d '{"email_address": "email@example.com"}' -H "Authorization:Bearer {{secret}}" -H 'Content-Type:application/json' ``` --- title: "`revokeInvitation()`" description: Use Clerk's JS Backend SDK to revoke an invitation. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/invitations/revoke-invitation lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/invitations/revoke-invitation.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/InvitationApi.ts#L50 */} Revokes an [`Invitation`](/docs/reference/backend/types/backend-invitation). Revoking an invitation makes the invitation email link unusable. However, it doesn't prevent the user from signing up if they follow the sign up flow. Only active (i.e. non-revoked) invitations can be revoked. ```ts function revokeInvitation(invitationId: string): Promise ``` ## Parameters * `invitationId` * `string` The ID of the invitation to revoke. ## Usage > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const invitationId = 'inv_123' const response = await clerkClient.invitations.revokeInvitation(invitationId) ``` ## Example ```ts {{ filename: 'app/api/example/route.ts' }} import { clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function POST() { const client = await clerkClient() const invitation = await client.invitations.revokeInvitation({ invitationId: 'invitation_123', }) return NextResponse.json({ message: 'Invitation revoked' }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' import { clerkClient } from '@clerk/astro/server' export const POST: APIRoute = async (context) => { await clerkClient(context).invitations.revokeInvitation({ invitationId: 'invitation_123', }) return new Response(JSON.stringify({ success: true }), { status: 200 }) } ``` ```ts {{ filename: 'public.ts' }} import { getAuth, clerkClient } from '@clerk/express' app.post('/revokeInvitation', async (req, res) => { await clerkClient.invitations.revokeInvitation({ invitationId: 'invitation_123', }) res.status(200).json({ success: true }) }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' import { json, redirect } from 'react-router-dom' export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() const invitationId = formData.get('invitationId') await clerkClient.invitations.revokeInvitation({ invitationId: invitationId, }) return json({ success: true }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { POST: async () => { await clerkClient().invitations.revokeInvitation({ invitationId: 'invitation_123', }) return json({ success: true }) }, }, }, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/invitations/{invitation_id}/revoke`. See the [BAPI reference](/docs/reference/backend-api/tag/invitations/post/invitations/\{invitation_id}/revoke){{ target: '_blank' }} for more information. Here's an example of making a request directly to the endpoint using cURL. Replace the `` with the ID of the invitation you want to revoke. Your Secret Key is already injected into the code snippet. Replace the `` with the ID of the invitation you want to revoke and replace `YOUR_SECRET_KEY` with your Clerk Secret Key. You can find your Secret Key on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ```bash {{ filename: 'terminal' }} curl https://api.clerk.com/v1/invitations//revoke -X POST -H "Authorization:Bearer {{secret}}" -H 'Content-Type:application/json' ``` --- title: "`createToken()`" description: Use Clerk's JS Backend SDK to create a M2M token. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/m2m-tokens/create-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/m2m-tokens/create-token.mdx --- Creates a new [M2M token](/docs/guides/development/machine-auth/m2m-tokens). Must be authenticated via a Machine Secret Key. ```ts function createToken(params?: CreateM2MTokenParams): Promise ``` ## `CreateM2MTokenParams` * `machineSecretKey?` * `string` Custom machine secret key for authentication. If not provided, the SDK will use the value from the environment variable. *** * `secondsUntilExpiration?` * `number | null` Number of seconds until the token expires. Defaults to `null` (token does not expire). *** * `claims?` * `Record | null` Additional custom claims to include in the token payload. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const m2mToken = await clerkClient.m2m.createToken() console.log(m2mToken) ``` While it is strongly recommended to use environment variables for security, if you need to pass in the machine secret key directly rather than using an environment variable, you can do so by passing it as an argument to the `createToken()` method, as shown in the following example: ```ts const m2mToken = await clerkClient.m2m.createToken({ machineSecretKey: 'ak_xxx', }) console.log(m2mToken) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/m2m_tokens`. See the [BAPI reference](/docs/reference/backend-api/tag/m2m-tokens/post/m2m_tokens){{ target: '_blank' }} for more information. --- title: "`verifyToken()`" description: Use Clerk's JS Backend SDK to verify a M2M token. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/m2m-tokens/verify-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/m2m-tokens/verify-token.mdx --- Verifies an [M2M token](/docs/guides/development/machine-auth/m2m-tokens). Must be authenticated via a Machine Secret Key. ```ts function verifyToken(params: VerifyM2MTokenParams): Promise ``` ## `VerifyM2MTokenParams` * `machineSecretKey?` * `string` Custom machine secret key for authentication. If not provided, the SDK will use the value from the environment variable. *** * `token` * `string` The M2M token to verify. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const response = await clerkClient.m2m.verifyToken({ token }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/m2m_tokens/verify`. See the [BAPI reference](/docs/reference/backend-api/tag/m2m-tokens/post/m2m_tokens/verify){{ target: '_blank' }} for more information. --- title: "`revokeToken()`" description: Use Clerk's JS Backend SDK to revoke a M2M token. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/m2m-tokens/revoke-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/m2m-tokens/revoke-token.mdx --- Revokes an [M2M token](/docs/guides/development/machine-auth/m2m-tokens). This endpoint can be authenticated by either a Machine Secret Key or by a Clerk Secret Key. * When revoking a M2M token with a Machine Secret Key, the token must be managed by the Machine associated with the Machine Secret Key. * When revoking a M2M token with a Clerk Secret Key, any token on the instance can be revoked. ```ts function revokeToken(params: RevokeM2MTokenParams): Promise ``` ## `RevokeM2MTokenParams` * `machineSecretKey?` * `string` Custom machine secret key for authentication. If not provided, the SDK will use the value from the environment variable. *** * `m2mTokenId` * `string` The ID of the M2M token to revoke. *** * `revocationReason?` * `string | null` Optional reason for revocation. Useful for your records. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const response = await clerkClient.m2m.revokeToken({ m2mTokenId }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/m2m_tokens/{m2m_token_id}/revoke`. See the [BAPI reference](/docs/reference/backend-api/tag/m2m-tokens/post/m2m_tokens/%7Bm2m_token_id%7D/revoke){{ target: '_blank' }} for more information. --- title: "`createScope()`" description: Use Clerk's Backend SDK to create a machine scope. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/machines/create-scope lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/machines/create-scope.mdx --- Creates a new machine scope, allowing the specified machine to access another machine. ```ts function createScope(machineId: string, toMachineId: string): Promise ``` ## Parameters * `machineId` * `string` The ID of the machine that will have access to the target machine. *** * `toMachineId` * `string` The ID of the machine that will be accessible by the source machine. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const machineId = 'mch_123' const toMachineId = 'mch_456' const response = await clerkClient.machines.createScope(machineId, toMachineId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/machines/{machine_id}/scopes`. See the [BAPI reference](/docs/reference/backend-api/tag/machines/post/machines/%7Bmachine_id%7D/scopes){{ target: '_blank' }} for more information. --- title: "`create()`" description: Use Clerk's Backend SDK to create a machine. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/machines/create lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/machines/create.mdx --- Creates a new machine. ```ts function create(params: CreateMachineParams): Promise ``` ## `CreateMachineParams` * `name` * `string` The name of the machine. *** * `scopedMachines?` * `string[]` Array of machine IDs that this machine will have access to. *** * `defaultTokenTtl?` * `number` The default time-to-live (TTL) in seconds for tokens created by this machine. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ### Basic machine creation ```ts const response = await clerkClient.machines.create({ name: 'Email Server', }) ``` ### Machine with scoped access ```ts const response = await clerkClient.machines.create({ name: 'API Gateway', scopedMachines: ['mch_123', 'mch_456'], defaultTokenTtl: 3600, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/machines`. See the [BAPI reference](/docs/reference/backend-api/tag/machines/post/machines){{ target: '_blank' }} for more information. --- title: "`deleteScope()`" description: Use Clerk's Backend SDK to delete a machine scope. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/machines/delete-scope lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/machines/delete-scope.mdx --- Deletes a machine scope, removing access between two machines. ```ts function deleteScope(machineId: string, otherMachineId: string): Promise ``` ## Parameters * `machineId` * `string` The ID of the machine that currently has access to the target machine. *** * `otherMachineId` * `string` The ID of the machine that will no longer be accessible by the source machine. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const machineId = 'mch_123' const otherMachineId = 'mch_456' const response = await clerkClient.machines.deleteScope(machineId, otherMachineId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/machines/{machine_id}/scopes/{other_machine_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/machines/delete/machines/%7Bmachine_id%7D/scopes/%7Bother_machine_id%7D){{ target: '_blank' }} for more information. --- title: "`delete()`" description: Use Clerk's Backend SDK to delete a machine. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/machines/delete lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/machines/delete.mdx --- Deletes a machine by its ID. ```ts {{ prettier: false }} function delete(machineId: string): Promise ``` ## Parameters * `machineId` * `string` The ID of the machine to delete. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const machineId = 'mch_123' const response = await clerkClient.machines.delete(machineId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/machines/{machine_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/machines/delete/machines/%7Bmachine_id%7D){{ target: '_blank' }} for more information. --- title: "`get()`" description: Use Clerk's Backend SDK to retrieve a machine. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/machines/get lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/machines/get.mdx --- Retrieves a machine by its ID. ```ts function get(machineId: string): Promise ``` ## Parameters * `machineId` * `string` The ID of the machine to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const machineId = 'mch_123' const response = await clerkClient.machines.get(machineId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/machines/{machine_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/machines/get/machines/%7Bmachine_id%7D){{ target: '_blank' }} for more information. --- title: "`getSecretKey()`" description: Use Clerk's Backend SDK to retrieve a machine secret key. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/machines/get-secret-key lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/machines/get-secret-key.mdx --- Retrieves a machine secret key by its ID. ```ts function getSecretKey(machineId: string): Promise ``` ## Parameters * `machineId` * `string` The ID of the machine for which to retrieve the secret key. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const machineId = 'mch_123' const response = await clerkClient.machines.getSecretKey(machineId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/machines/{machine_id}/secret_key`. See the [BAPI reference](/docs/reference/backend-api/tag/machines/get/machines/%7Bmachine_id%7D/secret_key){{ target: '_blank' }} for more information. --- title: "`list()`" description: Use Clerk's Backend SDK to get a list of machines for your application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/machines/list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/machines/list.mdx --- Retrieves a list of machines for your application. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of Machine objects, and a `totalCount` property that indicates the total number of machines for the application. Results are sorted by descending creation date by default. ```ts function list(params: GetMachineListParams = {}): Promise> ``` ## Parameters * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. *** * `orderBy?` * `'name' | 'created_at'` Return machines in a particular order. Prefix with a `-` to reverse the order. Prefix with a `+` to list in ascending order. Defaults to `'+created_at'`. *** * `query?` * `string` Filters machines with ID or name that match the given query. ## Examples > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ### Basic ```tsx const response = await clerkClient.machines.list() ``` ### Limit the number of results Retrieves list of machines that is filtered by the number of results. ```tsx const { data, totalCount } = await clerkClient.machines.list({ // returns the first 10 results limit: 10, }) ``` ### Skip results Retrieves list of machines that is filtered by the number of results to skip. ```tsx const { data, totalCount } = await clerkClient.machines.list({ // skips the first 10 results offset: 10, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/machines`. See the [BAPI reference](/docs/reference/backend-api/tag/machines/get/machines){{ target: '_blank' }} for more information. --- title: "`rotateSecretKey()`" description: Use Clerk's Backend SDK to rotate a machine's secret key. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/machines/rotate-secret-key lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/machines/rotate-secret-key.mdx --- Rotates the machine secret key for a given machine by its ID. ```ts function rotateSecretKey(params: RotateMachineSecretKeyParams): Promise ``` ## Parameters * `machineId` * `string` The ID of the machine for which to rotate the secret key. *** * `previousTokenTtl` * `number` The time in seconds that the previous secret key will remain valid after rotation. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const machineId = 'mch_123' const response = await clerkClient.machines.rotateSecretKey({ machineId, previousTokenTtl: 3600, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/machines/{machine_id}/secret_key/rotate`. See the [BAPI reference](/docs/reference/backend-api/tag/machines/post/machines/%7Bmachine_id%7D/secret_key/rotate){{ target: '_blank' }} for more information. --- title: "`update()`" description: Use Clerk's Backend SDK to update a machine. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/machines/update lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/machines/update.mdx --- Updates a machine by its ID. ```ts function update(params: UpdateMachineParams): Promise ``` ## `UpdateMachineParams` * `machineId` * `string` The ID of the machine to update. *** * `name?` * `string` The name of the machine. *** * `defaultTokenTtl?` * `number` The default time-to-live (TTL) in seconds for tokens created by this machine. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```ts const machineId = 'mch_123' const response = await clerkClient.machines.update({ machineId, name: 'New Machine Name', defaultTokenTtl: 3600, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/machines/{machine_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/machines/patch/machines/%7Bmachine_id%7D){{ target: '_blank' }} for more information. --- title: "`delete()`" description: Use Clerk's JS Backend SDK to delete an OAuth application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/oauth-applications/delete lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/oauth-applications/delete.mdx --- Deletes an [`OAuthApplication`](/docs/reference/backend/types/backend-oauth-application) by its ID. Returns a DeletedObjectResource object. ```ts {{ prettier: false }} function delete(oauthApplicationId: string): Promise ``` ## Parameters * `oauthApplicationId` * `string` The ID of the OAuth application to delete. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const oauthApplicationId = 'oauthapp_123' const response = await clerkClient.oauthApplications.delete(oauthApplicationId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/oauth_applications/{oauth_application_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/oauth-applications/delete/oauth_applications/%7Boauth_application_id%7D){{ target: '_blank' }} for more information. --- title: "`get()`" description: Use Clerk's JS Backend SDK to retrieve an OAuth application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/oauth-applications/get lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/oauth-applications/get.mdx --- Retrieves an [`OAuthApplication`](/docs/reference/backend/types/backend-oauth-application) by its ID. ```ts function get(oauthApplicationId: string): Promise ``` ## Parameters * `oauthApplicationId` * `string` The ID of the OAuth application to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const oauthApplicationId = 'oauthapp_123' const response = await clerkClient.oauthApplications.get(oauthApplicationId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/oauth_applications/{oauth_application_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/oauth-applications/get/oauth_applications/%7Boauth_application_id%7D){{ target: '_blank' }} for more information. --- title: "`update()`" description: Use Clerk's JS Backend SDK to update an OAuth application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/oauth-applications/update lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/oauth-applications/update.mdx --- Updates an [`OAuthApplication`](/docs/reference/backend/types/backend-oauth-application) by its ID. ```ts function update(params: UpdateOAuthApplicationParams): Promise ``` ## `UpdateOAuthApplicationParams` * `oauthApplicationId` * `string` The ID of the OAuth application to update. *** * `name` * `string` The name of the OAuth application. *** * `redirectUris?` * `string[] | null | undefined` An array of redirect URIs for the OAuth application. *** * `scopes?` * `string[] | null | undefined` Scopes for the OAuth application. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Defaults to `profile email`. Provide the requested scopes as a string, separated by spaces. *** * `consentScreenEnabled?` * `boolean | null | undefined` Specifies whether the consent screen should be displayed in the authentication flow. Cannot be disabled for dynamically registered OAuth applications. Defaults to `true`. *** * `public?` * `boolean | null | undefined` Indicates whether the client is public. If true, the Proof Key of Code Exchange (PKCE) flow can be used. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const oauthApplicationId = 'oauthapp_123' const response = await clerkClient.oauthApplications.update({ oauthApplicationId: oauthApplicationId, name: 'test', redirectUris: [''], scopes: 'profile email public_metadata private_metadata', public: true, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/oauth_applications/{oauth_application_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/oauth-applications/patch/oauth_applications/%7Boauth_application_id%7D){{ target: '_blank' }} for more information. --- title: "`list()`" description: Use Clerk's JS Backend SDK to retrieve a list of OAuth applications for an instance. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/oauth-applications/list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/oauth-applications/list.mdx --- Retrieves a list of OAuth applications for an instance. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`OAuthApplication`](/docs/reference/backend/types/backend-oauth-application) objects, and a `totalCount` property that indicates the total number of OAuth applications for the instance. ```ts function list( params: ClerkPaginationRequest = {}, ): Promise> ``` ## Parameters * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. *** * `orderBy?` * `'name' | 'created_at'` Return OAuth applications in a particular order. Prefix with a `-` to reverse the order. Prefix with a `+` to list in ascending order. Defaults to `'+created_at'`. *** * `nameQuery?` * `string` Filters OAuth applications with names that match the given query, via case-insensitive partial match. ## Examples > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ### Basic ```tsx const response = await clerkClient.oauthApplications.list() ``` ### Limit the number of results Retrieves list of OAuth applications that is filtered by the number of results. ```tsx const { data, totalCount } = await clerkClient.oauthApplications.list({ // returns the first 10 results limit: 10, }) ``` ### Skip results Retrieves list of OAuth applications that is filtered by the number of results to skip. ```tsx const { data, totalCount } = await clerkClient.oauthApplications.list({ // skips the first 10 results offset: 10, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/oauth_applications`. See the [BAPI reference](/docs/reference/backend-api/tag/oauth-applications/get/oauth_applications){{ target: '_blank' }} for more information. --- title: "`rotateSecret()`" description: Use Clerk's JS Backend SDK to rotate the OAuth application's client secret. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/oauth-applications/rotate-secret lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/oauth-applications/rotate-secret.mdx --- Rotates the client secret for a given [`OAuthApplication`](/docs/reference/backend/types/backend-oauth-application) by its ID. When the client secret is rotated, ensure that you update it in your authorized OAuth clients. ```ts function rotateSecret(oauthApplicationId: string): Promise ``` ## Parameters * `oauthApplicationId` * `string` The ID of the OAuth application for which to rotate the client secret. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const oauthApplicationId = 'oauthapp_123' const response = await clerkClient.oauthApplications.rotateSecret(oauthApplicationId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/oauth_applications/{oauth_application_id}/rotate_secret`. See the [BAPI reference](/docs/reference/backend-api/tag/oauth-applications/post/oauth_applications/%7Boauth_application_id%7D/rotate_secret){{ target: '_blank' }} for more information. --- title: "`create()`" description: Use Clerk's JS Backend SDK to create an OAuth application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/oauth-applications/create lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/oauth-applications/create.mdx --- Creates a new [`OAuthApplication`](/docs/reference/backend/types/backend-oauth-application). ```ts function create(params: CreateOAuthApplicationParams): Promise ``` ## `CreateOAuthApplicationParams` * `name` * `string` The name of the OAuth application. *** * `redirectUris?` * `string[] | null` An array of redirect URIs for the OAuth application. *** * `scopes?` * `string[] | null | undefined` Scopes for the OAuth application. Available scopes are `profile`, `email`, `public_metadata`, `private_metadata`. Defaults to `profile email`. Provide the requested scopes as a string, separated by spaces. *** * `consentScreenEnabled?` * `boolean | null | undefined` Specifies whether the consent screen should be displayed in the authentication flow. Cannot be disabled for dynamically registered OAuth applications. Defaults to `true`. *** * `public?` * `boolean | null | undefined` Indicates whether the client is public. If true, the Proof Key of Code Exchange (PKCE) flow can be used. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.oauthApplications.create({ name: 'oauthapp_123', redirect_uris: [''], scopes: 'profile email public_metadata', public: null, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/oauth_applications`. See the [BAPI reference](/docs/reference/backend-api/tag/oauth-applications/post/oauth_applications){{ target: '_blank' }} for more information. --- title: "`createOrganizationInvitationBulk()`" description: Use Clerk's JS Backend SDK to create multiple invitations for new users to join an Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/create-organization-invitation-bulk lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/create-organization-invitation-bulk.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L292-L303 */} Creates multiple [`OrganizationInvitation`](/docs/reference/backend/types/backend-organization-invitation)s in bulk for new users to join an Organization. ```ts function createOrganizationInvitationBulk( organizationId: string, params: CreateBulkOrganizationInvitationParams, ): Promise ``` ## Parameters `createOrganizationInvitationBulk()` accepts the following parameters: * `organizationId` * `string` The Organization ID of the Organization you want to invite users to. *** * `params` * [`CreateBulkOrganizationInvitationParams[]`](#create-bulk-organization-invitation-params) An array of objects, each representing a single invitation. ### `CreateBulkOrganizationInvitationParams` * `inviterUserId` * `string | null` The user ID of the user creating the invitation. *** * `emailAddress` * `string` The email address to send the invitation to. *** * `role` * OrganizationCustomRoleKey The [Role](/docs/guides/organizations/roles-and-permissions) to assign the invited user within the Organization. *** * `redirectUrl?` * `string` The full URL or path where users will land once the Organization invitation has been accepted. *** * `publicMetadata?` * OrganizationInvitationPublicMetadata Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const organizationId = 'org_123' // Each object in the array represents a single invitation const params = [ { inviterUserId: 'user_1', emailAddress: 'testclerk1@clerk.dev', role: 'org:admin', }, { inviterUserId: 'user_2', emailAddress: 'testclerk2@clerk.dev', role: 'org:member', }, ] const response = await clerkClient.organizations.createOrganizationInvitationBulk( organizationId, params, ) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/organizations/{organization_id}/invitations/bulk`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-invitations/post/organizations/\{organization_id}/invitations/bulk){{ target: '_blank' }} for more information. --- title: "`createOrganizationInvitation()`" description: Use Clerk's JS Backend SDK to create an invitation for new users to join an Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/create-organization-invitation lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/create-organization-invitation.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L248 */} Creates an [`OrganizationInvitation`](/docs/reference/backend/types/backend-organization-invitation) for new users to join an Organization. ```ts function createOrganizationInvitation( params: CreateOrganizationInvitationParams, ): Promise ``` ## `CreateOrganizationInvitationParams` * `organizationId` * `string` The Organization ID of the Organization a user is being invited to. *** * `inviterUserId` * `string | null` The user ID of the user creating the invitation. *** * `emailAddress` * `string` The email address to send the invitation to. *** * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) to assign the invited user within the Organization. *** * `redirectUrl?` * `string` The full URL or path where users will land once the Organization invitation has been accepted. *** * `publicMetadata?` * OrganizationInvitationPublicMetadata Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const organizationId = 'org_123' const inviterUserId = 'user_123' const emailAddress = 'testclerk123@clerk.dev' const role = 'org:member' const response = await clerkClient.organizations.createOrganizationInvitation({ organizationId, inviterUserId, emailAddress, role, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/organizations/{organization_id}/invitations`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-invitations/post/organizations/\{organization_id}/invitations){{ target: '_blank' }} for more information. --- title: "`deleteOrganizationMembership()`" description: Use Clerk's JS Backend SDK to remove a user from the specified Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/delete-organization-membership lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/delete-organization-membership.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L227 */} Removes a user from the specified Organization. Returns a [`OrganizationMembership`](/docs/reference/backend/types/backend-organization-membership) object. ```ts function deleteOrganizationMembership( params: DeleteOrganizationMembershipParams, ): Promise ``` ## `DeleteOrganizationMembershipParams` * `organizationId` * `string` The ID of the Organization the user will be removed from. *** * `userId` * `string` The ID of the user to be removed from the Organization. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const organizationId = 'org_123' const userId = 'user_123' const response = await clerkClient.organizations.deleteOrganizationMembership({ organizationId, userId, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/organizations/{organization_id}/memberships/{user_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-memberships/delete/organizations/\{organization_id}/memberships/\{user_id}){{ target: '_blank' }} for more information. --- title: "`createOrganization()`" description: Use Clerk's JS Backend SDK to create an Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/create-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/create-organization.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L109 */} Creates an [`Organization`](/docs/reference/backend/types/backend-organization). ```ts function createOrganization(params: CreateParams): Promise ``` ## `CreateParams` * `name` * `string` Name of the Organization. *** * `createdBy` * `string` The user ID for the user creating the Organization. The user will become an administrator for the Organization. *** * `slug?` * `string` Slug of the Organization. *** * `publicMetadata?` * OrganizationPublicMetadata Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API. *** * `privateMetadata?` * OrganizationPrivateMetadata Metadata that is only visible to your [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. *** * `maxAllowedMemberships?` * `number` The maximum number of memberships allowed in the Organization. Setting this value to `0` removes any limit, allowing an unlimited number of memberships. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const name = 'test-org' const createdBy = 'user_123' const response = await clerkClient.organizations.createOrganization({ name, createdBy }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/organizations`. See the [BAPI reference](/docs/reference/backend-api/tag/organizations/post/organizations){{ target: '_blank' }} for more information. --- title: "`createOrganizationMembership()`" description: Use Clerk's JS Backend SDK to create a membership to an Organization for a user directly (circumventing the need for an invitation). sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/create-organization-membership lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/create-organization-membership.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L187 */} Creates a membership to an Organization for a user directly (circumventing the need for an invitation). Returns a [`OrganizationMembership`](/docs/reference/backend/types/backend-organization-membership) object. ```ts function createOrganizationMembership( params: CreateOrganizationMembershipParams, ): Promise ``` ## `CreateOrganizationMembershipParams` * `organizationId` * `string` The ID of the Organization the user is being added to. *** * `userId` * `string` The ID of the user to be added to the Organization. *** * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) to assign the added user within the Organization. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). In the following example, an [`OrganizationMembership`](/docs/reference/backend/types/backend-organization-membership) is created for a user with the Role `org:member`. ```tsx const organizationId = 'org_123' const userId = 'user_123' const role = 'org:member' const response = await clerkClient.organizations.createOrganizationMembership({ organizationId, userId, role, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/organizations/{organization_id}/memberships`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-memberships/post/organizations/\{organization_id}/memberships){{ target: '_blank' }} for more information. --- title: "`deleteOrganizationLogo()`" description: Use Clerk's JS Backend SDK to delete an Organization's logo. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/delete-organization-logo lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/delete-organization-logo.mdx --- Deletes an Organization's logo. ```ts function deleteOrganizationLogo(organizationId: string): Promise ``` ## Parameters * `organizationId` * `string` The ID of the Organization for which the logo will be deleted. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const organizationId = 'org_123' const response = await clerkClient.organizations.deleteOrganizationLogo(organizationId) console.log(response) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/organizations/{organization_id}/logo`. See the [BAPI reference](/docs/reference/backend-api/tag/organizations/delete/organizations/\{organization_id}/logo){{ target: '_blank' }} for more information. --- title: "`deleteOrganization()`" description: Use Clerk's JS Backend SDK to delete an Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/delete-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/delete-organization.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L169 */} Deletes an [`Organization`](/docs/reference/backend/types/backend-organization). Returns a DeletedObjectResource object. ```ts function deleteOrganization(organizationId: string): Promise ``` ## Parameters * `organizationId` * `string` The ID of the Organization to delete. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const organizationId = 'org_123' const response = await clerkClient.organizations.deleteOrganization(organizationId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/organizations/{organization_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/organizations/delete/organizations/\{organization_id}){{ target: '_blank' }} for more information. --- title: "`getOrganizationInvitationList()`" description: Use Clerk's JS Backend SDK to retrieve a list of Organization invitations. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/get-organization-invitation-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/get-organization-invitation-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L237 */} Retrieves a list of Organization invitations. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`OrganizationInvitation`](/docs/reference/backend/types/backend-organization-invitation) objects, and a `totalCount` property that indicates the total number of Organization invitations in the system for the specified Organization. ```ts function getOrganizationInvitationList( params: GetOrganizationInvitationListParams, ): Promise> ``` ## `GetOrganizationInvitationListParams` * `organizationId` * `string` The ID of the Organization to retrieve the list of pending invitations from. *** * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. *** * `status?` * `string[]` The status of the invitation. Possible values: `pending`, `accepted`, `revoked`, `expired`. Defaults to `pending`. ## Examples ### Basic > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const organizationId = 'org_123' const response = await clerkClient.organizations.getOrganizationInvitationList({ organizationId }) ``` ### Filter by invitation status Retrieves Organization invitation list that is filtered by the status of the invitation. ```tsx const organizationId = 'org_123' const { data, totalCount } = await clerkClient.organizations.getOrganizationInvitationList({ organizationId, // returns a list of invitations that have not yet been accepted status: ['pending'], }) ``` ### Limit the number of results Retrieves Organization invitation list that is filtered by the number of results. ```tsx const organizationId = 'org_123' const { data, totalCount } = await clerkClient.organizations.getOrganizationInvitationList({ organizationId, // returns the first 10 results limit: 10, }) ``` ### Skip results Retrieves Organization invitation list that is filtered by the number of results to skip. ```tsx const organizationId = 'org_123' const { data, totalCount } = await clerkClient.organizations.getOrganizationInvitationList({ organizationId, // skips the first 10 results offset: 10, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/organizations/{organization_id}/invitations`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-invitations/get/organizations/\{organization_id}/invitations){{ target: '_blank' }} for more information. --- title: "`getOrganizationList()`" description: Use Clerk's JS Backend SDK to retrieve a list of Organizations. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/get-organization-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/get-organization-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L101 */} Retrieves a list of Organizations. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`Organization`](/docs/reference/backend/types/backend-organization) objects, and a `totalCount` property that indicates the total number of Organizations in the system. ```ts function getOrganizationList( params: GetOrganizationListParams, ): Promise> ``` ## `GetOrganizationListParams` * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. *** * `includeMembersCount?` * `boolean` Whether the member counts of each Organization should be included in the response or not. *** * `query?` * `string` Filters Organizations with ID, name, or slug that match the given query. Uses exact match for Organization ID and partial match for name and slug. *** * `orderBy?` * `'name' | 'created_at' | 'members_count'` Return Organizations in a particular order. Prefix with a `-` to reverse the order. Prefix with a `+` to list in ascending order. Defaults to `'-created_at'`. ## Examples ### Basic > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.organizations.getOrganizationList() ``` ### Limit the number of results Retrieves Organization list that is filtered by the number of results. ```tsx const { data, totalCount } = await clerkClient.organizations.getOrganizationList({ // returns the first 10 results limit: 10, }) ``` ### Skip results Retrieves Organization list that is filtered by the number of results to skip. ```tsx const { data, totalCount } = await clerkClient.organizations.getOrganizationList({ // skips the first 10 results offset: 10, }) ``` ### Filter by query Retrieves list of Organizations that match the query. ```tsx // returns organizations that have 'test' in their name const { data, totalCount } = await clerkClient.organizations.getOrganizationList({ query: 'test' }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/organizations`. See the [BAPI reference](/docs/reference/backend-api/tag/organizations/get/organizations){{ target: '_blank' }} for more information. --- title: "`getOrganizationMembershipList()`" description: Use Clerk's JS Backend SDK to retrieve a list of memberships for an Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/get-organization-membership-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/get-organization-membership-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L176 */} Retrieves a list of memberships for an Organization. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`OrganizationMembership`](/docs/reference/backend/types/backend-organization-membership) objects, and a `totalCount` property that indicates the total number of organization memberships in the system for the specified Organization. ```ts function getOrganizationMembershipList( params: GetOrganizationMembershipListParams, ): Promise> ``` ## `GetOrganizationMembershipListParams` * `createdAtAfter?` * `number` Filters memberships who have been created after the given date (with millisecond precision). For example, use `1730160000000` to retrieve memberships who have been created after 2024-10-29. *** * `createdAtBefore?` * `number` Filters memberships who have been created before the given date (with millisecond precision). For example, use `1730160000000` to retrieve memberships who have been created before 2024-10-29. *** * `emailAddress?` * `string[]` Filters memberships for the email addresses specified. Accepts up to 100 email addresses. Any email addresses not found are ignored. *** * `emailAddressQuery?` * `string` Filters memberships with emails that match the given query, via case-insensitive partial match. For example, `email_address_query=ello` will match a membership with the email `HELLO@example.com`. *** * `lastActiveAtAfter?` * `number` Filters memberships whose last session activity was after the given date (with millisecond precision). For example, use `1700690400000` to retrieve memberships whose last session activity was after 2023-11-23. *** * `lastActiveAtBefore?` * `number` Filters memberships whose last session activity was before the given date (with millisecond precision). For example, use `1700690400000` to retrieve memberships whose last session activity was before 2023-11-23. *** * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `nameQuery?` * `string` Filters memberships with names that match the given query, via case-insensitive partial match. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. *** * `orderBy?` * `'phone_number' | 'email_address' | 'created_at' | 'first_name' | 'last_name' | 'username'` Return memberships in a particular order. Prefix with a `-` to reverse the order. Prefix with a `+` to list in ascending order. Defaults to `'-created_at'`. *** * `organizationId` * `string` The ID of the Organization to retrieve the list of memberships from. *** * `phoneNumber?` * `string[]` Filters memberships for the phone numbers specified. Accepts up to 100 phone numbers. Any phone numbers not found are ignored. *** * `phoneNumberQuery?` * `string` Filters memberships with phone numbers that match the given query, via case-insensitive partial match. For example, `phone_number_query=555` will match a membership with the phone number `+1555xxxxxxx`. *** * `query?` * `string` Filters memberships that match the given query. For possible matches, we check the email addresses, phone numbers, usernames, Web3 wallet addresses, user IDs, first and last names. The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. *** * `role?` * `string[]` Filters memberships for the Roles specified. Accepts up to 100 Roles. Any Roles not found are ignored. *** * `userId?` * `string[]` Filters memberships for the user IDs specified. For each user ID, the `+` and `-` can be prepended to the ID, which denote whether the respective user ID should be included or excluded from the result set. Accepts up to 100 user IDs. Any user IDs not found are ignored. *** * `username?` * `string[]` Filters memberships for the usernames specified. Accepts up to 100 usernames. Any usernames not found are ignored. *** * `usernameQuery?` * `string` Filters memberships with usernames that match the given query, via case-insensitive partial match. For example, `username_query=CoolUser` will match a membership with the username `SomeCoolUser`. *** * `web3Wallet?` * `string[]` Filters memberships for the Web3 wallet addresses specified. Accepts up to 100 Web3 wallet addresses. Any Web3 wallet addresses not found are ignored. ## Examples ### Basic > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const organizationId = 'org_2ZUtbk2yvnFGItdeze1ivCh3uqh' const response = await clerkClient.organizations.getOrganizationMembershipList({ organizationId }) ``` ### `getOrganizationMembershipList({ organizationId, limit })` Retrieves Organization membership list that is filtered by the number of results. ```tsx const organizationId = 'org_123' const { data, totalCount } = await clerkClient.organizations.getOrganizationMembershipList({ organizationId, // returns the first 10 memberships limit: 10, }) ``` ### `getOrganizationMembershipList({ organizationId, offset })` Retrieves Organization membership list that is filtered by the number of results to skip. ```tsx const organizationId = 'org_123' const { data, totalCount } = await clerkClient.organizations.getOrganizationMembershipList({ organizationId, // skips the first 10 memberships offset: 10, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/organizations/{organization_id}/memberships`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-memberships/get/organizations/\{organization_id}/memberships){{ target: '_blank' }} for more information. --- title: "`getOrganizationInvitation()`" description: Use Clerk's JS Backend SDK to retrieve an Organization invitation. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/get-organization-invitation lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/get-organization-invitation.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L259 */} Retrieves an [`OrganizationInvitation`](/docs/reference/backend/types/backend-organization-invitation). ```ts function getOrganizationInvitation( params: GetOrganizationInvitationParams, ): Promise ``` ## `GetOrganizationInvitationParams` * `organizationId` * `string` The ID of the Organization that the invitation is for. *** * `invitationId` * `string` The ID of the invitation to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const organizationId = 'org_123' const invitationId = 'orginv_123' const response = await clerkClient.organizations.getOrganizationInvitation({ organizationId, invitationId, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/organizations/{organization_id}/invitations/{invitation_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-invitations/get/organizations/\{organization_id}/invitations/\{invitation_id}){{ target: '_blank' }} for more information. --- title: "`getOrganization()`" description: Use Clerk's JS Backend SDK to retrieve a single Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/get-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/get-organization.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L117 */} Retrieves a single [`Organization`](/docs/reference/backend/types/backend-organization). ```ts function getOrganization(params: GetOrganizationParams): Promise ``` ## `GetOrganizationParams` * `organizationId | slug` * `string` The ID of the Organization to retrieve, or the slug of the Organization to retrieve. ## Examples > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ### Retrieve by ID ```tsx const organizationId = 'org_123' const response = await clerkClient.organizations.getOrganization({ organizationId }) ``` ### Retrieve by slug Retrieve an Organization by its slug instead of its ID. ```tsx const slug = 'my-organization-slug' const response = await clerkClient.organizations.getOrganization({ slug }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/organizations/{organization_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/organizations/get/organizations/\{organization_id}){{ target: '_blank' }} for more information. --- title: "`revokeOrganizationInvitation()`" description: Use Clerk's JS Backend SDK to revoke an Organization invitation from a user for a specified Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/revoke-organization-invitation lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/revoke-organization-invitation.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L270 */} Revokes an [`OrganizationInvitation`](/docs/reference/backend/types/backend-organization-invitation) from a user for the specified Organization. ```ts function revokeOrganizationInvitation( params: RevokeOrganizationInvitationParams, ): Promise ``` ## `RevokeOrganizationInvitationParams` * `organizationId` * `string` The ID of the Organization the user was invited to. *** * `invitationId` * `string` The ID of the invitation to be revoked. *** * `requestingUserId` * `string` The ID of the user revoking the Organization invitation. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx {{ mark: [22] }} const organizationId = 'org_123' const invitationId = 'orginv_123' const requestingUserId = 'user_123' const response = await clerkClient.organizations.revokeOrganizationInvitation({ organizationId, invitationId, requestingUserId, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/organizations/{organization_id}/invitations/{invitation_id}/revoke`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-invitations/post/organizations/\{organization_id}/invitations/\{invitation_id}/revoke){{ target: '_blank' }} for more information. --- title: "`updateOrganizationLogo()`" description: Use Clerk's JS Backend SDK to update an Organization's logo. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/update-organization-logo lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/update-organization-logo.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L136 */} Updates the Organization's logo. Returns an [`Organization`](/docs/reference/backend/types/backend-organization) object. ```ts function updateOrganizationLogo( organizationId: string, params: UpdateLogoParams, ): Promise ``` ## `UpdateLogoParams` * `file` * `Blob | File` The file to upload as the Organization's logo. *** * `uploaderUserId?` * `string` The ID of the user uploading the logo. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). > \[!WARNING] > Using JS Backend SDK methods can contribute towards rate limiting. To set an Organization's logo, it's recommended to use the frontend organization.setLogo() method instead. ```tsx const organizationId = 'org_123' const uploaderUserId = 'user_123' const fileBits = ['logo-pic-content'] const fileName = 'logo.png' const file = new File(fileBits, fileName, { type: 'image/png' }) const params = { file, uploaderUserId, } const response = await clerkClient.organizations.updateOrganizationLogo(organizationId, params) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PUT/organizations/{organization_id}/logo`. See the [BAPI reference](/docs/reference/backend-api/tag/organizations/put/organizations/\{organization_id}/logo){{ target: '_blank' }} for more information. --- title: "`updateOrganizationMembershipMetadata()`" description: Use Clerk's JS Backend SDK to update the metadata associated with a user's Organization membership. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/update-organization-membership-metadata lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/update-organization-membership-metadata.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L214 */} Update the metadata attributes of an [`OrganizationMembership`](/docs/reference/backend/types/backend-organization-membership) by merging existing values with the provided parameters. Metadata values will be updated via a "deep" merge - "deep" means that any nested JSON objects will be merged as well. You can remove metadata keys at any level by setting their value to `null`. ```ts function updateOrganizationMembershipMetadata( params: UpdateOrganizationMembershipMetadataParams, ): Promise ``` ## `UpdateOrganizationMembershipMetadataParams` * `organizationId` * `string` The ID of the Organization this membership belongs to. *** * `userId` * `string` The ID of the user that this membership belongs to. *** * `publicMetadata?` * OrganizationMembershipPublicMetadata Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API. *** * `privateMetadata?` * OrganizationMembershipPrivateMetadata Metadata that is only visible to your [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx {{ mark: [[8, 10], 18] }} const organizationId = 'org_123' const userId = 'user_123' const response = await clerkClient.organizations.updateOrganizationMembershipMetadata({ organizationId, userId, publicMetadata: { example: 'this value is updated!', }, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/organizations/{organization_id}/memberships/{user_id}/metadata`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-memberships/patch/organizations/\{organization_id}/memberships/\{user_id}/metadata){{ target: '_blank' }} for more information. --- title: "`updateOrganizationMembership()`" description: Use Clerk's JS Backend SDK to update a user's Organization membership. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/update-organization-membership lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/update-organization-membership.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L201 */} Updates a user's [`OrganizationMembership`](/docs/reference/backend/types/backend-organization-membership). Currently, only the role can be updated. ```ts function updateOrganizationMembership( params: UpdateOrganizationMembershipParams, ): Promise ``` ## `UpdateOrganizationMembershipParams` * `organizationId` * `string` The ID of the Organization this membership belongs to. *** * `userId` * `string` The ID of the user that this membership belongs to. *** * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) to assign the user. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx {{ mark: [5, 17] }} const organizationId = 'org_123' const userId = 'user_123' const role = 'org:admin' const response = await clerkClient.organizations.updateOrganizationMembership({ organizationId, userId, role, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/organizations/{organization_id}/memberships/{user_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/organization-memberships/patch/organizations/\{organization_id}/memberships/\{user_id}){{ target: '_blank' }} for more information. --- title: "`updateOrganizationMetadata()`" description: Use Clerk's JS Backend SDK to update the metadata associated with a given Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/update-organization-metadata lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/update-organization-metadata.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/OrganizationApi.ts#L159 */} Updates the metadata attributes of an [`Organization`](/docs/reference/backend/types/backend-organization) by merging existing values with the provided parameters. Metadata values will be updated via a "deep" merge - "deep" meaning that any nested JSON objects will be merged as well. You can remove metadata keys at any level by setting their value to `null`. ```ts function updateOrganizationMetadata( organizationId: string, params: UpdateOrganizationMetadataParams, ): Promise ``` ## `UpdateOrganizationMetadataParams` * `organizationId` * `string` The ID of the Organization to update. *** * `publicMetadata?` * OrganizationPublicMetadata Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API . *** * `privateMetadata?` * OrganizationPrivateMetadata Metadata that is only visible to your [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx {{ mark: [[4, 6], 20] }} const organizationId = 'org_123' const response = await clerkClient.organizations.updateOrganizationMetadata(organizationId, { publicMetadata: { example: 'metadata', }, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/organizations/{organization_id}/metadata`. See the [BAPI reference](/docs/reference/backend-api/tag/organizations/patch/organizations/\{organization_id}/metadata){{ target: '_blank' }} for more information. --- title: "`updateOrganization()`" description: Use Clerk's JS Backend SDK to update an Organization's name. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/organization/update-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/organization/update-organization.mdx --- Updates an [`Organization`](/docs/reference/backend/types/backend-organization). ```ts function updateOrganization(params: UpdateOrganizationParams): Promise ``` ## `UpdateOrganizationParams` * `organizationId` * `string` The Organization ID of the Organization being updated. *** * `name?` * `string` The updated name of the Organization. *** * `slug?` * `string` The updated slug of the Organization. *** * `publicMetadata?` * OrganizationPublicMetadata Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API. Updating this property will override the existing metadata. To merge metadata, use [`updateOrganizationMetadata()`](/docs/reference/backend/organization/update-organization-metadata). *** * `privateMetadata?` * OrganizationPrivateMetadata Metadata that is only visible to your [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. Updating this property will override the existing metadata. To merge metadata, use [`updateOrganizationMetadata()`](/docs/reference/backend/organization/update-organization-metadata). *** * `maxAllowedMemberships?` * `number` The maximum number of memberships allowed in the Organization. Setting this value to `0` removes any limit, allowing an unlimited number of memberships. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx {{ mark: [3, 11] }} const organizationId = 'org_123' const name = 'Test Updated' const response = await clerkClient.organizations.updateOrganization(organizationId, { name }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/organizations/{organization_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/organizations/patch/organizations/\{organization_id}){{ target: '_blank' }} for more information. --- title: "`createPhoneNumber()`" description: Use Clerk's JS Backend SDK to create a phone number for the specified user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/phone-numbers/create-phone-number lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/phone-numbers/create-phone-number.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/PhoneNumberApi.ts#L29 */} Creates a PhoneNumber for the specified user. ```ts function createPhoneNumber(params: CreatePhoneNumberParams): Promise ``` ## `CreatePhoneNumberParams` * `userId` * `string` The ID of the user to create the phone number for. *** * `phoneNumber` * `string` The phone number to assign to the specified user. Must adhere to the [E.164 format](https://en.wikipedia.org/wiki/E.164) standard for phone number format. *** * `primary?` * `boolean` Whether or not to set the phone number as the user's primary phone number. Defaults to `false`, unless it is the first phone number. *** * `verified?` * `boolean` Whether or not the phone number is verified. *** * `reservedForSecondFactor` * `boolean` Whether or not the phone number is reserved for [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication). The phone number must also be verified. If there are no other reserved second factors, the phone number will be set as the default second factor. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.phoneNumbers.createPhoneNumber({ userId: 'user_123', phoneNumber: '15551234567', primary: true, verified: true, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/phone_numbers`. See the [BAPI reference](/docs/reference/backend-api/tag/phone-numbers/post/phone_numbers){{ target: '_blank' }} for more information. --- title: "`updatePhoneNumber()`" description: Use Clerk's JS Backend SDK to update a phone number. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/phone-numbers/update-phone-number lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/phone-numbers/update-phone-number.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/PhoneNumberApi.ts#L37 */} Updates a PhoneNumber. ```ts function updatePhoneNumber( phoneNumberId: string, params: UpdatePhoneNumberParams, ): Promise ``` ## `UpdatePhoneNumberParams` * `primary?` * `boolean` Whether or not to set the phone number as the user's primary phone number. *** * `verified?` * `boolean` Whether or not the phone number is verified. *** * `reservedForSecondFactor` * `boolean` Whether or not the phone number is reserved for [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication). The phone number must also be verified. If there are no other reserved second factors, the phone number will be set as the default second factor. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx {{ mark: [3, [14, 15]] }} const phoneNumberId = 'idn_123' const params = { verified: false } const response = await clerkClient.phoneNumbers.updatePhoneNumber(phoneNumberId, params) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/phone_numbers/{phone_number_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/phone-numbers/patch/phone_numbers/\{phone_number_id}){{ target: '_blank' }} for more information. --- title: "`deletePhoneNumber()`" description: Use Clerk's JS Backend SDK to delete a phone number. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/phone-numbers/delete-phone-number lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/phone-numbers/delete-phone-number.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/PhoneNumberApi.ts#L47 */} Deletes a PhoneNumber. ```ts function deletePhoneNumber(phoneNumberId: string): Promise ``` ## Parameters * `phoneNumberId` * `string` The ID of the phone number to delete. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const phoneNumberId = 'idn_123' const response = await clerkClient.phoneNumbers.deletePhoneNumber(phoneNumberId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/phone_numbers/{phone_number_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/phone-numbers/delete/phone_numbers/\{phone_number_id}){{ target: '_blank' }} for more information. --- title: "`getPhoneNumber()`" description: Use Clerk's JS Backend SDK to retrieve a single phone number by its ID. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/phone-numbers/get-phone-number lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/phone-numbers/get-phone-number.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/PhoneNumberApi.ts#L20 */} Retrieves a single PhoneNumber. ```ts function getPhoneNumber(phoneNumberId: string): Promise ``` ## Parameters * `phoneNumberId` * `string` The ID of the phone number to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const phoneNumberId = 'idn_123' const response = await clerkClient.phoneNumbers.getPhoneNumber(phoneNumberId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/phone_numbers/{phone_number_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/phone-numbers/get/phone_numbers/\{phone_number_id}){{ target: '_blank' }} for more information. --- title: "`getRedirectUrlList()`" description: Use Clerk's JS Backend SDK to retrieve a list of white-listed redirect URLs. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/redirect-urls/get-redirect-url-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/redirect-urls/get-redirect-url-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/RedirectUrlApi.ts#L13 */} Retrieves a list of all white-listed redirect URLs. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`RedirectUrl`](/docs/reference/backend/types/backend-redirect-url) objects, and a `totalCount` property that indicates the total number of redirect URLs for the application. ```tsx function getRedirectUrlList(): () => Promise> ``` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.redirectUrls.getRedirectUrlList() ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/redirect_urls/{id}`. See the [BAPI reference](/docs/reference/backend-api/tag/redirect-urls/get/redirect_urls){{ target: '_blank' }} for more information. --- title: "`deleteRedirectUrl()`" description: Use Clerk's JS Backend SDK to delete a redirect URL. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/redirect-urls/delete-redirect-url lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/redirect-urls/delete-redirect-url.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/RedirectUrlApi.ts#L37 */} Deletes a [`RedirectUrl`](/docs/reference/backend/types/backend-redirect-url). ```ts function deleteRedirectUrl(redirectUrlId: string): Promise ``` ## Parameters * `redirectUrlId` * `string` The ID of the redirect URL to delete. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const redirectUrlId = 'ru_123' const response = await clerkClient.redirectUrls.deleteRedirectUrl(redirectUrlId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/redirect_urls/{id}`. See the [BAPI reference](/docs/reference/backend-api/tag/redirect-urls/delete/redirect_urls/\{id}){{ target: '_blank' }} for more information. --- title: "`createRedirectUrl()`" description: Use Clerk's JS Backend SDK to create a redirect URL. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/redirect-urls/create-redirect-url lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/redirect-urls/create-redirect-url.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/RedirectUrlApi.ts#L29 */} Creates a [`RedirectUrl`](/docs/reference/backend/types/backend-redirect-url). ```ts function createRedirectUrl(params: CreateRedirectUrlParams): Promise ``` ## `CreateRedirectUrlParams` * `url` * `string` The full url value prefixed with `https://` or a custom scheme. For example, `https://my-app.com/oauth-callback` or `my-app://oauth-callback` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.redirectUrls.createRedirectUrl({ url: 'https://example.com', }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/redirect_urls`. See the [BAPI reference](/docs/reference/backend-api/tag/redirect-urls/post/redirect_urls){{ target: '_blank' }} for more information. --- title: "`getRedirectUrl()`" description: Use Clerk's JS Backend SDK to retrieve a single redirect URL by its ID. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/redirect-urls/get-redirect-url lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/redirect-urls/get-redirect-url.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/RedirectUrlApi.ts#L21 */} Retrieves a single [`RedirectUrl`](/docs/reference/backend/types/backend-redirect-url). ```ts function getRedirectUrl(redirectUrlId: string): Promise ``` ## Parameters * `redirectUrlId` * `string` The ID of the redirect URL to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const redirectUrlId = 'ru_123' const response = await clerkClient.redirectUrls.getRedirectUrl(redirectUrlId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/redirect_urls/{id}`. See the [BAPI reference](/docs/reference/backend-api/tag/redirect-urls/get/redirect_urls/\{id}){{ target: '_blank' }} for more information. --- title: "`getSamlConnectionList()`" description: Use Clerk's JS Backend SDK to retrieve the list of SAML connections for an instance. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/saml-connections/get-saml-connection-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/saml-connections/get-saml-connection-list.mdx --- Retrieves the list of SAML connections for an instance. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`SamlConnection`](/docs/reference/backend/types/backend-saml-connection) objects, and a `totalCount` property that indicates the total number of SAML connections for the instance. ```ts function getSamlConnectionList(params: SamlConnectionListParams = {}): Promise ``` ## `SamlConnectionListParams` * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Default: `10` *** * `offset?` * `number` The number of results to skip. Default: `0` ## Examples ### Basic > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.samlConnections.getSamlConnectionList() ``` ### Limit the number of results Retrieves Organization list that is filtered by the number of results. ```tsx const { data, totalCount } = await clerkClient.samlConnections.getSamlConnectionList({ // returns the first 10 results limit: 10, }) ``` ### Skip results Retrieves Organization list that is filtered by the number of results to skip. ```tsx const { data, totalCount } = await clerkClient.samlConnections.getSamlConnectionList({ // skips the first 10 results offset: 10, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/saml_connections`. See the [BAPI reference](/docs/reference/backend-api/tag/saml-connections/get/saml_connections){{ target: '_blank' }} for more information. --- title: "`getSamlConnection()`" description: Use Clerk's JS Backend SDK to retrieve a SAML connection. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/saml-connections/get-saml-connection lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/saml-connections/get-saml-connection.mdx --- Retrieves a [`SamlConnection`](/docs/reference/backend/types/backend-saml-connection) by its ID. ```ts function getSamlConnection(samlConnectionId: string): Promise ``` ## `GetOrganizationParams` * `samlConnectionId` * `string` The ID of the SAML connection to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const samlConnectionId = 'samlc_123' const response = await clerkClient.samlConnections.getSamlConnection(samlConnectionId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/saml_connections/{saml_connection_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/saml-connections/get/saml_connections/\{saml_connection_id}){{ target: '_blank' }} for more information. --- title: "`deleteSamlConnection()`" description: Use Clerk's JS Backend SDK to delete a SAML connection. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/saml-connections/delete-saml-connection lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/saml-connections/delete-saml-connection.mdx --- Deletes a [`SamlConnection`](/docs/reference/backend/types/backend-saml-connection) by its ID. Returns a DeletedObjectResource object. ```ts function deleteSamlConnection(samlConnectionId: string): Promise ``` ## Parameters * `samlConnectionId` * `string` The ID of the SAML connection to delete. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const samlConnectionId = 'samlc_123' const response = await clerkClient.samlConnections.deleteSamlConnection(samlConnectionId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/saml_connections/{saml_connection_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/saml-connections/delete/saml_connections/\{saml_connection_id}){{ target: '_blank' }} for more information. --- title: "`updateSamlConnection()`" description: Use Clerk's JS Backend SDK to update a SAML connection. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/saml-connections/update-saml-connection lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/saml-connections/update-saml-connection.mdx --- Updates a [`SamlConnection`](/docs/reference/backend/types/backend-saml-connection) by its ID. ```ts function updateSamlConnection( samlConnectionId: string, params: UpdateSamlConnectionParams = {}, ): Promise ``` ## `UpdateSamlConnectionParams` * `name?` * `string` The name to use as a label for this SAML Connection. *** * `provider?` * `'saml_custom' | 'saml_okta' | 'saml_google' | 'saml_microsoft'` The IdP provider of the connection. *** * `domain?` * `string` The domain of your Organization. Sign in flows using an email with this domain will use this SAML Connection. For example: `'clerk.dev'` *** * `OId?` * `string` The ID of the Organization to which users of this SAML Connection will be added *** * `idpEntityId?` * `string` The Entity ID as provided by the IdP. *** * `idpSsoUrl?` * `string` The Single-Sign On URL as provided by the IdP. *** * `idpCertificate?` * `string` The X.509 certificate as provided by the IdP. *** * `idpMetadataUrl?` * `string` The URL which serves the IdP metadata. If present, it takes priority over the corresponding individual properties. *** * `idpMetadata?` * `string` The XML content of the IdP metadata file. If present, it takes priority over the corresponding individual properties. *** * `attributeMapping?` * `{ emailAddress?: string, firstName?: string, lastName?: string, userId?: string }` The attribute mapping for the SAML connection. *** * `active?` * `boolean` Indicates whether the connection is active or not. *** * `syncUserAttributes?` * `boolean` Indicates whether the connection syncs user attributes between the Service Provider (SP) and Identity Provider (IdP) or not. *** * `allowSubdomains?` * `boolean` Indicates whether users with an email address subdomain are allowed to use this connection in order to authenticate or not. *** * `allowIdpInitiated?` * `boolean` Indicates whether the connection allows Identity Provider (IdP) initiated flows or not. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const samlConnectionId = 'samlc_123' const response = await clerkClient.samlConnections.updateSamlConnection(samlConnectionId, { name: 'Updated SAML Connection', }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/saml_connections/{saml_connection_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/saml-connections/patch/saml_connections/\{saml_connection_id}){{ target: '_blank' }} for more information. --- title: "`createSamlConnection()`" description: Use Clerk's JS Backend SDK to create a SAML connection. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/saml-connections/create-saml-connection lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/saml-connections/create-saml-connection.mdx --- Creates a new [`SamlConnection`](/docs/reference/backend/types/backend-saml-connection). ```ts function createSamlConnection(params: CreateSamlConnectionParams): Promise ``` ## `CreateSamlConnectionParams` * `name` * `string` The name to use as a label for this SAML Connection. *** * `provider` * `'saml_custom' | 'saml_okta' | 'saml_google' | 'saml_microsoft'` The Identity Provider (IdP) provider of the connection. *** * `domain` * `string` The domain of your Organization. Sign in flows using an email with this domain will use this SAML Connection. For example: `'clerk.dev'` *** * `organizationId?` * `string` The ID of the Organization to which users of this SAML Connection will be added *** * `idpEntityId?` * `string` The Entity ID as provided by the Identity Provider (IdP). *** * `idpSsoUrl?` * `string` The Single-Sign On URL as provided by the Identity Provider (IdP). *** * `idpCertificate?` * `string` The X.509 certificate as provided by the Identity Provider (IdP). *** * `idpMetadataUrl?` * `string` The URL which serves the Identity Provider (IdP) metadata. If present, it takes priority over the corresponding individual properties. *** * `idpMetadata?` * `string` The XML content of the Identity Provider (IdP) metadata file. If present, it takes priority over the corresponding individual properties. *** * `attributeMapping?` * `{ emailAddress?: string, firstName?: string, lastName?: string, userId?: string }` The attribute mapping for the SAML connection. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.samlConnections.createSamlConnection({ name: 'test-okta', provider: 'saml_okta', domain: 'clerk.dev', idpMetadataUrl: 'https://trial-000000.okta.com/app/exk...', attributeMapping: { emailAddress: 'user.email', firstName: 'user.firstName', lastName: 'user.lastName', }, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/saml_connections`. See the [BAPI reference](/docs/reference/backend-api/tag/saml-connections/post/saml_connections){{ target: '_blank' }} for more information. --- title: "`getSessionList()`" description: Use Clerk's JS Backend SDK to retrieve a list of sessions. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/sessions/get-session-list lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/sessions/get-session-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/SessionApi.ts/#L18 */} Retrieves a list of sessions. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`Session`](/docs/reference/backend/types/backend-session) objects, and a `totalCount` property that indicates the total number of sessions for the specified user. ```ts function getSessionList( queryParams: SessionListParams, ): Promise> ``` ## `SessionListParams` `getSessionList()` requires either `clientId` or `userId` to be provided. * `clientId?` * `string` The client ID to retrieve the list of sessions for. *** * `userId?` * `string` The user ID to retrieve the list of sessions for. *** * `status?` * [`SessionStatus`](#session-status) The status of the session. *** * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. ### `SessionStatus` ```tsx type SessionStatus = | 'abandoned' | 'active' | 'pending' | 'ended' | 'expired' | 'removed' | 'replaced' | 'revoked' ``` | Value | Description | | - | - | | `abandoned` | The session was abandoned client-side. | | `active` | The session is valid and all activity is allowed. | | `pending` | The user has signed in but hasn't completed [session tasks](/docs/guides/configure/session-tasks). | | `ended` | The user signed out of the session, but the `Session` remains in the `Client` object. | | `expired` | The period of allowed activity for this session has passed. | | `removed` | The user signed out of the session and the `Session` was removed from the `Client` object. | | `replaced` | The session has been replaced by another one, but the `Session` remains in the `Client` object. | | `revoked` | The application ended the session and the `Session` was removed from the `Client` object. | ## Examples > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). Retrieve a list of sessions for a specific `userId`: ```tsx const userId = 'user_123' const response = await clerkClient.sessions.getSessionList({ userId }) ``` ### Filter by session status In this example, a list of sessions with a `status` of `'expired'` is retrieved. You can see that the returned [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) includes `data`, which is an array of [`Session`](/docs/reference/backend/types/backend-session) objects, and `totalCount`, which indicates the total number of sessions for the specified user. ```tsx {{ mark: [3, 15] }} const userId = 'user_123' const status = 'expired' const response = await clerkClient.sessions.getSessionList({ userId, status }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/sessions`. See the [BAPI reference](/docs/reference/backend-api/tag/Sessions){{ target: '_blank' }} for more information. --- title: "`getToken()`" description: Use Clerk's JS Backend SDK to retrieve a token for a JWT template that is defined in the Clerk Dashboard. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/sessions/get-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/sessions/get-token.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/SessionApi.ts/#L51 */} Retrieves a token for a JWT Template that is defined on the [**JWT templates**](https://dashboard.clerk.com/~/jwt-templates) page in the Clerk Dashboard. ```ts function getToken(sessionId: string, template: string): Promise ``` ## Parameters * `sessionId` * `string` The ID of the session to retrieve a token for. *** * `template` * `string` The name of the JWT template from the [Clerk Dashboard](https://dashboard.clerk.com/~/jwt-templates) to generate a new token from. For example: 'firebase', 'grafbase', or your custom template's name. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```js const sessionId = 'sess_123' const template = 'test' const response = await clerkClient.sessions.getToken(sessionId, template) ``` ## Examples with frameworks The following examples demonstrate how to use `getToken()` with different frameworks. Each example performs the following steps: 1. Gets the current session ID using framework-specific auth helpers. 2. Checks if there's an active session. 3. Uses the JS Backend SDK's `getToken()` method to generate a token from a template. 4. Returns the token in the response. The token resembles the following: ``` { jwt: 'eyJhbG...' } ``` > \[!NOTE] > For these examples to work, you must have a JWT template named "test" in the [Clerk Dashboard](https://dashboard.clerk.com/~/jwt-templates) before running the code. ```js {{ filename: 'app/api/get-token-example/route.ts' }} import { auth, clerkClient } from '@clerk/nextjs/server' export async function GET() { const { sessionId } = await auth() if (!sessionId) { return Response.json({ message: 'Unauthorized' }, { status: 401 }) } const template = 'test' const client = await clerkClient() const token = await client.sessions.getToken(sessionId, template) return Response.json({ token }) } ``` ```ts {{ filename: 'pages/api/getToken.ts' }} import { clerkClient, getAuth } from '@clerk/nextjs/server' import type { NextApiRequest, NextApiResponse } from 'next' export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { sessionId } = getAuth(req) if (!sessionId) { return res.status(401).json({ error: 'Unauthorized' }) } const template = 'test' const client = await clerkClient() const token = await client.sessions.getToken(sessionId, template) return res.json({ token }) } ``` ```js {{ filename: 'getToken.ts' }} import { clerkClient } from '@clerk/express' app.get('/api/get-token', async (req, res) => { const sessionId = req.auth.sessionId if (!sessionId) { res.status(401).json({ error: 'Unauthorized' }) return } const template = 'test' const token = await clerkClient.sessions.getToken(sessionId, template) res.json({ token }) }) ``` ```ts {{ filename: 'app/routes/get-token.ts' }} import { createClerkClient } from '@clerk/remix/api.server' import { getAuth } from '@clerk/remix/ssr.server' import { ActionFunction, json } from '@remix-run/node' export const action: ActionFunction = async (req) => { const { sessionId } = await getAuth(req) const template = 'test' const token = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY, }).sessions.getToken(sessionId, template) return json({ token }) } ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/sessions/{session_id}/tokens/{template_name}`. See the [BAPI reference](/docs/reference/backend-api/tag/sessions/post/sessions/\{session_id}/tokens/\{template_name}){{ target: '_blank' }} for more information. --- title: "`getSession()`" description: Use Clerk's JS Backend SDK to retrieve a single session by its ID. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/sessions/get-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/sessions/get-session.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/SessionApi.ts/#L26 */} Retrieves a single [`Session`](/docs/reference/backend/types/backend-session). ```ts function getSession(sessionId: string): Promise ``` ## Parameters * `sessionId` * `string` The ID of the session to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const sessionId = 'sess_123' const response = await clerkClient.sessions.getSession(sessionId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/sessions/{session_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/sessions/get/sessions/\{session_id}){{ target: '_blank' }} for more information. --- title: "`verifySession()` (deprecated)" description: Use Clerk's JS Backend SDK to to verify whether a session with a given ID corresponds to the provided session token. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/sessions/verify-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/sessions/verify-session.mdx --- > \[!CAUTION] > This method is now deprecated. Refer to the [Manual JWT Verification](/docs/guides/sessions/manual-jwt-verification) guide for the recommended way to verify sessions/tokens. Verifies whether a session with a given ID corresponds to the provided session token. Throws an error if the provided ID is invalid. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const sessionId = 'my-session-id' const token = 'my-session-token' const session = await clerkClient.sessions.verifySession(sessionId, token) ``` ## Required parameters * `sessionId` * `string` The ID of the session to verify. *** * `token` * `string` The token of the session to verify with. --- title: "`revokeSession()`" description: Use Clerk's JS Backend SDK to revoke a session given its ID. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/sessions/revoke-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/sessions/revoke-session.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/SessionApi.ts/#L34 */} Revokes a [`Session`](/docs/reference/backend/types/backend-session). User will be signed out from the particular client the referred to. ```ts function revokeSession(sessionId: string): Promise ``` ## Parameters * `sessionId` * `string` The ID of the session to revoke. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const sessionId = 'sess_123' const response = await clerkClient.sessions.revokeSession(sessionId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/sessions/{session_id}/revoke`. See the [BAPI reference](/docs/reference/backend-api/tag/sessions/post/sessions/\{session_id}/revoke){{ target: '_blank' }} for more information. --- title: "`createTestingToken()`" description: Use Clerk's JS Backend SDK to create a testing token for the instance. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/testing-tokens/create-testing-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/testing-tokens/create-testing-token.mdx --- Creates a [Testing Token](/docs/guides/development/testing/overview#testing-tokens) for the instance. ```ts function createTestingToken(): Promise ``` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerk.testingTokens.createTestingToken() ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/testing_tokens`. See the [BAPI reference](/docs/reference/backend-api/tag/testing-tokens/post/testing_tokens){{ target: '_blank' }} for more information. --- title: "`createSignInToken()`" description: Use Clerk's JS Backend SDK to create a new sign-in token for a given user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/sign-in-tokens/create-sign-in-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/sign-in-tokens/create-sign-in-token.mdx --- Creates a new sign-in token and associates it with the given user. By default, sign-in tokens expire in 30 days. You can optionally supply a different duration in seconds using the `expires_in_seconds` property. ```ts function createSignInToken(params: CreateSignInTokensParams): Promise ``` ## `CreateSignInTokenParams` * `userId` * `string` The ID of the user who can use the newly created sign-in token. *** * `expiresInSeconds` * `string` Specifies the life duration of the sign in token in seconds. Defaults to `2592000` (30 days) ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const expiresInSeconds = 60 * 60 * 24 * 7 // 1 week const response = await clerkClient.signInTokens.createSignInToken({ userId, expiresInSeconds, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/sign_in_tokens`. See the [BAPI reference](/docs/reference/backend-api/tag/sign-in-tokens/post/sign_in_tokens){{ target: '_blank' }} for more information. --- title: "`revokeSignInToken()`" description: Use Clerk's JS Backend SDK to revoke a pending sign-in token. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/sign-in-tokens/revoke-sign-in-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/sign-in-tokens/revoke-sign-in-token.mdx --- Revokes a pending sign-in token. ```ts function revokeSignInToken(signInTokenId: string): Promise ``` ## Parameters * `signInTokenId` * `string` The ID of the sign-in token to revoke. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const signInTokenId = 'sit_123' const response = await clerkClient.signInTokens.revokeSignInToken(signInTokenId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/sign_in_tokens/{sign_in_token_id}/revoke`. See the [BAPI reference](/docs/reference/backend-api/tag/sign-in-tokens/post/sign_in_tokens/\{sign_in_token_id}/revoke){{ target: '_blank' }} for more information. --- title: Auth object description: The Auth object contains information about the current user's session. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/auth-object lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/auth-object.mdx --- The `Auth` object contains important information like the current user's session ID, user ID, and Organization ID. It also contains methods to check for Permissions and retrieve the current user's session token. > \[!NOTE] > The structure of the `Auth` object varies depending on the type of request. > For machine-authenticated requests (e.g. using an API key or OAuth token), the object reflects machine-level authentication data instead of user session details. > > If you're working with machine-authenticated requests, refer to the [Machine properties section](#machine-properties) for a detailed breakdown. ## How to access the `Auth` object {/* How to access the `Auth` object */} The `Auth` object is available on the `request` object in server contexts. Some frameworks provide a helper that returns the `Auth` object. See the following table for more information. | Framework | How to access the `Auth` object | | - | - | | Next.js App Router | auth() | | Next.js Pages Router | getAuth() | | Astro | locals.auth() | | Express | req.auth | | React Router | getAuth() | | Remix | getAuth() | | Tanstack React Start | auth() | | Other | `request.auth` | ## Session properties * `actor` * `ActClaim | undefined` Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). *** * `debug` * `AuthObjectDebug` Used to help debug issues when using Clerk in development. *** * `factorVerificationAge` * `[number, number] | null` An array where each item represents the number of minutes since the last verification of a first or second factor: `[firstFactorAge, secondFactorAge]`. *** * [`getToken()`](#get-token) * `ServerGetToken` A function that gets the current user's [session token](/docs/guides/sessions/session-tokens) or a [custom JWT template](/docs/guides/sessions/jwt-templates). *** * [`has()`](#has) * (isAuthorizedParams: [CheckAuthorizationParamsWithCustomPermissions](#check-authorization-params-with-custom-permissions)) => boolean A function that checks if the user has an Organization Role or custom Permission. *** * `orgId` * `string | undefined` The ID of the user's Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `orgPermissions` * OrganizationCustomPermissionKey\[] | undefined The current user's Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. permissions. *** * `orgRole` * OrganizationCustomRoleKey | undefined The current user's Role in their Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `orgSlug` * `string | undefined` The URL-friendly identifier of the user's Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `sessionClaims` * `JwtPayload` The current user's [session claims](/docs/guides/sessions/session-tokens). *** * `sessionStatus` * `'active' | 'pending'` The current state of the session. *** * `sessionId` * `string` The ID of the current session. *** * `tokenType` * `'session_token'` The type of request to authenticate. *** * `userId` * `string` The ID of the current user. ### `has()` The `has()` helper can be used to do two types of checks: * **Authorization:** Check if the user has been granted a specific type of access control (Role, Permission, Feature, or Plan) and returns a boolean value. For examples, see the [guide on verifying if a user is authorized](/docs/guides/secure/authorization-checks). * **Reverification:** Check if the user has verified their credentials within a certain time frame and returns a boolean value. For examples, see the [guide on reverification](/docs/guides/secure/reverification). ```ts function has(isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions): boolean ``` #### `CheckAuthorizationParamsWithCustomPermissions` `CheckAuthorizationParamsWithCustomPermissions` has the following properties: * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) to check for. *** * `permission` * `string` The [Permission](/docs/guides/organizations/roles-and-permissions) to check for. *** * `feature` * `string` The [Feature](/docs/guides/billing/overview) to check for. *** * `plan` * `string` The [Plan](/docs/guides/billing/overview) to check for. *** * `reverification?` * [ReverificationConfig](#reverification-config) The reverification configuration to check for. This feature is currently in public beta. **It is not recommended for production use**. ##### `ReverificationConfig` ```ts type ReverificationConfig = | SessionVerificationTypes | { level: SessionVerificationLevel afterMinutes: SessionVerificationAfterMinutes } type SessionVerificationTypes = 'strict_mfa' | 'strict' | 'moderate' | 'lax' ``` The `ReverificationConfig` type has the following properties: * `strict_mfa` Requires the user to verify their credentials within the past 10 minutes. If not verified, prompt for both the first and second factors. *** * `strict` Requires the user to verify their credentials within the past 10 minutes. If not verified, prompt for the second factor. *** * `moderate` Requires the user to verify their credentials within the past hour. If not verified, prompt for the second factor. *** * `lax` Requires the user to verify their credentials within the past day. If not verified, prompt for the second factor. *** * `level` * `"first_factor" | "second_factor" | "multi_factor"` The reverification level of credentials to check for. *** * `afterMinutes` * `number` The age of the factor level to check for. Value should be greater than or equal to 1 and less than 99,999. ### `getToken()` `getToken()` retrieves the current user's [session token](/docs/guides/sessions/session-tokens) or a [custom JWT template](/docs/guides/sessions/jwt-templates). > \[!NOTE] > Providing a `template` will perform a network request and will count towards [rate limits](/docs/guides/how-clerk-works/system-limits#backend-api-requests). ```typescript const getToken: ServerGetToken type ServerGetToken = (options?: ServerGetTokenOptions) => Promise type ServerGetTokenOptions = { template?: string // The name of the custom JWT template to retrieve. } ``` #### Example: Use `getToken()` in the frontend The `Auth` object is not available in the frontend. To use the `getToken()` method in the frontend: * For React-based applications, you can use the `useAuth()` hook. See the reference documentation for example usage. * For JavaScript applications, see the reference documentation for example usage. #### Example: Use `getToken()` in the backend To use the `getToken()` method in the backend: * In App Router applications, use the auth() helper. * In Pages Router applications, use the getAuth() helper. ```js {{ filename: 'app/api/get-token-example/route.ts' }} import { auth } from '@clerk/nextjs/server' export async function GET() { const { getToken } = await auth() const template = 'supabase' const token = await getToken({ template }) return Response.json({ token }) } ``` ```ts {{ filename: 'pages/api/getToken.ts' }} import { getAuth } from '@clerk/nextjs/server' import type { NextApiRequest, NextApiResponse } from 'next' export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { getToken } = getAuth(req) const template = 'test' const token = await getToken({ template }) return res.json({ token }) } ``` ```ts {{ filename: 'app/routes/api/example.ts' }} import { getAuth } from '@clerk/tanstack-react-start/server' import { json } from '@tanstack/react-start' import { createServerFileRoute } from '@tanstack/react-start/server' export const ServerRoute = createServerFileRoute().methods({ GET: async ({ req, params }) => { const { isAuthenticated, userId, getToken } = await getAuth(req) if (!isAuthenticated) { return json({ error: 'Unauthorized' }, { status: 401 }) } const token = await getToken({ template: 'supabase' }) // Add logic that retrieves the data // from your database using the token return json({ // ... }) }, }) ``` To use the `getToken()` method in the backend, you can access it using the `Auth` object returned by the `request` object. ```js {{ filename: 'getToken.ts' }} app.get('/api/get-token', async (req, res) => { const getToken = req.auth.getToken const template = 'test' const token = await getToken({ template }) res.json({ token }) }) ``` To use the `getToken()` method in the backend, you can access it using the getAuth() function. ```ts {{ filename: 'app/routes/get-token.ts' }} import { getAuth } from '@clerk/remix/ssr.server' import { ActionFunction, json } from '@remix-run/node' export const action: ActionFunction = async (req) => { const { getToken } = await getAuth(req) const template = 'test' const token = await getToken({ template }) return json({ token }) } ``` ## `Auth` object example without Active Organization The following is an example of the `Auth` object without an Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Notice that there is no `o` claim. Read more about token claims in the [guide on session tokens](/docs/guides/sessions/session-tokens). > \[!IMPORTANT] > This example is for version 2 of Clerk's session token. To see an example of version 1, select the respective tab above. ```js {{ prettier: false }} { azp: 'http://localhost:3000', email: 'email@example.com', exp: 1744735488, fva: [ 9, -1 ], iat: 1744735428, iss: 'https://renewing-bobcat-00.clerk.accounts.dev', jti: 'aee4d4a5071bdd66e21b', nbf: 1744735418, pla: 'u:example-plan', role: 'authenticated', sid: 'sess_123', sub: 'user_123', v: 2 } ``` > \[!IMPORTANT] > Version 1 of Clerk's session token was deprecated on April 14, 2025. To upgrade to version 2, go to the [**Updates**](https://dashboard.clerk.com/~/updates) page in the Clerk Dashboard. ```js {{ prettier: false }} { sessionId: 'sess_123', userId: 'user_123', orgId: null, orgRole: null, orgSlug: null, orgPermissions: null, has: [Function (anonymous)], getToken: [AsyncFunction (anonymous)], claims: { azp: 'http://localhost:3000', exp: 1666622607, iat: 1666622547, iss: 'https://renewing-bobcat-00.clerk.accounts.dev', nbf: 1666622537, sid: 'sess_123', sub: 'user_123', }, } ``` ## `Auth` object example with Active Organization The following is an example of the `Auth` object with an Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Notice the addition of the `o` claim. Read more about token claims in the [guide on session tokens](/docs/guides/sessions/session-tokens). > \[!IMPORTANT] > This example is for version 2 of Clerk's session token. To see an example of version 1, select the respective tab above. ```js {{ prettier: false }} { azp: 'http://localhost:3000', email: 'email@example.com', exp: 1744734948, fea: 'o:example-feature', fva: [ 0, -1 ], iat: 1744734888, iss: 'https://renewing-bobcat-00.clerk.accounts.dev', jti: '004f0096e5cd44911924', nbf: 1744734878, o: { fpm: '1', id: 'org_123', per: 'example-perm', rol: 'admin', slg: 'example-org' }, pla: 'o:free_org', role: 'authenticated', sid: 'sess_123', sub: 'user_123', v: 2 } ``` > \[!IMPORTANT] > Version 1 of Clerk's session token was deprecated on April 14, 2025. To upgrade to version 2, go to the [**Updates**](https://dashboard.clerk.com/~/updates) page in the Clerk Dashboard. ```js {{ prettier: false }} { sessionId: 'sess_123', userId: 'user_123', orgId: 'org_123', orgRole: 'org:admin', orgSlug: undefined, orgPermissions: ['org:example-feature:example-perm'], // Custom Permissions has: [Function (anonymous)], getToken: [AsyncFunction (anonymous)], claims: { azp: 'http://localhost:3000', exp: 1666622607, iat: 1666622547, iss: 'https://renewing-bobcat-00.clerk.accounts.dev', nbf: 1666622537, sid: 'sess_123', sub: 'user_123', }, } ``` ## `Auth` object example with valid factor age The following is an example of the `Auth` object with a valid factor age. Notice the addition of the `fva` claim with a value of `[0, 0]`, indicating that the first and second factors have been verified within the past minute. Read more about token claims in the [guide on session tokens](/docs/guides/sessions/session-tokens). > \[!IMPORTANT] > This example is for version 2 of Clerk's session token. To see an example of version 1, select the respective tab above. ```js {{ mark: [5], prettier: false }} { azp: 'http://localhost:3000', email: 'email@example.com', exp: 1744735488, fva: [ 0,0 ], iat: 1744735428, iss: 'https://renewing-bobcat-00.clerk.accounts.dev', jti: 'aee4d4a5071bdd66e21b', nbf: 1744735418, role: 'authenticated', sid: 'sess_123', sub: 'user_123', v: 2 } ``` > \[!IMPORTANT] > Version 1 of Clerk's session token was deprecated on April 14, 2025. To upgrade to version 2, go to the [**Updates**](https://dashboard.clerk.com/~/updates) page in the Clerk Dashboard. ```js {{ mark: [8], prettier: false }} { sessionId: 'sess_123', userId: 'user_123', orgId: null, orgRole: null, orgSlug: null, orgPermissions: null, factorVerificationAge: [0,0], has: [Function (anonymous)], getToken: [AsyncFunction (anonymous)], claims: { azp: 'http://localhost:3000', exp: 1666622607, iat: 1666622547, iss: 'https://renewing-bobcat-00.clerk.accounts.dev', nbf: 1666622537, sid: 'sess_123', sub: 'user_123', }, } ``` ## `Auth` object example of a user without an MFA method registered The following is an example of the `Auth` object of a user without an MFA method registered. Notice the addition of the `fva` claim, but the value is `[0, -1]`. `0` indicates that the first factor has been verified within the past minute, and `-1` indicates that there is no second factor registered for the user. Read more about token claims in the [guide on session tokens](/docs/guides/sessions/session-tokens). > \[!IMPORTANT] > This example is for version 2 of Clerk's session token. To see an example of version 1, select the respective tab above. ```js {{ mark: [5], prettier: false }} { azp: 'http://localhost:3000', email: 'email@example.com', exp: 1744735488, fva: [ 0,-1 ], iat: 1744735428, iss: 'https://renewing-bobcat-00.clerk.accounts.dev', jti: 'aee4d4a5071bdd66e21b', nbf: 1744735418, role: 'authenticated', sid: 'sess_123', sub: 'user_123', v: 2 } ``` > \[!IMPORTANT] > Version 1 of Clerk's session token was deprecated on April 14, 2025. To upgrade to version 2, go to the [**Updates**](https://dashboard.clerk.com/~/updates) page in the Clerk Dashboard. ```js {{ mark: [8], prettier: false }} { sessionId: 'sess_123', userId: 'user_123', orgId: null, orgRole: null, orgSlug: null, orgPermissions: null, factorVerificationAge: [0, -1], has: [Function (anonymous)], getToken: [AsyncFunction (anonymous)], claims: { azp: 'http://localhost:3000', exp: 1666622607, iat: 1666622547, iss: 'https://renewing-bobcat-00.clerk.accounts.dev', nbf: 1666622537, sid: 'sess_123', sub: 'user_123', }, } ``` ## Machine properties * `id` * `string` The ID of the machine. *** * `subject` * `string` The ID of the user or Organization that the machine is associated with. *** * `name` * `string` The name of the machine. For 'api\_key' and 'machine\_token' types. *** * `claims` * `Record | null` The machine's claims. For 'api\_key' and 'machine\_token' types. *** * `scopes` * `string[]` The scopes of the machine. *** * [`getToken()`](#get-token) * `() => Promise` A function that gets the machine's token. *** * `tokenType` * `'api_key' | 'oauth_token' | 'm2m_token'` The type of request to authenticate. *** * `debug` * `AuthObjectDebug` Used to help debug issues when using Clerk in development. ## `Auth` object example of a machine request The following is an example of the `Auth` object of an authenticated machine request (i.e. a request authenticated using a machine token like an API key). Notice the addition of a `tokenType` property with the value of `'api_key'`, which distinguishes the request as a machine request rather than a user session. The `scopes` array defines the permissions granted by the token. ```js {{ prettier: false }} { id: 'oat_123', tokenType: 'oauth_token', userId: 'user_123', clientId: 'client_123', name: 'GitHub OAuth', scopes: ['read', 'write'], getToken: [AsyncFunction (anonymous)], } ``` --- title: The Backend `AllowlistIdentifier` object description: The Backend AllowlistIdentifier object holds information about a AllowlistIdentifier of your application. However, the Backend AllowlistIdentifier object is different from the AllowlistIdentifier object in that it is used in the Backend API. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-allowlist-identifier lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-allowlist-identifier.mdx --- The Backend `AllowlistIdentifier` object represents an identifier that has been added to the allowlist of your application. The Backend `AllowlistIdentifier` object is used in the [Backend API](/docs/reference/backend-api/tag/Allow-list-Block-list#operation/ListAllowlistIdentifiers) and is not directly accessible from the Frontend API. ## Properties | Property | Type | Description | | -------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------- | | `createdAt` | `number` | The date when the allowlist identifier was first created. | | `id` | `string` | A unique ID for the allowlist identifier. | | `identifier` | `string` | The identifier that was added to the allowlist. | | `identifierType` | "email\_address" \| "phone\_number" \| "web3\_wallet" | The type of the allowlist identifier. | | `instanceId?` | `string` | The ID of the instance that this allowlist identifier belongs to. | | `invitationId?` | `string` | The ID of the invitation sent to the identifier. | | `updatedAt` | `number` | The date when the allowlist identifier was last updated. | --- title: The Backend `IdentificationLink` object description: Contains information about any identifications that might be linked to the email address. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-identification-link lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-identification-link.mdx --- Contains information about any identifications that might be linked to the email address. ## Properties | Property | Type | Description | | ------------------------ | -------- | ------------------------------------------------------------------------------------ | | `id` | `string` | The unique identifier for the identification link. | | `type` | `string` | The type of the identification link, e.g., `"email_address"`, `"phone_number"`, etc. | --- title: The Backend `EmailAddress` object description: The Backend EmailAddress object is a model around an email address. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-email-address lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-email-address.mdx --- The Backend `EmailAddress` object is a model around an email address. Email addresses must be **verified** to ensure that they are assigned to their rightful owners. The `EmailAddress` object holds all necessary state around the verification process. For implementation examples for adding and verifying email addresses, see the [email link custom flow](/docs/guides/development/custom-flows/authentication/email-links) and [email code custom flow](/docs/guides/development/custom-flows/account-updates/add-email) guides. ## Properties | Property | Type | Description | | ---------------------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | `emailAddress` | `string` | The value of the email address. | | `id` | `string` | The unique identifier for the email address. | | `linkedTo` | [IdentificationLink](/docs/reference/backend/types/backend-identification-link)\[] | An array of objects containing information about any identifications that might be linked to the email address. | | `verification` | null \| [Verification](/docs/reference/backend/types/backend-verification) | An object holding information on the verification of the email address. | --- title: The Backend `Invitation` object description: The Backend Invitation object represents an invitation to join your application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-invitation lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-invitation.mdx --- The Backend `Invitation` object represents an invitation to join your application. ## Properties | Property | Type | Description | | -------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createdAt` | `number` | The date when the `Invitation` was first created. | | `emailAddress` | `string` | The email address that the invitation was sent to. | | `id` | `string` | The unique identifier for the `Invitation`. | | `publicMetadata` | null \| Record\ | Metadata{{ target: '_blank' }} that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. | | `revoked?` | `boolean` | Whether the `Invitation` has been revoked. | | `status` | "expired" \| "revoked" \| "pending" \| "accepted" | The status of the `Invitation`. | | `updatedAt` | `number` | The date when the `Invitation` was last updated. | | `url?` | `string` | The URL that the user can use to accept the invitation. | --- title: The Backend `ExternalAccount` object description: The Backend ExternalAccount object is a model around an identification obtained by an external provider (e.g. a social provider such as Google). sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-external-account lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-external-account.mdx --- The Backend `ExternalAccount` object is a model around an identification obtained by an external provider (e.g. a social provider such as Google). External account must be verified, so that you can make sure they can be assigned to their rightful owners. The `ExternalAccount` object holds all necessary state around the verification process. ## Properties | Property | Type | Description | | ------------------------------------------------ | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | | `approvedScopes` | `string` | The scopes that the user has granted access to. | | `emailAddress` | `string` | The user's email address. | | `externalId` | `string` | The unique ID of the user in the provider. | | `firstName` | `string` | The user's first name. | | `id` | `string` | The unique identifier for this external account. | | `identificationId` | `string` | The identification with which this external account is associated. | | `imageUrl` | `string` | The user's image URL. | | `label` | null \| string | A descriptive label to differentiate multiple external accounts of the same user for the same provider. | | `lastName` | `string` | The user's last name. | | `phoneNumber` | null \| string | The phone number related to this specific external account. | | `provider` | `string` | The provider name (e.g., `google`). | | `publicMetadata` | null \| Record\ | Metadata that can be read from the Frontend API and Backend API and can be set only from the Backend API. | | `username` | null \| string | The user's username. | | `verification` | null \| [Verification](/docs/reference/backend/types/backend-verification) | An object holding information on the verification of this external account. | --- title: The Backend `Client` object description: The Backend Client object holds information about the authenticated sessions in the current device. However, the Backend Client object is different from the Client object in that it is used in the Backend API. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-client lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-client.mdx --- The Backend `Client` object is similar to the Client object as it holds information about the authenticated sessions in the current device. However, the Backend `Client` object is different from the `Client` object in that it is used in the [Backend API](/docs/reference/backend-api/tag/Clients#operation/GetClient) and is not directly accessible from the Frontend API. ## Properties | Property | Type | Description | | -------------------------------------------------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | `createdAt` | `number` | The date when the `Client` was first created. | | `id` | `string` | The unique identifier for the `Client`. | | `lastActiveSessionId` | null \| string | The ID of the last active [Session](/docs/reference/backend/types/backend-session). | | `lastAuthenticationStrategy` | null \| LastAuthenticationStrategy | The last authentication strategy used by the `Client`. | | `sessionIds` | string\[] | An array of [Session](/docs/reference/backend/types/backend-session){{ target: '_blank' }} IDs associated with the `Client`. | | `sessions` | [Session](/docs/reference/backend/types/backend-session)\[] | An array of [Session](/docs/reference/backend/types/backend-session){{ target: '_blank' }} objects associated with the `Client`. | | `signInId` | null \| string | The ID of the SignIn{{ target: '_blank' }}. | | `signUpId` | null \| string | The ID of the SignUp{{ target: '_blank' }}. | | `updatedAt` | `number` | The date when the `Client` was last updated. | --- title: The Backend `OAuthApplication` object description: The Backend OAuthApplication object describes an OAuth Application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-oauth-application lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-oauth-application.mdx --- The Backend `OAuthApplication` object holds information about an OAuth application. ## Properties | Property | Type | Description | | ---------------------------------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `authorizeUrl` | `string` | The URL used to authorize the user and obtain an authorization code. | | `clientId` | `string` | The ID of the client associated with the OAuth application. | | `clientImageUrl` | null \| string | The URL of the image or logo representing the OAuth application. | | `clientSecret?` | `string` | The client secret associated with the OAuth application. Empty if public client. | | `clientUri` | null \| string | The public-facing URL of the OAuth application, often shown on consent screens. | | `consentScreenEnabled` | `boolean` | Specifies whether the consent screen should be displayed in the authentication flow. Cannot be disabled for dynamically registered OAuth applications. | | `createdAt` | `number` | The date when the OAuth application was first created. | | `discoveryUrl` | `string` | The OpenID Connect discovery endpoint URL for this OAuth application. | | `dynamicallyRegistered` | `boolean` | Specifies whether the OAuth application is dynamically registered. | | `id` | `string` | The unique identifier for the OAuth application. | | `instanceId` | `string` | The ID of the instance that this OAuth application belongs to. | | `isPublic` | `boolean` | Indicates whether the client is public. If true, the Proof Key of Code Exchange (PKCE) flow can be used. | | `name` | `string` | The name of the new OAuth application. | | `pkceRequired` | `boolean` | Specifies whether the Proof Key of Code Exchange (PKCE) flow should be required in the authentication flow. | | `redirectUris` | string\[] | An array of redirect URIs of the new OAuth application. | | `scopes` | `string` | Scopes for the new OAuth application. | | `tokenFetchUrl` | `string` | The URL used by the client to exchange an authorization code for an access token. | | `tokenIntrospectionUrl` | `string` | The URL used to introspect and validate issued access tokens. | | `updatedAt` | `number` | The date when the OAuth application was last updated. | | `userInfoUrl` | `string` | The URL where the client can retrieve user information using an access token. | --- title: The Backend `OrganizationInvitation` object description: The Backend OrganizationInvitation object is the model around an Organization invitation. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-organization-invitation lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-organization-invitation.mdx --- The Backend `OrganizationInvitation` object is similar to the OrganizationInvitation object as it's the model around an organization invitation. However, the Backend `OrganizationInvitation` object is different in that it's used in the [Backend API](/docs/reference/backend-api/tag/Organization-Invitations#operation/CreateOrganizationInvitation){{ target: '_blank' }} and is not directly accessible from the Frontend API. ## Properties | Property | Type | Description | | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createdAt` | `number` | The date when the invitation was first created. | | `emailAddress` | `string` | The email address of the user who is invited to the [`Organization`](/docs/reference/backend/types/backend-organization). | | `expiresAt` | `number` | The date when the invitation expires. | | `id` | `string` | The unique identifier for the `OrganizationInvitation`. | | `organizationId` | `string` | The ID of the [`Organization`](/docs/reference/backend/types/backend-organization) that the user is invited to. | | `privateMetadata` | OrganizationInvitationPrivateMetadata | Metadata that can be read and set only from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. | | `publicMetadata` | OrganizationInvitationPublicMetadata | Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. | | `publicOrganizationData?` | null \| [PublicOrganizationDataJSON](#public-organization-data-json) | Public data about the organization that the user is invited to. | | `role` | `string` | The role of the invited user. | | `roleName` | `string` | The name of the role of the invited user. | | `status?` | "revoked" \| "pending" \| "accepted" | The status of the invitation. | | `updatedAt` | `number` | The date when the invitation was last updated. | | `url` | null \| string | The URL that the user can use to accept the invitation. | ## `PublicOrganizationDataJSON` | Property | Type | Description | | ----------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | `has_image` | `boolean` | Whether the organization has a profile image. | | `id` | `string` | The unique identifier for the resource. | | `image_url?` | `string` | Holds the default organization profile image. Compatible with Clerk's [Image Optimization](/docs/guides/development/image-optimization). | | `name` | `string` | The name of the organization. | | `object` | `ObjectType` | The type of the resource. | | `slug` | `string` | The slug of the organization. | --- title: The Backend `OrganizationMembership` object description: The Backend OrganizationMembership object is the model around an Organization membership entity and describes the relationship between users and Organizations. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-organization-membership lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-organization-membership.mdx --- The Backend `OrganizationMembership` object is similar to the OrganizationMembership object as it's the model around an organization membership entity and describes the relationship between users and organizations. However, the Backend `OrganizationMembership` object is different in that it's used in the [Backend API](/docs/reference/backend-api/tag/Organization-Memberships#operation/CreateOrganizationMembership){{ target: '_blank' }} and is not directly accessible from the Frontend API. ## Properties | Property | Type | Description | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `createdAt` | `number` | The date when the membership was first created. | | `id` | `string` | The unique identifier for the membership. | | `organization` | [`Organization`](/docs/reference/backend/types/backend-organization) | The organization that the user is a member of. | | `permissions` | string\[] | The permissions granted to the user in the organization. | | `privateMetadata` | OrganizationMembershipPrivateMetadata | Metadata that can be read and set only from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. | | `publicMetadata` | OrganizationMembershipPublicMetadata | Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. | | `publicUserData?` | null \| [OrganizationMembershipPublicUserData](#organization-membership-public-user-data) | Public information about the user that this membership belongs to. | | `role` | `string` | The role of the user. | | `updatedAt` | `number` | The date when the membership was last updated. | ### `OrganizationMembershipPublicUserData` | Property | Type | Description | | ------------------------------------ | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | `firstName` | null \| string | The first name of the user. | | `hasImage` | `boolean` | Whether the user has a profile picture. | | `identifier` | `string` | The identifier of the user. | | `imageUrl` | `string` | Holds the default avatar or user's uploaded profile image. Compatible with Clerk's [Image Optimization](/docs/guides/development/image-optimization). | | `lastName` | null \| string | The last name of the user. | | `userId` | `string` | The ID of the user that this public data belongs to. | --- title: The Backend `Organization` object description: The Backend Organization object holds information about an Organization, as well as methods for managing it. However, the it is different from the Organization object in that it is used in the Backend API and is not directly accessible from the Frontend API. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-organization.mdx --- The Backend `Organization` object is similar to the Organization object as it holds information about an organization, as well as methods for managing it. However, the Backend `Organization` object is different in that it is used in the [Backend API](/docs/reference/backend-api/tag/Organizations#operation/ListOrganizations){{ target: '_blank' }} and is not directly accessible from the Frontend API. ## Properties | Property | Type | Description | | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `adminDeleteEnabled` | `boolean` | Whether the organization allows admins to delete users. | | `createdAt` | `number` | The date when the organization was first created. | | `createdBy?` | `string` | The ID of the user who created the organization. | | `hasImage` | `boolean` | Whether the organization has an image. | | `id` | `string` | The unique identifier for the organization. | | `imageUrl` | `string` | Holds the organization's logo. Compatible with Clerk's [Image Optimization](/docs/guides/development/image-optimization). | | `maxAllowedMemberships` | `number` | The maximum number of memberships allowed in the organization. | | `membersCount?` | `number` | The number of members in the organization. | | `name` | `string` | The name of the organization. | | `privateMetadata` | OrganizationPrivateMetadata | Metadata that can be read and set only from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. | | `publicMetadata` | null \| OrganizationPublicMetadata | Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. | | `slug` | `string` | The URL-friendly identifier of the user's active organization. If supplied, it must be unique for the instance. | | `updatedAt` | `number` | The date when the organization was last updated. | --- title: The Backend `PhoneNumber` object description: The Backend PhoneNumber object describes a phone number. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-phone-number lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-phone-number.mdx --- The Backend `PhoneNumber` object describes a phone number. Phone numbers can be used as a proof of identification for users, or simply as a means of contacting users. Phone numbers must be **verified** to ensure that they can be assigned to their rightful owners. The `PhoneNumber` object holds all the necessary state around the verification process. Finally, phone numbers can be used as part of [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication). During sign in, users can opt in to an extra verification step where they will receive an SMS message with a one-time code. This code must be entered to complete the sign in process. ## Properties | Property | Type | Description | | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `defaultSecondFactor` | `boolean` | Set to `true` if this phone number is the default second factor. Set to `false` otherwise. A user must have exactly one default second factor, if multi-factor authentication (2FA) is enabled. | | `id` | `string` | The unique identifier for this phone number. | | `linkedTo` | [IdentificationLink](/docs/reference/backend/types/backend-identification-link)\[] | An object containing information about any other identification that might be linked to this phone number. | | `phoneNumber` | `string` | The value of this phone number, in [E.164 format](https://en.wikipedia.org/wiki/E.164). | | `reservedForSecondFactor` | `boolean` | Set to `true` if this phone number is reserved for multi-factor authentication (2FA). Set to `false` otherwise. | | `verification` | null \| [Verification](/docs/reference/backend/types/backend-verification) | An object holding information on the verification of this phone number. | --- title: The Backend `RedirectUrl` object description: The Backend RedirectUrl object represents a redirect URL in your application. This object is used in the Backend API. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-redirect-url lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-redirect-url.mdx --- Redirect URLs are whitelisted URLs that facilitate secure authentication flows in native applications (e.g. React Native, Expo). In these contexts, Clerk ensures that security-critical nonces are passed only to the whitelisted URLs. The Backend `RedirectUrl` object represents a redirect URL in your application. This object is used in the Backend API. ## Properties | Property | Type | Description | | ---------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `createdAt` | `number` | The date when the redirect URL was first created. | | `id` | `string` | The unique identifier for the redirect URL. | | `updatedAt` | `number` | The date when the redirect URL was last updated. | | `url` | `string` | The full URL value prefixed with `https://` or a custom scheme. Examples: `https://my-app.com/oauth-callback`, `my-app://oauth-callback`. | --- title: The Backend `SamlAccount` object description: The Backend SamlAccount object describes a SAML account. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-saml-account lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-saml-account.mdx --- The Backend `SamlAccount` object describes a SAML account. ## Properties | Property | Type | Description | | ------------------------------------------------------------ | --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | `active` | `boolean` | A boolean that indicates whether the SAML account is active. | | `emailAddress` | `string` | The email address of the SAML account. | | `enterpriseConnectionId` | null \| string | The ID of the enterprise connection associated with this SAML account. | | `firstName` | `string` | The first name of the SAML account. | | `id` | `string` | The unique identifier for the SAML account. | | `lastAuthenticatedAt` | null \| number | The date when the SAML account was last authenticated. | | `lastName` | `string` | The last name of the SAML account. | | `provider` | `string` | The provider of the SAML account. | | `providerUserId` | null \| string | The user's ID as used in the provider. | | `samlConnection` | null \| SamlAccountConnection | The SAML connection of the SAML account. | | `verification` | null \| [Verification](/docs/reference/backend/types/backend-verification) | The verification of the SAML account. | --- title: The Backend `SamlConnection` object description: The Backend SamlConnection object holds information about a SAML connection for an Organization. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-saml-connection lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-saml-connection.mdx --- The Backend `SamlConnection` object holds information about a SAML connection for an organization. ## Properties | Property | Type | Description | | ---------------------------------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `acsUrl` | `string` | The Assertion Consumer Service (ACS) URL of the connection. | | `active` | `boolean` | Indicates whether the connection is active or not. | | `allowIdpInitiated` | `boolean` | Indicates whether the connection allows Identity Provider (IdP) initiated flows or not. | | `allowSubdomains` | `boolean` | Indicates whether users with an email address subdomain are allowed to use this connection in order to authenticate or not. | | `attributeMapping` | `AttributeMapping` | Defines the attribute name mapping between the Identity Provider (IdP) and Clerk's User properties. | | `createdAt` | `number` | The date when the connection was first created. | | `domain` | `string` | The domain of your organization. Sign in flows using an email with this domain will use the connection. | | `id` | `string` | The unique identifier for the connection. | | `idpCertificate` | null \| string | The X.509 certificate as provided by the Identity Provider (IdP). | | `idpEntityId` | null \| string | The Entity ID as provided by the Identity Provider (IdP). | | `idpMetadata` | null \| string | The XML content of the Identity Provider (IdP) metadata file. If present, it takes priority over the corresponding individual properties. | | `idpMetadataUrl` | null \| string | The URL which serves the Identity Provider (IdP) metadata. If present, it takes priority over the corresponding individual properties. | | `idpSsoUrl` | null \| string | The Single-Sign On URL as provided by the Identity Provider (IdP). | | `name` | `string` | The name to use as a label for the connection. | | `organizationId` | null \| string | The organization ID of the organization. | | `provider` | `string` | The Identity Provider (IdP) of the connection. | | `spEntityId` | `string` | The Entity ID as provided by the Service Provider (Clerk). | | `spMetadataUrl` | `string` | The metadata URL as provided by the Service Provider (Clerk). | | `syncUserAttributes` | `boolean` | Indicates whether the connection syncs user attributes between the Service Provider (SP) and Identity Provider (IdP) or not. | | `updatedAt` | `number` | The date when the SAML connection was last updated. | | `userCount` | `number` | The number of users associated with the connection. | --- title: The Backend `Session` object description: The Backend Session object holds information about a Session of your application. However, the Backend Session object is different from the Session object in that it is used in the Backend API. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-session lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-session.mdx --- The Backend `Session` object is similar to the Session object as it is an abstraction over an HTTP session and models the period of information exchange between a user and the server. However, the Backend `Session` object is different as it is used in the [Backend API](/docs/reference/backend-api/tag/Sessions#operation/GetSessionList) and is not directly accessible from the Frontend API. ## Properties | Property | Type | Description | | ----------------------------------------------------------------- | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `abandonAt` | `number` | The date when the `Session` will be abandoned. | | `actor` | null \| Record\ | The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). | | `clientId` | `string` | The ID of the client associated with the `Session`. | | `createdAt` | `number` | The date when the `Session` was first created. | | `expireAt` | `number` | The date when the `Session` will expire. | | `id` | `string` | The unique identifier for the `Session`. | | `lastActiveAt` | `number` | The time the session was last active on the [`Client`](/docs/reference/backend/types/backend-client). | | `lastActiveOrganizationId?` | `string` | The ID of the last active organization. | | `latestActivity?` | [`SessionActivity`](/docs/reference/backend/types/backend-session-activity) | An object that provides additional information about this session, focused around user activity data. | | `status` | `string` | The current state of the `Session`. | | `updatedAt` | `number` | The date when the `Session` was last updated. | | `userId` | `string` | The ID of the user associated with the `Session`. | --- title: The Backend `SessionActivity` object description: The Backend SessionActivity object models the activity of a user session, capturing details such as the device type, browser information, and geographical location. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-session-activity lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-session-activity.mdx --- The Backend `SessionActivity` object models the activity of a user session, capturing details such as the device type, browser information, and geographical location. ## Properties | Property | Type | Description | | --------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------- | | `browserName?` | `string` | The name of the browser from which this session activity occurred. | | `browserVersion?` | `string` | The version of the browser from which this session activity occurred. | | `city?` | `string` | The city from which this session activity occurred. Resolved by IP address geo-location. | | `country?` | `string` | The country from which this session activity occurred. Resolved by IP address geo-location. | | `deviceType?` | `string` | The type of the device which was used in this session activity. | | `id` | `string` | The unique identifier for the session activity record. | | `ipAddress?` | `string` | The IP address from which this session activity originated. | | `isMobile` | `boolean` | Will be set to `true` if the session activity came from a mobile device. Set to `false` otherwise. | --- title: The Backend `User` object description: The Backend User object holds information about a user of your application. However, the Backend User object is different from the User object in that it is used in the Backend API. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-user.mdx --- The Backend `User` object is similar to the `User` object as it holds information about a user of your application, such as their unique identifier, name, email addresses, phone numbers, and more. However, the Backend `User` object is different from the `User` object in that it is used in the [Backend API](/docs/reference/backend-api/tag/Users#operation/GetUser){{ target: '_blank' }} and is not directly accessible from the Frontend API. ## Properties | Property | Type | Description | | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `backupCodeEnabled` | `boolean` | A boolean indicating whether the user has enabled Backup codes. | | `banned` | `boolean` | A boolean indicating whether the user is banned or not. | | `createdAt` | `number` | The date when the user was first created. | | `createOrganizationEnabled` | `boolean` | A boolean indicating whether the organization creation is enabled for the user or not. | | `createOrganizationsLimit` | null \| number | An integer indicating the number of organizations that can be created by the user. If the value is `0`, then the user can create unlimited organizations. Default is `null`. | | `deleteSelfEnabled` | `boolean` | A boolean indicating whether the user can delete their own account. | | `emailAddresses` | [EmailAddress](/docs/reference/backend/types/backend-email-address)\[] | An array of all the `EmailAddress` objects associated with the user. Includes the primary. | | `externalAccounts` | [ExternalAccount](/docs/reference/backend/types/backend-external-account)\[] | An array of all the `ExternalAccount` objects associated with the user via OAuth. **Note**: This includes both verified & unverified external accounts. | | `externalId` | null \| string | The ID of the user as used in your external systems. Must be unique across your instance. | | `firstName` | null \| string | The user's first name. | | `hasImage` | `boolean` | A getter boolean to check if the user has uploaded an image or one was copied from OAuth. Returns `false` if Clerk is displaying an avatar for the user. | | `id` | `string` | The unique identifier for the user. | | `imageUrl` | `string` | The URL of the user's profile image. | | `lastActiveAt` | null \| number | Date when the user was last active. | | `lastName` | null \| string | The user's last name. | | `lastSignInAt` | null \| number | The date when the user last signed in. May be empty if the user has never signed in. | | `legalAcceptedAt` | null \| number | The unix timestamp of when the user accepted the legal requirements. `null` if [**Require express consent to legal documents**](/docs/guides/secure/legal-compliance) is not enabled. | | `locale` | null \| string | The locale of the user in BCP-47 format. | | `locked` | `boolean` | A boolean indicating whether the user is banned or not. | | `passwordEnabled` | `boolean` | A boolean indicating whether the user has a password on their account. | | `phoneNumbers` | [PhoneNumber](/docs/reference/backend/types/backend-phone-number)\[] | An array of all the `PhoneNumber` objects associated with the user. Includes the primary. | | `primaryEmailAddressId` | null \| string | The ID for the `EmailAddress` that the user has set as primary. | | `primaryPhoneNumberId` | null \| string | The ID for the `PhoneNumber` that the user has set as primary. | | `primaryWeb3WalletId` | null \| string | The ID for the [`Web3Wallet`](/docs/reference/backend/types/backend-web3-wallet) that the user signed up with. | | `privateMetadata` | `UserPrivateMetadata` | Metadata that can be read and set only from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. | | `publicMetadata` | `UserPublicMetadata` | Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. | | `samlAccounts` | [SamlAccount](/docs/reference/backend/types/backend-saml-account)\[] | An array of all the `SamlAccount` objects associated with the user via SAML. | | `totpEnabled` | `boolean` | A boolean indicating whether the user has enabled TOTP by generating a TOTP secret and verifying it via an authenticator app. | | `twoFactorEnabled` | `boolean` | A boolean indicating whether the user has enabled two-factor authentication. | | `unsafeMetadata` | `UserUnsafeMetadata` | Metadata that can be read and set from the Frontend API. It's considered unsafe because it can be modified from the frontend. | | `updatedAt` | `number` | The date when the user was last updated. | | `username` | null \| string | The user's username. | | `web3Wallets` | [Web3Wallet](/docs/reference/backend/types/backend-web3-wallet)\[] | An array of all the `Web3Wallet` objects associated with the user. Includes the primary. | ## Accessors | Property | Type | Description | | ------------------------------------------------------ | ---------------------------------------------------------------------------------------- | -------------------------------------- | | `fullName` | null \| string | The full name of the user. | | `primaryEmailAddress` | null \| [EmailAddress](/docs/reference/backend/types/backend-email-address) | The primary email address of the user. | | `primaryPhoneNumber` | null \| [PhoneNumber](/docs/reference/backend/types/backend-phone-number) | The primary phone number of the user. | | `primaryWeb3Wallet` | null \| [Web3Wallet](/docs/reference/backend/types/backend-web3-wallet) | The primary web3 wallet of the user. | --- title: The Backend `Verification` object description: The Backend Verification object describes the state of the verification process of a sign-in or sign-up attempt. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-verification lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-verification.mdx --- The Backend `Verification` object describes the state of the verification process of a sign-in or sign-up attempt. ## Properties | Property | Type | Description | | ------------------------------------------------------------------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `attempts` | null \| number | The number of attempts related to the verification. | | `expireAt` | null \| number | The time the verification will expire at. | | `externalVerificationRedirectURL` | null \| URL | The redirect URL for an external verification. | | `message` | null \| string | The message that will be presented to the user's Web3 wallet for signing during authentication. This follows the [Sign-In with Ethereum (SIWE) protocol format](https://docs.login.xyz/general-information/siwe-overview/eip-4361#example-message-to-be-signed), which typically includes details like the requesting service, wallet address, terms acceptance, nonce, timestamp, and any additional resources. | | `nonce` | null \| string | The [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) pertaining to the verification. | | `status` | `VerificationStatus` | The state of the verification.
  • `unverified`: The verification has not been verified yet.
  • `verified`: The verification has been verified.
  • `transferable`: The verification is transferable to between sign-in and sign-up flows.
  • `failed`: The verification has failed.
  • `expired`: The verification has expired.
| |
`strategy` | `string` | The strategy pertaining to the parent sign-up or sign-in attempt. | --- title: The Backend `Web3Wallet` object description: The Backend Web3Wallet object describes a Web3 wallet address. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/backend-web3-wallet lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/backend-web3-wallet.mdx --- The Backend `Web3Wallet` object describes a Web3 wallet address. The address can be used as a proof of identification for users. Web3 addresses must be verified to ensure that they can be assigned to their rightful owners. The verification is completed via Web3 wallet browser extensions, such as [Metamask](https://metamask.io/), [Coinbase Wallet](https://www.coinbase.com/wallet), and [OKX Wallet](https://www.okx.com/help/section/faq-web3-wallet). The `Web3Wallet3` object holds all the necessary state around the verification process. ## Properties | Property | Type | Description | | ---------------------------------------- | --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | `id` | `string` | The unique ID for the Web3 wallet. | | `verification` | null \| [Verification](/docs/reference/backend/types/backend-verification) | An object holding information on the verification of this Web3 wallet. | | `web3Wallet` | `string` | The Web3 wallet address, made up of 0x + 40 hexadecimal characters. | --- title: "`CommercePlan`" description: The Backend `CommercePlan` object holds information about a Plan of your application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/commerce-plan lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/commerce-plan.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `CommercePlan` object is similar to the BillingPlanResource object as it holds information about a Plan, as well as methods for managing it. However, the `CommercePlan` object is different in that it is used in the [Backend API](https://clerk.com/docs/reference/backend-api/model/commerceplan){{ target: '_blank' }} and is not directly accessible from the Frontend API. ## Properties * `id` * `string` The unique identifier for the Plan. *** * `productId` * `string` The ID of the product the Plan belongs to. *** * `name` * `string` The name of the Plan. *** * `slug` * `string` The URL-friendly identifier of the Plan. *** * `description` * `undefined | string` The description of the Plan. *** * `isDefault` * `boolean` Whether the Plan is the default Plan. *** * `isRecurring` * `boolean` Whether the Plan is recurring. *** * `hasBaseFee` * `boolean` Whether the Plan has a base fee. *** * `publiclyVisible` * `boolean` Whether the Plan is displayed in the `` component. *** * `fee` * BillingMoneyAmount The monthly fee of the Plan. *** * `annualFee` * BillingMoneyAmount The annual fee of the Plan. *** * `annualMonthlyFee` * BillingMoneyAmount The annual fee of the Plan on a monthly basis. *** * `forPayerType` * `'user' | 'org'` The type of payer for the Plan. *** * `features` * [`Feature[]`](/docs/reference/backend/types/feature) The Features the Plan offers. --- title: "`CommerceSubscriptionItem`" description: The Backend `CommerceSubscriptionItem` object holds information about a subscription item of your application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/commerce-subscription-item lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/commerce-subscription-item.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `CommerceSubscriptionItem` object is similar to the BillingSubscriptionItemResource object as it holds information about a subscription item, as well as methods for managing it. However, the `CommerceSubscriptionItem` object is different in that it is used in the [Backend API](https://clerk.com/docs/reference/backend-api/model/commercesubscriptionitem){{ target: '_blank' }} and is not directly accessible from the Frontend API. ## Properties * `id` * `string` The unique identifier for the subscription item. *** * `status` * `'active' | 'past_due' | 'upcoming' | 'canceled' | 'ended' | 'expired' | 'incomplete' | 'abandoned'` The status of the subscription item. *** * `planPeriod` * `'month' | 'annual'` The Plan period for the subscription item. *** * `periodStart` * `number` Unix timestamp (milliseconds) of when the current period starts. *** * `periodEnd` * `number | null` Unix timestamp (milliseconds) of when the current period ends. *** * `nextPayment` * `null | { amount: number; date: number; }` The next payment information. If present, contains the amount of the next payment and the Unix timestamp (milliseconds) of when the next payment is scheduled. *** * `amount` * undefined | null | BillingMoneyAmount The current amount for the subscription item. *** * `plan` * [CommercePlan](/docs/reference/backend/types/commerce-plan) The Plan associated with this subscription item. *** * `planId` * `string` The Plan ID. *** * `createdAt` * `number` Unix timestamp (milliseconds) of when the subscription item was created. *** * `updatedAt` * `number` Unix timestamp (milliseconds) of when the subscription item was last updated. *** * `canceledAt` * `number | null` Unix timestamp (milliseconds) of when the subscription item was canceled. *** * `pastDueAt` * `number | null` Unix timestamp (milliseconds) of when the subscription item became past due. *** * `endedAt` * `number | null` Unix timestamp (milliseconds) of when the subscription item ended. *** * `payerId` * `string` The payer ID. *** * `isFreeTrial?` * `boolean` Whether this subscription item is currently in a free trial period. *** * `lifetimePaid?` * null | BillingMoneyAmount The lifetime amount paid for this subscription item. --- title: "`CommerceSubscription`" description: The Backend CommerceSubscription object holds information about a subscription of your application. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/commerce-subscription lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/commerce-subscription.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `CommerceSubscription` object is similar to the BillingSubscriptionResource object as it holds information about a subscription, as well as methods for managing it. However, the `CommerceSubscription` object is different in that it is used in the [Backend API](https://clerk.com/docs/reference/backend-api/tag/billing/get/organizations/%7Borganization_id%7D/billing/subscription){{ target: '_blank' }} and is not directly accessible from the Frontend API. ## Properties * `id` * `string` The unique identifier for the commerce subscription. *** * `status` * `"abandoned" | "active" | "ended" | "canceled" | "incomplete" | "past_due"` The current status of the subscription. *** * `payerId` * `string` The ID of the payer for this subscription. *** * `createdAt` * `number` Unix timestamp (milliseconds) of when the subscription was created. *** * `updatedAt` * `number` Unix timestamp (milliseconds) of when the subscription was last updated. *** * `activeAt` * `number | null` Unix timestamp (milliseconds) of when the subscription became active. *** * `pastDueAt` * `number | null` Unix timestamp (milliseconds) of when the subscription became past due. *** * `subscriptionItems` * [CommerceSubscriptionItem](/docs/reference/backend/types/commerce-subscription-item)\[] Array of subscription items in this subscription. *** * `nextPayment` * null | \{ amount: BillingMoneyAmount; date: number; } Information about the next scheduled payment. *** * `eligibleForFreeTrial` * `boolean` Whether the payer is eligible for a free trial. --- title: "`Feature`" description: The Feature type represents a Feature that a Plan can offer. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/feature lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/feature.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `Feature` object represents a Feature of a subscription Plan. * `id` * `string` The unique identifier for the Feature. *** * `name` * `string` The name of the Feature. *** * `description` * `string` The description of the Feature. *** * `slug` * `string` The URL-friendly identifier of the Feature. *** * `avatarUrl` * `string` The URL of the Feature's avatar image. --- title: "`PaginatedResourceResponse`" description: An interface that describes the response of a method that returns a paginated list of resources. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/types/paginated-resource-response lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/types/paginated-resource-response.mdx --- An interface that describes the response of a method that returns a paginated list of resources. If the promise resolves, you will get back the [properties](#properties) listed below. `data` will be an array of the resource type you requested. You can use the `totalCount` property to determine how many total items exist remotely. Some methods that return this type allow pagination with the `limit` and `offset` parameters, in which case the first 10 items will be returned by default. For methods such as [`getAllowlistIdentifierList()`](/docs/reference/backend/allowlist/get-allowlist-identifier-list), which do not take a `limit` or `offset`, all items will be returned. If the promise is rejected, you will receive a `ClerkAPIResponseError` or network error. ## Properties | Property | Type | Description | | ------------------------------------ | -------- | -------------------------------------------- | | `data` | `T` | An array that contains the fetched data. | | `totalCount` | `number` | The total count of data that exist remotely. | --- title: "`banUser()`" description: Use Clerk's JS Backend SDK to mark a given user as banned. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/ban-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/ban-user.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L247 */} Marks the given [`User`](/docs/reference/backend/types/backend-user) as banned, which means that all their sessions are revoked and they are not allowed to sign in again. ```ts function banUser(userId: string): Promise ``` ## Parameters * `userId` * `string` The ID of the user to ban. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.banUser(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/users/{user_id}/ban`. See the [BAPI reference](/docs/reference/backend-api/tag/users/post/users/\{user_id}/ban){{ target: '_blank' }} for more information. --- title: "`deleteUserPasskey()`" description: Use Clerk's JS Backend SDK to delete the passkey identification for a given user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/delete-user-passkey lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/delete-user-passkey.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L403 */} Deletes the passkey identification for a given user and notifies them through email. Returns a DeletedObjectResource. ```ts function deleteUserPasskey(params: DeleteUserPasskeyParams): Promise ``` ## `DeleteUserPasskeyParams` * `userId` * `string` The ID of the user that owns the passkey identity. *** * `passkeyIdentificationId` * `string` The ID of the passkey identity to be deleted. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const passkeyIdentificationId = 'passkey_identification_123' const response = await clerkClient.users.deleteUserPasskey({ userId, passkeyIdentificationId, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/users/{user_id}/passkeys/{passkey_identification_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/users/delete/users/%7Buser_id%7D/passkeys/%7Bpasskey_identification_id%7D){{ target: '_blank' }} for more information. --- title: "`createUser()`" description: Use Clerk's JS Backend SDK to create a user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/create-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/create-user.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L140 */} Creates a [`User`](/docs/reference/backend/types/backend-user). Your user management settings in the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) determine how you should setup your user model. Anything **Required** in **Users & Authentication -> User & authentication** will need to be provided when creating a user. Trying to add a field that isn't enabled in **Users & Authentication -> User & authentication** will result in an error. Any email address and phone number created using this method will be automatically marked as verified. > \[!CAUTION] > > This endpoint is [rate limited](/docs/guides/how-clerk-works/system-limits). For development instances, a rate limit rule of **100 requests per 10 seconds** is applied. > For production instances, that limit goes up to **1000 requests per 10 seconds**. ```ts function createUser(params: CreateUserParams): Promise ``` ## `CreateUserParams` * `externalId?` * `string` The ID of the user as used in your external systems. Must be unique across your instance. *** * `firstName?` * `string` The user's first name. *** * `lastName?` * `string` The user's last name. *** * `emailAddress[]?` * `string[]` Email addresses to add to the user. Must be unique across your instance. The first email address will be set as the users primary email address. *** * `phoneNumber[]?` * `string[]` Phone numbers that will be added to the user. Must be unique across your instance. The first phone number will be set as the users primary phone number. *** * `web3_wallet[]?` * `string[]` Web3 wallet addresses that will be added to the user. Must be unique across your instance. The first wallet will be set as the users primary wallet. *** * `username?` * `string` The username to give to the user. Must be unique across your instance. *** * `password?` * `string` The plaintext password to give the user. Must be at least 8 characters long, and can not be in any list of hacked passwords. *** * `passwordDigest?` * `string` In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. The digests should be generated with one of the supported algorithms. The hashing algorithm can be specified using the `password_hasher` property. *** * `passwordHasher?` * `'argon2i' | 'argon2id' | 'awscognito' | 'bcrypt' | 'bcrypt_sha256_django' | 'md5' | 'pbkdf2_sha256' | 'pbkdf2_sha256_django' | 'pbkdf2_sha1' | 'phpass' | 'scrypt_firebase' | 'scrypt_werkzeug' | 'sha256'` The hashing algorithm that was used to generate the password digest. The algorithms we support at the moment are: > \[!WARNING] > For password hashers considered insecure (currently, `MD5` and `SHA256`), the corresponding user password hashes will be transparently migrated to `bcrypt` (a secure hasher) upon the user's first successful password sign in. > Insecure schemes are marked with `(insecure)` in the list below. * `awscognito` * When set, `password_digest` must be in the format of `awscognito###`. * Upon a successful migration, `password_hasher` will be updated to `bcrypt`, and `password_digest` will be updated to a `bcrypt` hash. * See the [migration guide](/docs/guides/development/migrating/cognito) for usage details. * [`bcrypt`](https://en.wikipedia.org/wiki/Bcrypt) * When set, `password_digest` must be in the format of `$$$` * [`bcrypt_sha256_django`](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/) * This is the Django-specific variant of Bcrypt, using SHA256 hashing function. When set, `password_digest` must be in the format of (as exported from Django): `bcrypt_sha256$$$$` * [`bcrypt_peppered`](https://github.com/heartcombo/devise) * Used in implementations such as Devise for Ruby on Rails applications. Identical to `bcrypt` except that a `pepper` string is appended to the input before hashing. When set, `password_digest` must be in the format of `$$$$` * [`md5` (insecure)](https://en.wikipedia.org/wiki/MD5) * When set, `password_digest` must be in the format of `5f4dcc3b5aa765d61d8327deb882cf99` * [`pbkdf2_sha1`](https://en.wikipedia.org/wiki/PBKDF2) * When set, `password_digest` must be in the format of `pbkdf2_sha1$$$` or `pbkdf2_sha1$$$$` * Accepts the salt as a hex-encoded string. If the salt is not a valid hex string, the raw bytes will be used instead. Accepts the hash as a hex-encoded string. Optionally accepts the key length as the last parameter (defaults to 32). * [`pbkdf2_sha256`](https://en.wikipedia.org/wiki/PBKDF2) * This is the PBKDF2 algorithm using the SHA256 hashing function. When set, `password_digest` must be in the format of `pbkdf2_sha256$$$` * Both the salt and the hash are expected to be base64-encoded. * [`pbkdf2_sha512`](https://en.wikipedia.org/wiki/PBKDF2) * This is the PBKDF2 algorithm using the SHA512 hashing function. When set, `password_digest` must be in the format of `pbkdf2_sha512$$$` * [`pbkdf2_sha256_django`](https://docs.djangoproject.com/en/4.0/topics/auth/passwords/) * This is the Django-specific variant of PBKDF2. When set, `password_digest` must be in the format of (as exported from Django): `pbkdf2_sha256$$$` * The salt is expected to be un-encoded, the hash is expected base64-encoded. * [`phpass`](https://www.openwall.com/phpass/) * Portable public domain password hashing framework for use in PHP applications. When set, `password_digest` must be in the format of `$P$` * `$P$` is the prefix used to identify `phpass` hashes. * *rounds* is a single character encoding a 6-bit integer representing the number of rounds used. * *salt* is eight characters drawn from \[./0-9A-Za-z], providing a 48-bit salt. * *checksum* is 22 characters drawn from the same set, encoding the 128-bit checksum with MD5. * [`scrypt_firebase`](https://firebaseopensource.com/projects/firebase/scrypt/) * The Firebase-specific variant of scrypt. When set, `password_digest` must be in the format of `$$$$$` * *hash:* The actual Base64 hash. This can be retrieved when exporting the user from Firebase. * *salt:* The salt used to generate the above hash. Again, this is given when exporting the user from Firebase. * *signer key:* The base64 encoded signer key. * *salt separator:* The base64 encoded salt separator. * *rounds:* The number of rounds the algorithm needs to run. * *memory cost:* The cost of the algorithm run * The first 2 (hash and salt) are per user and can be retrieved when exporting the user from Firebase. The other 4 values (signer key, salt separator, rounds and memory cost) are project-wide settings and can be retrieved from the project's password hash parameters. * [`scrypt_werkzeug`](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.security.generate_password_hash) * The Werkzeug-specific variant of scrypt. When set, `password_digest` must be in the format of `$$$` * *algorithm args:* The algorithm used to generate the hash. * *salt:* The salt used to generate the above hash. * *hash:* The actual Base64 hash. * [`sha256` (insecure)](https://en.wikipedia.org/wiki/SHA-2) * When set, `password_digest` must be a 64-length hex string. For example: `9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08` * [`argon2`](https://argon2.online/) variants: `argon2i` and `argon2id`. * Algorithms in the argon2 family generate digests that encode the following information: * *version (v):* The argon version, version 19 is assumed * *memory (m):* The memory used by the algorithm (in kibibytes) * *iterations (t):* The number of iterations to perform * *parallelism (p):* The number of threads to use * Parts are demarcated by the `$` character, with the first part identifying the algorithm variant The middle part is a comma-separated list of the encoding options (memory, iterations, parallelism). The final part is the actual digest. * When set, `password_digest` must be in the format of `$argon2i$v=19$m=4096,t=3,p=1$4t6CL3P7YiHBtwESXawI8Hm20zJj4cs7/4/G3c187e0$m7RQFczcKr5bIR0IIxbpO2P0tyrLjf3eUW3M3QSwnLc` * For the argon2id case, the value of the algorithm in the first part of the digest is `argon2id`: `$argon2id$v=19$m=64,t=4,p=8$Z2liZXJyaXNo$iGXEpMBTDYQ8G/71tF0qGjxRHEmR3gpGULcE93zUJVU` If you need support for any particular hashing algorithm, [contact support](https://clerk.com/support). *** * `skipPasswordChecks?` * `boolean` When set to `true`, all password checks are skipped. It is recommended to use this method only when migrating plaintext passwords to Clerk. Upon migration the user base should be prompted to pick stronger password. *** * `skipPasswordRequirement?` * `boolean` When set to `true`, password is not required anymore when creating the user and can be omitted. This is useful when you are trying to create a user that doesn't have a password, in an instance that is using passwords. You cannot use this flag if password is the only way for a user to sign into your instance. *** * `totpSecret?` * `string` In case TOTP is configured on the instance, you can provide the secret to enable it on the newly created user without the need to reset it. Currently, the supported options are:
  • Period: 30 seconds
  • Code length: 6 digits
  • Algorithm: SHA1
*** * `backupCodes?` * `string[]` If backup codes are configured on the instance, you can provide them to enable it on the newly created user without the need to reset them. You must provide the backup codes in plain format or the corresponding bcrypt digest. *** * `publicMetadata?` * UserPublicMetadata Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. *** * `privateMetadata?` * UserPrivateMetadata Metadata that can be read and set only from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. *** * `unsafeMetadata?` * UserUnsafeMetadata Metadata that can be read and set from the Frontend API. It's considered unsafe because it can be modified from the frontend. *** * `legalAcceptedAt?` * `Date` The date when the user accepted the legal documents. `null` if [**Require express consent to legal documents**](/docs/guides/secure/legal-compliance) is not enabled. *** * `skipLegalChecks?` * `boolean` When set to `true` all legal checks are skipped. It is not recommended to skip legal checks unless you are migrating a user to Clerk. *** * `createdAt` * `string` A custom date/time denoting when the user signed up to the application, specified in [RFC3339 format](https://datatracker.ietf.org/doc/html/rfc3339). For example: `2012-10-20T07:15:20.902Z`.
## Usage > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.users.createUser({ firstName: 'Test', lastName: 'User', emailAddress: ['testclerk123@gmail.com'], password: 'password', }) ``` ## Example ```ts {{ filename: 'app/api/example/route.ts' }} import { auth, clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function POST() { const client = await clerkClient() const user = await client.users.createUser({ emailAddress: ['test@example.com'], password: 'password', }) return NextResponse.json({ message: 'User created', user }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' import { clerkClient } from '@clerk/astro/server' export const POST: APIRoute = async (context) => { await clerkClient(context).users.createUser({ emailAddress: ['test@example.com'], password: 'password', }) return new Response(JSON.stringify({ success: true }), { status: 200 }) } ``` ```ts {{ filename: 'public.ts' }} import { getAuth, clerkClient } from '@clerk/express' app.post('/createUser', async (req, res) => { await clerkClient.users.createUser({ emailAddress: ['test@example.com'], password: 'password', }) res.status(200).json({ success: true }) }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' import { json } from 'react-router-dom' export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() const emailAddress = formData.get('emailAddress') const password = formData.get('password') await clerkClient.users.createUser({ emailAddress: [emailAddress], password: password, }) return json({ success: true }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { POST: async () => { await clerkClient().users.createUser({ emailAddress: ['test@example.com'], password: 'my-secure-password', }) return json({ success: true }) }, }, }, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/users`. See the [BAPI reference](/docs/reference/backend-api/tag/users/post/users){{ target: '_blank' }} for more information. Here's an example of making a request directly to the endpoint using cURL. Replace `YOUR_SECRET_KEY` with your Clerk Secret Key. You can find your Secret Key on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ```bash {{ filename: 'terminal' }} curl 'https://api.clerk.com/v1/users' -X POST -H 'Authorization:Bearer {{secret}}' -H 'Content-Type:application/json' -d '{ "email_address": ["test@example.com"], "password": "my-secure-password" }' ``` --- title: "`deleteUserExternalAccount()`" description: Use Clerk's JS Backend SDK to delete a user's external account by ID. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/delete-user-external-account lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/delete-user-external-account.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L421 */} Deletes a user's external account by ID. Returns a DeletedObjectResource. ```ts function deleteUserExternalAccount( params: DeleteUserExternalAccountParams, ): Promise ``` ## `DeleteUserExternalAccountParams` * `userId` * `string` The ID of the user to delete the external account for. *** * `externalAccountId` * `string` The ID of the external account to delete. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const externalAccountId = 'external_account_123' const response = await clerkClient.users.deleteUserExternalAccount({ userId, externalAccountId, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/users/{user_id}/external_accounts/{external_account_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/users/delete/users/%7Buser_id%7D/external_accounts/%7Bexternal_account_id%7D){{ target: '_blank' }} for more information. --- title: "`deleteUserBackupCodes()`" description: Use Clerk's JS Backend SDK to delete all of a user's backup codes. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/delete-user-backup-codes lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/delete-user-backup-codes.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L430 */} Deletes all of a user's backup codes. ```ts function deleteUserBackupCodes(userId: string): Promise ``` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.deleteUserBackupCodes(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/users/{user_id}/backup_code`. See the [BAPI reference](/docs/reference/backend-api/tag/users/delete/users/%7Buser_id%7D/backup_code){{ target: '_blank' }} for more information. --- title: "`deleteUserProfileImage()`" description: Use Clerk's JS Backend SDK to delete a user's profile image. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/delete-user-profile-image lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/delete-user-profile-image.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L158 */} Deletes a user's profile image. Returns a [`User`](/docs/reference/backend/types/backend-user) object. ```ts function deleteUserProfileImage(userId: string): Promise ``` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). > \[!WARNING] > Using JS Backend SDK methods can contribute towards rate limiting. To remove a user's profile image, it's recommended to use the frontend user.setProfileImage(\{ file: null }) method instead. ```tsx const userId = 'user_123' const response = await clerkClient.users.deleteUserProfileImage(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/users/{user_id}/profile_image`. See the [BAPI reference](/docs/reference/backend-api/tag/users/delete/users/\{user_id}/profile_image){{ target: '_blank' }} for more information. --- title: "`deleteUserTOTP()`" description: Use Clerk's JS Backend SDK to delete all of a user's TOTPs. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/delete-user-totp lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/delete-user-totp.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L438 */} Deletes all of a user's TOTPs. ```ts function deleteUserTOTP(userId: string): Promise ``` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.deleteUserTOTP(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/users/{user_id}/totp`. See the [BAPI reference](/docs/reference/backend-api/tag/users/delete/users/%7Buser_id%7D/totp){{ target: '_blank' }} for more information. --- title: "`deleteUserWeb3Wallet()`" description: Use Clerk's JS Backend SDK to delete the Web3 wallet identification for a given user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/delete-user-web3-wallet lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/delete-user-web3-wallet.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L412 */} Deletes the Web3 wallet identification for a given user. Returns a DeletedObjectResource. ```ts function deleteUserWeb3Wallet(params: DeleteWeb3WalletParams): Promise ``` ## `DeleteWeb3WalletParams` * `userId` * `string` The ID of the user that owns the Web3 wallet identity. *** * `web3WalletIdentificationId` * `string` The ID of the Web3 wallet identity to be deleted. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const web3WalletIdentificationId = 'web3_wallet_identification_123' const response = await clerkClient.users.deleteUserWeb3Wallet({ userId, web3WalletIdentificationId, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/users/{user_id}/web3_wallets/{web3_wallet_identification_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/users/delete/users/%7Buser_id%7D/web3_wallets/%7Bweb3_wallet_identification_id%7D){{ target: '_blank' }} for more information. --- title: "`deleteUser()`" description: Use Clerk's JS Backend SDK to delete a user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/delete-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/delete-user.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L171 */} Deletes a [`User`](/docs/reference/backend/types/backend-user) given a valid ID. ```ts function deleteUser(userId: string): Promise ``` ## Parameters * `userId` * `string` The ID of the user to delete. ## Usage > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.deleteUser(userId) ``` ## Example ```ts {{ filename: 'app/api/example/route.ts' }} import { clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function POST() { await clerkClient.users.deleteUser('user_123') return NextResponse.json({ success: true }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' import { clerkClient } from '@clerk/astro/server' export const POST: APIRoute = async (context) => { await clerkClient(context).users.deleteUser('user_123') return new Response(JSON.stringify({ success: true }), { status: 200 }) } ``` ```ts {{ filename: 'public.ts' }} import { clerkClient } from '@clerk/express' app.post('/deleteUser', async (req, res) => { await clerkClient.users.deleteUser('user_123') res.status(200).json({ success: true }) }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' import { json, redirect } from 'react-router-dom' export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() const userId = formData.get('userId') await clerkClient.users.deleteUser(userId) return json({ success: true }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { auth, clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { POST: async () => { await clerkClient().users.deleteUser('user_123') return json({ success: true }) }, }, }, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/users/{user_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/users/delete/users/\{user_id}){{ target: '_blank' }} for more information. Here's an example of making a request directly to the endpoint using cURL. Replace `YOUR_SECRET_KEY` with your Clerk Secret Key. You can find your Secret Key on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ```bash {{ filename: 'terminal' }} curl 'https://api.clerk.com/v1/users/{user_id}' -X DELETE -H 'Authorization:Bearer {{secret}}' -H 'Content-Type:application/json' ``` --- title: "`getCount()`" description: Use Clerk's JS Backend SDK to retrieve the total number of users. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/get-count lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/get-count.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L189 */} Retrieves the total number of users. ```ts function getCount(params: UserCountParams): Promise ``` ## `UserCountParams` The total count of users can be filtered down by adding one or more of these parameters. * `emailAddress?` * `string[]` Counts users with emails that match the given query, via case-insensitive partial match. For example, `hello` will match a user with the email `hello@example.com`. *** * `phoneNumber?` * `string[]` Counts users with phone numbers that match the given query, via case-insensitive partial match. For example, `555` will match a user with the phone number `+1555xxxxxxx`. *** * `externalId?` * `string[]` Counts users with the specified external IDs. *** * `username?` * `string[]` Counts users with the specified usernames. *** * `web3wallet?` * `string[]` Counts users with the specified Web3 wallet addresses. *** * `userId?` * `string` Counts users with the user IDs specified. *** * `query?` * `string` Counts users that match the given query. For possible matches, Clerk checks the email addresses, phone numbers, usernames, Web3 wallet addresses, user IDs, first and last names. The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. ## Examples > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ### Basic ```tsx const response = await clerkClient.users.getCount() ``` ### Filter by query The following example retrieves the total number of users matching the query `test`. ```tsx const response = await clerkClient.users.getCount({ query: 'test' }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/users/count`. See the [BAPI reference](/docs/reference/backend-api/tag/users/get/users/count){{ target: '_blank' }} for more information. --- title: "`disableUserMFA()`" description: Use Clerk's JS Backend SDK to disable all of a user's MFA methods at once. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/disable-user-mfa lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/disable-user-mfa.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L206 */} Disable all of a user's MFA methods (e.g. OTP sent via SMS, TOTP on their authenticator app) at once. ```ts function disableUserMFA(userId: string): Promise ``` ## Parameters * `userId` * `string` The ID of the user to disable MFA for. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.disableUserMFA(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `DELETE/users/{user_id}/mfa`. See the [BAPI reference](/docs/reference/backend-api/tag/users/delete/users/\{user_id}/mfa){{ target: '_blank' }} for more information. --- title: "`getOrganizationInvitationList()`" description: Use Clerk's JS Backend SDK to retrieve a list of Organization invitations for a given user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/get-organization-invitation-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/get-organization-invitation-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L330 */} Retrieves a list of Organization invitations for a given user. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`OrganizationInvitation`](/docs/reference/backend/types/backend-organization-invitation) objects, and a `totalCount` property that indicates the total number of Organization invitations in the system for the specified Organization. ```ts function getOrganizationInvitationList( params: GetOrganizationInvitationListParams, ): Promise> ``` ## `GetOrganizationInvitationListParams` * `userId` * `string` The ID of the user to retrieve the list of Organization invitations for. *** * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. *** * `status?` * `string[]` The status of the invitation. Possible values: `pending`, `accepted`, `revoked`, `expired`. Defaults to `pending`. ## Examples ### Basic > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.getOrganizationInvitationList({ userId }) ``` ### Filter by invitation status Retrieves a list of a user's Organization invitations that is filtered by the status of the invitation. ```tsx const userId = 'user_123' const { data, totalCount } = await clerkClient.users.getOrganizationInvitationList({ userId, // returns a list of invitations that have not yet been accepted status: ['pending'], }) ``` ### Limit the number of results Retrieves a list of a user's Organization invitations that is filtered by the number of results. ```tsx const userId = 'user_123' const { data, totalCount } = await clerkClient.users.getOrganizationInvitationList({ userId, // returns the first 10 invitations limit: 10, }) ``` ### Skip results Retrieves a list of a user's Organization invitations that is filtered by the number of results to skip. ```tsx const userId = 'user_123' const { data, totalCount } = await clerkClient.users.getOrganizationInvitationList({ userId, // skips the first 10 invitations offset: 10, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/users/{user_id}/organization_invitations`. See the [BAPI reference](/docs/reference/backend-api/tag/users/get/users/%7Buser_id%7D/organization_invitations){{ target: '_blank' }} for more information. --- title: "`getOrganizationMembershipList()`" description: Use Clerk's JS Backend SDK to retrieve a list of Organization memberships for a given user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/get-organization-membership-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/get-organization-membership-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L214 */} Retrieves a list of Organization memberships for a given user. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`OrganizationMembership`](/docs/reference/backend/types/backend-organization-membership) objects, and a `totalCount` property that indicates the total number of Organization memberships in the system for the specified Organization. ```ts function getOrganizationMembershipList( params: GetOrganizationMembershipListParams, ): Promise> ``` ## `GetOrganizationMembershipListParams` * `userId` * `string` The ID of the user to retrieve the list of Organization memberships for. *** * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. ## Examples > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.getOrganizationMembershipList({ userId }) ``` ### Limit the number of results Retrieves a list of a user's Organization memberships that is filtered by the number of results. ```tsx const userId = 'user_123' const { data, totalCount } = await clerkClient.users.getOrganizationMembershipList({ userId, // returns the first 10 memberships limit: 10, }) ``` ### Skip results Retrieves a list of a user's Organization memberships that is filtered by the number of results to skip. ```tsx const userId = 'user_123' const { data, totalCount } = await clerkClient.users.getOrganizationMembershipList({ userId, // skips the first 10 memberships offset: 10, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/users/{user_id}/organization_memberships`. See the [BAPI reference](/docs/reference/backend-api/tag/users/get/users/\{user_id}/organization_memberships){{ target: '_blank' }} for more information. --- title: "`getUserList()`" description: Use Clerk's JS Backend SDK to retrieve a list of users. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/get-user-list lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/get-user-list.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L116 */} Retrieves a list of users. Returns a [`PaginatedResourceResponse`](/docs/reference/backend/types/paginated-resource-response) object with a `data` property that contains an array of [`User`](/docs/reference/backend/types/backend-user) objects, and a `totalCount` property that indicates the total number of users for the application. ```tsx function getUserList(): (params: UserListParams) => Promise> ``` ## `UserListParams` * `limit?` * `number` The number of results to return. Must be an integer greater than zero and less than 501. Can be used for paginating the results together with `offset`. Defaults to `10`. *** * `offset?` * `number` Skip the first `offset` results when paginating. Needs to be an integer greater or equal to zero. To be used in conjunction with `limit`. Defaults to `0`. *** * `orderBy?` * `'created_at' | 'updated_at' | 'email_address' | 'web3wallet' | 'first_name' | 'last_name' | 'phone_number' | 'username' | 'last_active_at' | 'last_sign_in_at'` Return users in a particular order. Prefix with a `-` to reverse the order. Prefix with a `+` to list in ascending order. Defaults to `'-created_at'`. *** * `emailAddress?` * `string[]` Filters users with the specified email addresses. Accepts up to 100 email addresses. Any email addresses not found are ignored. *** * `phoneNumber?` * `string[]` Filters users with the specified phone numbers. Accepts up to 100 phone numbers. Any phone numbers not found are ignored. *** * `externalId?` * `string[]` Filters users with the specified external IDs. For each external ID, the `+` and `-` can be prepended to the ID, which denote whether the respective external ID should be included or excluded from the result set. Accepts up to 100 external IDs. Any external IDs not found are ignored. *** * `username?` * `string[]` Filters users with the specified usernames. Accepts up to 100 usernames. Any usernames not found are ignored. *** * `web3Wallet?` * `string[]` Filters users with the specified Web3 wallet addresses. Accepts up to 100 Web3 wallet addresses. Any Web3 wallet addressed not found are ignored. *** * `userId?` * `string[]` Filters users with the user IDs specified. For each user ID, the `+` and `-` can be prepended to the ID, which denote whether the respective user ID should be included or excluded from the result set. Accepts up to 100 user IDs. Any user IDs not found are ignored. *** * `organizationId?` * `string[]` Filters users that have memberships to the given Organizations. For each Organization ID, the `+` and `-` can be prepended to the ID, which denote whether the respective Organization should be included or excluded from the result set. Accepts up to 100 Organization IDs. *** * `query?` * `string` Filters users that match the given query. For possible matches, we check the email addresses, phone numbers, usernames, Web3 wallet addresses, user IDs, first and last names. The query value doesn't need to match the exact value you are looking for, it is capable of partial matches as well. *** * `last_active_at_since` * `number` Filters users that had session activity since the given date, with day precision. Providing a value with higher precision than day will result in an error. Example: use `1700690400000` to retrieve users that had session activity from 2023-11-23 until the current day. For example: `1700690400000`. ## Examples ### Basic > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const response = await clerkClient.users.getUserList() ``` ### Limit the number of results Retrieves user list that is ordered and filtered by the number of results. ```tsx const { data, totalCount } = await clerkClient.users.getUserList({ orderBy: '-created_at', limit: 10, }) ``` ### Filter by email addresses and phone numbers Retrieves user list that is filtered by the given email addresses and phone numbers. ```tsx const emailAddress = ['email1@clerk.dev', 'email2@clerk.dev'] const phoneNumber = ['+12025550108'] // If these filters are included, the response will contain only users that own any of these emails and/or phone numbers. const { data, totalCount } = await clerkClient.users.getUserList({ emailAddress, phoneNumber }) ``` ### Filter by query To do a broader match through a list of fields, you can use the query parameter which partially matches the fields: `userId`, `emailAddress`, `phoneNumber`, `username`, `web3Wallet`, `firstName` and `lastName`. ```tsx // Matches users with the string `test` matched in multiple user attributes. const { data, totalCount } = await clerkClient.users.getUserList({ query: 'test', }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/users`. See the [BAPI reference](/docs/reference/backend-api/tag/users/get/users){{ target: '_blank' }} for more information. --- title: "`getUser()`" description: Use Clerk's JS Backend SDK to retrieve a single user by their ID. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/get-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/get-user.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L132 */} Retrieves a single [`User`](/docs/reference/backend/types/backend-user) by their ID, if the ID is valid. ```ts function getUser(userId: string): Promise ``` ## Parameters * `userId` * `string` The ID of the user to retrieve. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.getUser(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/users/{user_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/users/get/users/\{user_id}){{ target: '_blank' }} for more information. --- title: getUserOauthAccessToken() description: Use Clerk's JS Backend SDK to retrieve the corresponding OAuth access token for a user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/get-user-oauth-access-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/get-user-oauth-access-token.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L197 */} Retrieve the corresponding OAuth access token for a user that has previously authenticated with a particular OAuth provider. ```ts function getUserOauthAccessToken( userId: string, provider: `${OAuthProvider}`, ): Promise ``` ## Parameters * `userId` * `string` The ID of the user to retrieve the OAuth access token for. *** * `provider` * $\{OAuthProvider} The OAuth provider to retrieve the access token for. If using a custom OAuth provider, prefix the provider name with `custom_` (e.g., `custom_foo`). ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const provider = 'google' const response = await clerkClient.users.getUserOauthAccessToken(userId, provider) ``` You can also explore [the example](/docs/guides/configure/auth-strategies/social-connections/overview#get-an-o-auth-access-token-for-a-social-provider) that demonstrates how this method retrieves a social provider's OAuth access token, enabling access to user data from both the provider and Clerk. ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `GET/users/{user_id}/oauth_access_tokens/{provider}`. See the [BAPI reference](/docs/reference/backend-api/tag/users/get/users/\{user_id}/oauth_access_tokens/\{provider}){{ target: '_blank' }} for more information. --- title: "`lockUser()`" description: Use Clerk's JS Backend SDK to mark a user as locked, which means they are not allowed to sign in again until the lock expires. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/lock-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/lock-user.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L263 */} Marks the given [`User`](/docs/reference/backend/types/backend-user) as locked, which means they are not allowed to sign in again until the lock expires. By default, lockout duration is 1 hour, but it can be configured in the application's [**Attack protection**](https://dashboard.clerk.com/~/user-authentication/attack-protection) settings. For more information, see the [dedicated guide for customizing **Attack protection** settings](/docs/guides/secure/user-lockout). ```ts function lockUser(userId: string): Promise ``` ## Parameters * `userId` * `string` The ID of the user to lockout. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.lockUser(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/users/{user_id}/lock`. See the [BAPI reference](/docs/reference/backend-api/tag/users/post/users/\{user_id}/lock){{ target: '_blank' }} for more information. --- title: "`unbanUser()`" description: Use Clerk's JS Backend SDK to remove the ban mark from a user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/unban-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/unban-user.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L255 */} Removes the ban mark from the given [`User`](/docs/reference/backend/types/backend-user). ```ts function unbanUser(userId: string): Promise ``` ## Parameters * `userId` * `string` The ID of the user to unban. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.unbanUser(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/users/{user_id}/unban`. See the [BAPI reference](/docs/reference/backend-api/tag/users/post/users/\{user_id}/unban){{ target: '_blank' }} for more information. --- title: "`updateUserMetadata()`" description: Use Clerk's JS Backend SDK to update the metadata associated with the specified user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/update-user-metadata lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/update-user-metadata.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L171 */} Updates the metadata associated with the specified user by merging existing values with the provided parameters. A "deep" merge will be performed - "deep" means that any nested JSON objects will be merged as well. You can remove metadata keys at any level by setting their value to `null`. Returns a [`User`](/docs/reference/backend/types/backend-user) object. ```ts function updateUserMetadata(userId: string, params: UpdateUserMetadataParams): Promise ``` ## `UpdateUserMetadataParams` * `userId` * `string` The ID of the user to update. *** * `publicMetadata?` * UserPublicMetadata Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. *** * `privateMetadata?` * UserPrivateMetadata Metadata that can be read and set only from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. ## Usage > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.updateUserMetadata(userId, { publicMetadata: { example: 'metadata', }, }) ``` ## Example This example updates the user's public metadata to include a birthday, but you can update the public, private, or unsafe metadata to include any information you want. ```ts {{ filename: 'app/api/example/route.ts' }} import { auth, clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function POST() { const { userId } = await auth() const client = await clerkClient() await client.users.updateUserMetadata(userId, { publicMetadata: { birthday: '1990-01-01', }, }) return NextResponse.json({ success: true }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' import { clerkClient } from '@clerk/astro/server' export const POST: APIRoute = async (context) => { const { userId } = context.locals.auth() await clerkClient(context).users.updateUserMetadata(userId, { publicMetadata: { birthday: '1990-01-01', }, }) return new Response(JSON.stringify({ success: true }), { status: 200 }) } ``` ```ts {{ filename: 'public.ts' }} import { getAuth, clerkClient } from '@clerk/express' app.post('/updateBirthday', async (req, res) => { const { userId } = getAuth(req) await clerkClient.users.updateUserMetadata(userId, { publicMetadata: { birthday: '1990-01-01', }, }) res.status(200).json({ success: true }) }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/example' export async function action({ request }: Route.ActionArgs) { const { userId } = await getAuth(request) await clerkClient.users.updateUserMetadata(userId, { publicMetadata: { birthday: '1990-01-01', }, }) return json({ success: true }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { auth, clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { POST: async () => { const { userId } = await auth() await clerkClient().users.updateUserMetadata(userId, { publicMetadata: { birthday: '1990-01-01', }, }) return json({ success: true }) }, }, }, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/users/{user_id}/metadata`. See the [BAPI reference](/docs/reference/backend-api/tag/users/patch/users/\{user_id}/metadata){{ target: '_blank' }} for more information. Here's an example of making a request directly to the endpoint using cURL. Replace `YOUR_SECRET_KEY` with your Clerk Secret Key. You can find your Secret Key on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ```bash {{ filename: 'curl.sh' }} curl -XPATCH -H 'Authorization: Bearer {{secret}}' -H "Content-type: application/json" -d '{ "public_metadata": { "birthday": "1990-01-01" } }' 'https://api.clerk.com/v1/users/{user_id}/metadata' ``` --- title: "`unlockUser()`" description: Use Clerk's JS Backend SDK to remove a sign-in lock from a user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/unlock-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/unlock-user.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L271 */} Removes a sign-in lock from the given [`User`](/docs/reference/backend/types/backend-user). ```ts function unlockUser(userId: string): Promise ``` ## Parameters * `userId` * `string` The ID of the user to unlock. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const response = await clerkClient.users.unlockUser(userId) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/users/{user_id}/unlock`. See the [BAPI reference](/docs/reference/backend-api/tag/users/post/users/\{user_id}/unlock){{ target: '_blank' }} for more information. --- title: "`updateUserProfileImage()`" description: Use Clerk's JS Backend SDK to update a user's profile image. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/update-user-profile-image lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/update-user-profile-image.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L158 */} Updates a user's profile image. Returns a [`User`](/docs/reference/backend/types/backend-user) object. ```ts function updateUserProfileImage(userId: string, params: { file: Blob | File }): Promise ``` ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). > \[!WARNING] > Using JS Backend SDK methods can contribute towards rate limiting. To set a user's profile image, it's recommended to use the frontend user.setProfileImage() method instead. ```tsx const userId = 'user_123' const fileBits = ['profile-pic-content'] const fileName = 'profile-pic.png' const file = new File(fileBits, fileName, { type: 'image/png' }) const params = { file, } const response = await clerkClient.users.updateUserProfileImage(userId, params) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/users/{user_id}/profile_image`. See the [BAPI reference](/docs/reference/backend-api/tag/users/post/users/\{user_id}/profile_image){{ target: '_blank' }} for more information. --- title: "`updateUser()`" description: Use Clerk's JS Backend SDK to update a user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/update-user lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/update-user.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L148 */} Updates a [`User`](/docs/reference/backend/types/backend-user). ```ts function updateUser(userId: string, params: UpdateUserParams): Promise ``` ## `UpdateUserParams` * `userId` * `string` The ID of the user to update. *** * `externalId?` * `string` The ID of the user as used in your external systems or your previous authentication solution. Must be unique across your instance. *** * `firstName?` * `string` The user's first name. *** * `lastName?` * `string` The user's last name. *** * `primaryEmailAddressID?` * `string` The ID of the email address to set as primary. It must be verified, and present on the current user. *** * `notifyPrimaryEmailAddressChanged?` * `boolean` If set to `true`, the user will be notified that their primary email address has changed. By default, no notification is sent. Defaults to `false`. *** * `primaryPhoneNumberID?` * `string` The ID of the phone number to set as primary. It must be verified, and present on the current user. *** * `primaryWeb3WalletID?` * `string` The ID of the Web3 wallet to set as primary. It must be verified, and present on the current user. *** * `username?` * `string` The user's username. It must be unique across your instance. *** * `profileImageID?` * `string` The ID of the image to set as the user's profile image. *** * `password?` * `string` The plaintext password to give the user. Must be at least 8 characters long, and can not be in any list of hacked passwords. *** * `passwordDigest?` * `string` In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. The digests should be generated with one of the supported algorithms. The hashing algorithm can be specified using the `password_hasher` property. *** * `passwordHasher?` * `'argon2i' | 'argon2id' | 'bcrypt' | 'bcrypt_sha256_django' | 'md5' | 'pbkdf2_sha256' | 'pbkdf2_sha256_django' | 'pbkdf2_sha1' | 'phpass' | 'scrypt_firebase' | 'scrypt_werkzeug' | 'sha256'` The hashing algorithm that was used to generate the password digest. Each of the supported hashers expects the incoming digest to be in a particular format. See the [Clerk Backend API reference](/docs/reference/backend-api/tag/users/post/users){{ target: '_blank' }} for more information. *** * `skipPasswordChecks?` * `boolean` When set to `true`, all password checks are skipped. It is recommended to use this method only when migrating plaintext passwords to Clerk. Upon migration the user base should be prompted to pick stronger password. *** * `skipPasswordRequirement?` * `boolean` When set to `true`, password is not required anymore when creating the user and can be omitted. This is useful when you are trying to create a user that doesn't have a password, in an instance that is using passwords. You cannot use this flag if password is the only way for a user to sign into your instance. *** * `signOutOfOtherSessions?` * `boolean` Set to `true` to sign out the user from all their active sessions once their password is updated. Can only be used when providing the `password` parameter. *** * `totpSecret?` * `string` In case TOTP is configured on the instance, you can provide the secret to enable it on the newly created user without the need to reset it. Currently, the supported options are:
  • Period: 30 seconds
  • Code length: 6 digits
  • Algorithm: SHA1
*** * `backupCodes?` * `string[]` If backup codes are configured on the instance, you can provide them to enable it on the newly created user without the need to reset them. You must provide the backup codes in plain format or the corresponding bcrypt digest. *** * `publicMetadata?` * UserPublicMetadata Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. Updating this property will override the existing metadata. To merge metadata, use [`updateUserMetadata()`](/docs/reference/backend/user/update-user-metadata). *** * `privateMetadata?` * UserPrivateMetadata Metadata that can be read and set only from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. Updating this property will override the existing metadata. To merge metadata, use [`updateUserMetadata()`](/docs/reference/backend/user/update-user-metadata). *** * `unsafeMetadata?` * UserUnsafeMetadata Metadata that can be read and set from the Frontend API. It's considered unsafe because it can be modified from the frontend. *** * `deleteSelfEnabled?` * `boolean` If `true`, the user can delete themselves with the Frontend API. *** * `createOrganizationEnabled?` * `boolean` If `true`, the user can create Organizations with the Frontend API. *** * `createOrganizationsLimit?` * `number` An integer indicating the number of Organizations that can be created by the user. If the value is `0`, then the user can create unlimited Organizations. Default is `null`. *** * `legalAcceptedAt?` * `Date` The date when the user accepted the legal documents. `null` if [**Require express consent to legal documents**](/docs/guides/secure/legal-compliance) is not enabled. *** * `skipLegalChecks?` * `boolean` When set to `true` all legal checks are skipped. It is not recommended to skip legal checks unless you are migrating a user to Clerk. *** * `createdAt?` * `Date` A custom date/time denoting when the user signed up to the application, specified in RFC3339 format. For example: `2012-10-20T07:15:20.902Z`. *** * `skipLegalChecks?` * `boolean` When set to `true` all legal checks are skipped. It is not recommended to skip legal checks unless you are migrating a user to Clerk. *** * `legalAcceptedAt?` * `Date` A custom date/time denoting when the user accepted legal requirements, specified in RFC3339 format. For example: `2012-10-20T07:15:20.902Z`.
## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const params = { firstName: 'John', lastName: 'Wick' } const response = await clerkClient.users.updateUser(userId, params) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `PATCH/users/{user_id}`. See the [BAPI reference](/docs/reference/backend-api/tag/users/patch/users/\{user_id}){{ target: '_blank' }} for more information. --- title: "`verifyTOTP()`" description: Use Clerk's JS Backend SDK to verify a TOTP or backup code for a user. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/verify-totp lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/verify-totp.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L236 */} Verify that the provided TOTP or backup code is valid for the user. Verifying a backup code will result it in being consumed (i.e. it will become invalid). Useful for custom auth flows and re-verification. ```ts function verifyTOTP(params: VerifyTOTPParams): Promise<{ verified: true; code_type: 'totp' }> ``` ## `VerifyTOTPParams` * `userId` * `string` The ID of the user to verify the TOTP for. *** * `code` * `string` The TOTP or backup code to verify ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const code = '123456' const response = await clerkClient.users.verifyTOTP({ userId, code, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/users/{user_id}/verify_totp`. See the [BAPI reference](/docs/reference/backend-api/tag/users/post/users/\{user_id}/verify_totp){{ target: '_blank' }} for more information. --- title: "`verifyPassword()`" description: Use Clerk's JS Backend SDK to check that the user's password matches the supplied input. Useful for custom auth flows and re-verification. sdk: js-backend sdkScoped: "true" canonical: /docs/reference/backend/user/verify-password lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-backend notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby activeSdk: js-backend sourceFile: /docs/reference/backend/user/verify-password.mdx --- {/* clerk/javascript file: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/endpoints/UserApi.ts#L225 */} Check that the user's password matches the supplied input. Useful for custom auth flows and re-verification. ```ts function verifyPassword(params: VerifyPasswordParams): Promise<{ verified: true }> ``` ## `VerifyPasswordParams` * `userId` * `string` The ID of the user to verify the password for. *** * `password` * `string` The password to verify. ## Example > \[!NOTE] > Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties). ```tsx const userId = 'user_123' const password = 'testpassword123' const response = await clerkClient.users.verifyPassword({ userId, password, }) ``` ## Backend API (BAPI) endpoint This method in the SDK is a wrapper around the BAPI endpoint `POST/users/{user_id}/verify_password`. See the [BAPI reference](/docs/reference/backend-api/tag/users/post/users/\{user_id}/verify_password){{ target: '_blank' }} for more information. --- title: Ruby on Rails integration description: The Clerk Ruby SDK provides a Rack middleware and a gem to integrate Clerk into your Rails app. sdk: ruby sdkScoped: "true" canonical: /docs/reference/ruby/rails lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ruby notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,js-backend activeSdk: ruby sourceFile: /docs/reference/ruby/rails.mdx --- The Clerk Ruby SDK provides a seamless integration with Ruby on Rails through a Rack middleware and dedicated Rails helpers. When you add the Clerk gem to your Rails application, the middleware is automatically included in your application's middleware stack. ## Install `clerk-sdk-ruby` The [Clerk Ruby SDK](/docs/reference/ruby/overview) provides a range of backend utilities to simplify user authentication and management in your application. 1. Add the following code to your application's `Gemfile`. ```ruby {{ filename: 'Gemfile' }} gem 'clerk-sdk-ruby', require: "clerk" ``` 2. Run the following command to install the SDK: ```sh {{ filename: 'terminal' }} $ bundle install ``` ## Configuration The configuration object provides a flexible way to configure the SDK. When a configuration value is not explicitly provided, it will fall back to checking the corresponding [environment variable](/docs/reference/ruby/overview#available-environment-variables). You must provide your Clerk Secret Key, which can be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The following example shows how to set up your configuration object: ```ruby Clerk.configure do |c| c.secret_key = `{{secret}}` # if omitted: ENV["CLERK_SECRET_KEY"] - API calls will fail if unset c.logger = Logger.new(STDOUT) # if omitted, no logging end ``` For more information, see [Faraday's documentation](https://lostisland.github.io/faraday/#/). ## Example: Access the `clerk` object To access Clerk's authentication functionality in your controllers, include the `Clerk::Authenticatable` concern. This gives your controller and views access to the `clerk` helper, which provides access to the current session claims such as `clerk.user` and `clerk.organization`. ```ruby {{ filename: 'app/controllers/application_controller.rb' }} class ApplicationController < ActionController::Base include Clerk::Authenticatable private # If the user is not authenticated, redirect to the sign-in page def require_clerk_session! # The `CLERK_SIGN_IN_URL` env var must be set or the `sign_in_url` method will fail redirect_to clerk.sign_in_url unless clerk.session end end ``` ## Example: Protect routes To protect specific controllers or actions, you can add a `before_action` callback that uses the `require_clerk_session!` method to check for an authenticated Clerk session. This is particularly useful for securing admin sections or sensitive operations. ```ruby class AdminController < ApplicationController # Protect routes with the `require_clerk_session!` method before_action :require_clerk_session! def index # ... end end ``` ## Example: Reverification For actions requiring additional security, Clerk provides a `:require_reverification!` filter that prompts users to re-authenticate. This filter accepts an optional [preset](/docs/reference/ruby/overview#reverification) parameter to customize the reverification requirements. In the following example, all actions in the `AdminController` will be protected from unauthenticated users. If the user is authenticated, they will be required to reverify their session before accessing the `destroy` action. ```ruby class AdminController < ApplicationController # Protect routes with the `require_clerk_session!` method before_action :require_clerk_session! # Protect `destroy` with the `require_reverification!` method # Reverification preset is set to `LAX` before_action :require_reverification!, only: :destroy, preset: Clerk::StepUp::Preset::LAX def index # ... end def destroy # ... end end ``` --- title: Clerk Ruby SDK description: The Clerk Ruby SDK provides a range of backend utilities to simplify user authentication and management in your application. sdk: ruby sdkScoped: "true" canonical: /docs/reference/ruby/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: ruby notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,js-backend activeSdk: ruby sourceFile: /docs/reference/ruby/overview.mdx --- The Clerk Ruby SDK provides a powerful set of tools and utilities to seamlessly integrate authentication, user management, and Organization management into your Ruby application. To get started, refer to the appropriate guide: * [Vanilla Ruby](/docs/ruby/getting-started/quickstart) * [Rails](/docs/reference/ruby/rails) * [Rack](/docs/reference/ruby/rack) * [Sinatra](/docs/reference/ruby/sinatra) ## Available environment variables The Ruby SDK supports the following environment variables: | Variable name | Usage | | - | - | | `CLERK_SECRET_KEY` | The Secret Key of your instance **(required)** | | `CLERK_API_BASE` | Overrides the default API base URL: `https://api.clerk.com/v1/` | | `CLERK_SIGN_IN_URL` | Rails view helper: `clerk_sign_in_url` | | `CLERK_SIGN_IN_UP` | Rails view helper: `clerk_sign_up_url` | | `CLERK_USER_PROFILE_URL` | Rails view helper: `clerk_user_profile_url` | ## Available methods All available methods are listed in the [Ruby HTTP Client documentation](https://github.com/clerk/clerk-http-client-ruby/tree/main/.generated#documentation-for-api-endpoints){{ target: '_blank' }}. The Ruby HTTP Client is a generated wrapper around the [Backend API](/docs/reference/backend-api){{ target: '_blank' }} that provides a more Ruby-friendly interface. ### Reverification The reverification feature provides an additional layer of security by requiring users to reverify their session before accessing sensitive routes. By default, it is set to `STRICT`, but accepts the following presets: * `Clerk::StepUp::Preset::LAX`: Authenticated within the past day, requiring the second factor * `Clerk::StepUp::Preset::MODERATE`: Authenticated within the past hour, requiring the second factor * `Clerk::StepUp::Preset::STRICT`: Authenticated within the past 10 minutes, requiring the second factor * `Clerk::StepUp::Preset::STRICT_MFA`: Authenticated within the past 10 minutes, requiring both first and second factors --- title: Ruby with Rack description: The Clerk Ruby SDK provides a Rack middleware to integrate Clerk into your Rack-based application. sdk: ruby sdkScoped: "true" canonical: /docs/reference/ruby/rack lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ruby notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,js-backend activeSdk: ruby sourceFile: /docs/reference/ruby/rack.mdx --- The Clerk Ruby SDK provides a Rack middleware to integrate Clerk into your Rack-based application. ## Install `clerk-sdk-ruby` The [Clerk Ruby SDK](/docs/reference/ruby/overview) provides a range of backend utilities to simplify user authentication and management in your application. 1. Add the following code to your application's `Gemfile`. ```ruby {{ filename: 'Gemfile' }} gem 'clerk-sdk-ruby', require: "clerk" ``` 2. Run the following command to install the SDK: ```sh {{ filename: 'terminal' }} $ bundle install ``` ## Configuration The configuration object provides a flexible way to configure the SDK. When a configuration value is not explicitly provided, it will fall back to checking the corresponding [environment variable](/docs/reference/ruby/overview#available-environment-variables). You must provide your Clerk Secret Key, which can be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The following example shows how to set up your configuration object: ```ruby Clerk.configure do |c| c.secret_key = `{{secret}}` # if omitted: ENV["CLERK_SECRET_KEY"] - API calls will fail if unset c.logger = Logger.new(STDOUT) # if omitted, no logging end ``` For more information, see [Faraday's documentation](https://lostisland.github.io/faraday/#/). ## Add Clerk's Rack middleware Add the Clerk middleware to your Rack application by updating your `config.ru` file with the following code: ```ruby {{ filename: 'config.ru' }} require "rack" require "clerk/rack" require_relative "app" use Clerk::Rack::Middleware run App.new ``` ## Access the `clerk` object Once you've added the middleware, you can access the `clerk` object in your actions and views. The `clerk` object provides access to the [Ruby SDK's available methods](/docs/reference/ruby/overview#available-methods). The following example demonstrates a simple Rack application that protects all routes. If the user is authenticated, it returns the user's first name and ID. If the user is not authenticated, it returns a `401` status code. ```ruby {{ filename: 'app.rb' }} require "erb" require "clerk" class App def call(env) clerk = env["clerk"] # Check if the user is authenticated user = clerk.user user ? [200, {"Content-Type" => "text/plain"}, ["Authenticated User: #{user.first_name} (#{user.id})"]]: [401, {"Content-Type" => "text/plain"}, ["Not Authenticated"]] end end ``` ## Example: Reverification The reverification feature provides an additional layer of security by requiring users to reverify their session before accessing sensitive routes. There are two ways to handle reverification in a Rack application: 1. [In your middleware](#in-your-middleware) 2. [In your application logic](#in-your-application-logic) ### In your middleware To handle reverification in your Rack middleware, use the `Clerk::Rack::Reverification` middleware. It accepts an optional [preset](/docs/reference/ruby/overview#reverification) parameter to customize the reverification requirements and an optional `routes` parameter to specify which routes should be protected. In the following example, the reverification preset is set to `LAX` and reverification is required for all routes that match the `/*` pattern. ```ruby {{ filename: 'config.ru' }} require "rack" require "clerk/rack" require_relative "app" use Clerk::Rack::Middleware # Reverification preset is set to `LAX` use Clerk::Rack::Reverification, preset: Clerk::StepUp::Preset::LAX, routes: ["/*"] run App.new ``` ### In your application logic To handle reverification in your app logic, * Use the `clerk.user_needs_reverification?` method to check if the user needs to reverify their session, which accepts an optional [preset](/docs/reference/ruby/overview#reverification) parameter to customize the reverification requirements. * Use the `clerk.user_reverification_rack_response` method to get the response. The following example demonstrates a simple Rack application that requires authentication and reverification for all routes. ```ruby {{ filename: 'app.rb' }} require "erb" require "clerk" STEP_UP_PRESET = Clerk::StepUp::Preset::LAX class App def call(env) clerk = env["clerk"] # Check if the user needs to reverify their session if clerk.user_needs_reverification?(STEP_UP_PRESET) # Get the response return clerk.user_reverification_rack_response(STEP_UP_PRESET) end # Check if the user is authenticated user = clerk.user user ? [200, {"Content-Type" => "text/plain"}, ["Authenticated User: #{user.first_name} (#{user.id})"]]: [401, {"Content-Type" => "text/plain"}, ["Not Authenticated"]] end end ``` --- title: Sinatra integration description: The Clerk Ruby SDK provides a Sinatra extension to integrate Clerk into your Sinatra app. sdk: ruby sdkScoped: "true" canonical: /docs/reference/ruby/sinatra lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: ruby notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,js-backend activeSdk: ruby sourceFile: /docs/reference/ruby/sinatra.mdx --- The Clerk Ruby SDK provides a seamless integration with Sinatra through a dedicated extension that gives you access to authentication, user management, and Organization management features. ## Install `clerk-sdk-ruby` The [Clerk Ruby SDK](/docs/reference/ruby/overview) provides a range of backend utilities to simplify user authentication and management in your application. 1. Add the following code to your application's `Gemfile`. ```ruby {{ filename: 'Gemfile' }} gem 'clerk-sdk-ruby', require: "clerk" ``` 2. Run the following command to install the SDK: ```sh {{ filename: 'terminal' }} $ bundle install ``` ## Configuration The configuration object provides a flexible way to configure the SDK. When a configuration value is not explicitly provided, it will fall back to checking the corresponding [environment variable](/docs/reference/ruby/overview#available-environment-variables). You must provide your Clerk Secret Key, which can be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The following example shows how to set up your configuration object: ```ruby Clerk.configure do |c| c.secret_key = `{{secret}}` # if omitted: ENV["CLERK_SECRET_KEY"] - API calls will fail if unset c.logger = Logger.new(STDOUT) # if omitted, no logging end ``` For more information, see [Faraday's documentation](https://lostisland.github.io/faraday/#/). ## Add Clerk's Sinatra extension The `clerk` object provides access to the [Ruby SDK's available methods](/docs/reference/ruby/overview#available-methods). To get access to the `clerk` object, you must `register` the `Sinatra::Clerk` extension. The following example demonstrates how to register the `Sinatra::Clerk` extension and access the user's [`User`](https://github.com/clerk/clerk-http-client-ruby/blob/main/.generated/docs/User.md) object. ```ruby {{ filename: 'app.rb' }} require "clerk/sinatra" require "sinatra/base" class App < Sinatra::Base register Sinatra::Clerk # Access the user's `User` object get "/" do @user = clerk.user erb :index, format: :html5 end run! if app_file == $0 end ``` ## Example: Protect routes The `auth` filter can be added to any route to protect it from unauthenticated users. If a user is not authenticated, by default, `auth` will redirect them to the sign-in page. ```ruby require "clerk/sinatra" require "sinatra/base" class App < Sinatra::Base register Sinatra::Clerk get "/" do erb :index, format: :html5 end # Protect the "/admin" route with the `auth` filter # If the user is not authenticated, they will be redirected to the sign-in page get "/admin", auth: true do @user = clerk.user erb :admin, format: :html5 end run! if app_file == $0 end ``` ### Override the default behavior of the `auth` filter By default, the `auth` filter will redirect to the sign-in page if the user is not authenticated. You can override this behavior by using `set(:auth)`. In the following example, the `auth` filter is overridden to redirect to the homepage if the user is not authenticated. ```ruby {{ filename: 'app.rb' }} require "clerk/sinatra" require "sinatra/base" class App < Sinatra::Base register Sinatra::Clerk # Set `auth` to perform custom behavior set(:auth) do |active| condition do # If the user is not authenticated, redirect to the homepage if active && !clerk.session puts "User is not authenticated, redirecting to the homepage" redirect '/' end end end get "/" do erb :index, format: :html5 end # Protect the "/admin" route with the `auth` filter # which will perform the custom behavior set in `set(:auth)` get "/admin", auth: true do @user = clerk.user erb :admin, format: :html5 end run! if app_file == $0 end ``` ## Example: Reverification For actions requiring additional security, Clerk provides a `reverify` filter that prompts users to re-authenticate. This filter accepts an optional [preset](/docs/reference/ruby/overview#reverification) parameter to customize the reverification requirements. In the following example, the `/super-secret-admin` or `/chill-admin` routes will be protected from unauthenticated users. If the user is authenticated, they will be required to reverify their session, depending on when they last verified their session. ```ruby require "clerk/sinatra" require "sinatra/base" class App < Sinatra::Base register Sinatra::Clerk get "/" do erb :index, format: :html5 end # Protect the "/super-secret-admin" route with the `auth` and `reverify` filters # Reverification preset defaults to `STRICT` post "/super-secret-admin", auth: true, reverify: true do {message: clerk.user? ? "Valid session" : "Not logged in"}.to_json end # Protect the "/chill-admin" route with the `auth` and `reverify` filters # Reverification preset is set to `LAX` post "/chill-admin", auth: true, reverify: Clerk::StepUp::Preset::LAX do {message: clerk.user? ? "Valid session" : "Not logged in"}.to_json end run! if app_file == $0 end ``` --- title: Upgrade to `clerk-sdk-ruby` v4 description: Learn how to upgrade your application to use Clerk Ruby SDK v4. sdk: ruby sdkScoped: "true" canonical: /docs/reference/ruby/v4-upgrade-guide lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ruby notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,js-backend activeSdk: ruby sourceFile: /docs/reference/ruby/v4-upgrade-guide.mdx --- In January 2025, version 4.0 of the Clerk Ruby SDK was released. This guide covers the breaking changes that were introduced. ## `Clerk.configure` updates Previously, `Clerk.configure` accepted `api_key` as a parameter. Now, it accepts `secret_key` instead. ```ruby {{ del: [4], ins: [5] }} require 'clerk' Clerk.configure do |c| c.api_key = `{{secret}}` c.secret_key = `{{secret}}` end ``` ## `middleware_cache_store` updates Previously, if Rails was detected, the `middleware_cache_store` was set to `Rails.cache`. Otherwise, it was set to `nil`. Now, if Rails is not detected, the `middleware_cache_store` attempts to use `ActiveSupport::Cache::MemoryStore` before defaulting to `nil`. ## Available methods updates With the introduction of our generated Ruby HTTP Client, the `Clerk::SDK` class methods have all been overhauled to align with the [Clerk OpenAPI specification](https://github.com/clerk/openapi-specs){{ target: '_blank' }}. Refer to the [Ruby HTTP Client documentation](https://github.com/clerk/clerk-http-client-ruby/tree/main/.generated#documentation-for-api-endpoints){{ target: '_blank' }} for more information on what methods are available via the `Clerk::SDK` class or the `clerk.sdk` helper method. --- title: "`updateClerkOptions()`" description: The `updateClerkOptions()` function allows you to update Clerk's options at runtime. sdk: vue sdkScoped: "true" canonical: /docs/reference/vue/update-clerk-options lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: vue notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/vue/update-clerk-options.mdx --- The `updateClerkOptions()` function is used to update Clerk's options at runtime. It can be called at any time after [Clerk has been initialized](/docs/reference/vue/clerk-plugin). ## Usage ```vue ``` ## Properties * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `localization` * [Localization](/docs/guides/customizing-clerk/localization) | undefined Optional object to localize your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. [components-ref]: /docs/reference/components/overview [ap-ref]: /docs/guides/customizing-clerk/account-portal --- title: Clerk Vue SDK description: The Clerk Vue SDK gives you access to prebuilt components, composables, and helpers to make user authentication easier. sdk: vue sdkScoped: "true" canonical: /docs/reference/vue/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: vue notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/vue/overview.mdx --- The Clerk Vue SDK gives you access to prebuilt components, composables, and helpers to make user authentication easier. Refer to the [quickstart guide](/docs/vue/getting-started/quickstart) to get started. ## `clerkPlugin` To configure Clerk with Vue, you must initialize `clerkPlugin`. See the [quickstart](/docs/vue/getting-started/quickstart#add-clerk-plugin-to-your-app) for more information. ## `updateClerkOptions()` The `updateClerkOptions()` function is used to update Clerk's options at runtime. It can be called at any time after [Clerk has been initialized](/docs/reference/vue/clerk-plugin). See the [reference documentation](/docs/reference/vue/update-clerk-options) for more information. ## Custom composables The Vue SDK provides access to custom composables that include access to the Clerk object, User object, Organization object, and a set of useful helper methods for signing in and signing up. * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() ## Framework-specific SDKs > \[!IMPORTANT] > If you're building a standard Vue application (client-side only), use `@clerk/vue`. If you're using Nuxt, use the dedicated `@clerk/nuxt` package which includes backend integration. Clerk offers framework-specific SDKs that are customized to provide the better developer experience and integration with each framework's features. Choose the appropriate SDK based on your framework: | Framework | Package | Docs | | - | - | - | | Nuxt | `@clerk/nuxt` | Nuxt SDK | --- title: "`clerkPlugin`" description: The `clerkPlugin` provides session and user context to Clerk's composables and components. sdk: vue sdkScoped: "true" canonical: /docs/reference/vue/clerk-plugin lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: vue notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,ruby,js-backend activeSdk: vue sourceFile: /docs/reference/vue/clerk-plugin.mdx --- The `clerkPlugin` is required to integrate Clerk into your Vue application, providing session and user context to Clerk's composables and components. ## Usage To configure Clerk with Vue, you must initialize `clerkPlugin`. It's required to pass your Clerk Publishable Key as an option. You can add an `if` statement to check that the key is imported properly. This prevents the app from running without the Publishable Key and catches TypeScript errors. The `clerkPlugin` accepts optional options, such as `{ signInForceRedirectUrl: '/dashboard' }`. See the [properties section](#properties) for more information. ```ts {{ filename: 'src/main.ts' }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Add your Clerk Publishable Key to the .env.local file') } const app = createApp(App) // clerkPlugin requires your Clerk Publishable Key // It can accept other options, such as { signInForceRedirectUrl: '/dashboard' } app.use(clerkPlugin, { publishableKey: PUBLISHABLE_KEY }) app.mount('#app') ``` To update Clerk options at runtime, use the [`updateClerkOptions()`](/docs/reference/vue/update-clerk-options) function. ## Properties | Property | Type | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`afterMultiSessionSingleSignOutUrl?` | null \| string | The full URL or path to navigate to after signing out the current user is complete. This option applies to [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). | | ~~`afterSignInUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl` or `signInForceRedirectUrl` instead. | | `afterSignOutUrl?` | null \| string | Full URL or path to navigate to after successful sign out. | | ~~`afterSignUpUrl?`~~ | null \| string | **Deprecated.** Use `signUpFallbackRedirectUrl` or `signUpForceRedirectUrl` instead. | | `allowedRedirectOrigins?` | (string \| RegExp)\[] | An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `allowedRedirectProtocols?` | string\[] | An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `appearance?` | [`Appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) | Optional object to style your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `clerkJSUrl?` | `string` | The URL that `@clerk/clerk-js` should be hot-loaded from. | | `clerkJSVariant?` | "" \| "headless" | If your web application only uses Control Components, you can set this value to `'headless'` and load a minimal ClerkJS bundle for optimal page performance. | | `clerkJSVersion?` | `string` | The npm version for `@clerk/clerk-js`. | | `domain?` | string \| (url: URL) => string | **Required if your application is a satellite application**. Sets the domain of the satellite application. | | `experimental?` | `Autocomplete`\<\{ commerce: boolean; persistClient: boolean; rethrowOfflineNetworkErrors: boolean; \}, `Record`\<`string`, `any`\>\> | Enable experimental flags to gain access to new features. These flags are not guaranteed to be stable and may change drastically in between patch or minor versions. | | `initialState?` | `Serializable`\<\{ actor: undefined \| \{ \[x: string]: unknown; sub: string; \}; factorVerificationAge: \[number, number]; organization: undefined \| OrganizationResource; orgId: undefined \| string; orgPermissions: undefined \| string\[]; orgRole: undefined \| string; orgSlug: undefined \| string; session: undefined \| SessionResource; sessionClaims: JwtPayload; sessionId: undefined \| string; sessionStatus: SessionStatusClaim; user: undefined \| UserResource; userId: undefined \| string; \}\> | Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `isSatellite?` | boolean \| (url: URL) => boolean | A boolean that indicates whether the application is a satellite application. | | `localization?` | [`LocalizationResource`](/docs/guides/customizing-clerk/localization) | Optional object to localize your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `newSubscriptionRedirectUrl?` | null \| string | The URL to navigate to after the user completes the checkout and clicks the "Continue" button. | | `nonce?` | `string` | This nonce value will be passed through to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. | | `proxyUrl?` | string \| (url: URL) => string \| (url: URL) => string | **Required for applications that run behind a reverse proxy**. The URL that Clerk will proxy requests to. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). | | `publishableKey` | `string` | The Clerk Publishable 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. | | ~~`redirectUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl`, `signInForceRedirectUrl`, `signUpFallbackRedirectUrl`, or `signUpForceRedirectUrl` instead. | | `routerPush?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "push" navigation. | | `routerReplace?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "replace" navigation. | | `sdkMetadata?` | \{ environment?: string; name: string; version: string; \} | Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `sdkMetadata.environment?` | `string` | Typically this will be the `NODE_ENV` that the SDK is currently running in. | | `sdkMetadata.name` | `string` | The npm package name of the SDK. | | `sdkMetadata.version` | `string` | The npm package version of the SDK. | | `selectInitialSession?` | (client: ClientResource) => null \| SignedInSessionResource | By default, the last signed-in session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. | | `signInFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signInForceRedirectUrl?` | null \| string | 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. | | `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. | | `signUpFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signUpForceRedirectUrl?` | null \| string | 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. | | `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. | | `standardBrowser?` | `boolean` | By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. | | `supportEmail?` | `string` | Optional support email for display in authentication screens. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `taskUrls?` | `Record`\<`"choose-organization"`, `string`\> | Customize the URL paths users are redirected to after sign-in or sign-up when specific session tasks need to be completed. When `undefined`, it uses Clerk's default task flow URLs. Defaults to `undefined`. | | `telemetry?` | false \| \{ debug?: boolean; disabled?: boolean; perEventSampling?: boolean; \} | Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. | | `touchSession?` | `boolean` | By default, the [Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/Sessions#operation/touchSession) is called during page focus to keep the last active session alive. This option allows you to disable this behavior. | | `waitlistUrl?` | `string` | The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). | --- title: Clerk Nuxt SDK description: The Clerk Nuxt SDK gives you access to prebuilt components, composables, and helpers to make user authentication easier. sdk: nuxt sdkScoped: "true" canonical: /docs/reference/nuxt/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nuxt notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,vue,ruby,js-backend activeSdk: nuxt sourceFile: /docs/reference/nuxt/overview.mdx --- The Clerk Nuxt SDK gives you access to prebuilt components, composables, and helpers to make user authentication easier. Refer to the [quickstart guide](/docs/nuxt/getting-started/quickstart) to get started. ## Integration To configure Clerk with Nuxt, you must pass the `@clerk/nuxt` module to your Nuxt config in your `nuxt.config.ts` file. See the [reference](/docs/reference/nuxt/integration) for more information on configuring the module, including setting Clerk options like `signInForceRedirectUrl`. ## Client-side helpers Because the Nuxt SDK is built on top of the Clerk Vue SDK, you can use the composables that the Vue SDK provides. These composables include access to the Clerk object, User object, Organization object, and a set of useful helper methods for signing in and signing up. Learn more in the Vue SDK reference. * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() ## `Auth` object The `Auth` object is available at `event.context.auth()` in your [event handlers](https://h3.unjs.io/guide/event-handler). This JavaScript object contains important information like session data, your user's ID, as well as their Organization ID. Learn more. ### `event.context.auth()` options * `opts?` * `{acceptsToken: TokenType, treatPendingAsSignedOut: boolean }` An optional object that can be used to configure the behavior of the `event.context.auth()` function. It accepts the following properties: * `acceptsToken?`: The type of authentication token(s) to accept. Valid values are: * `'session_token'` - authenticates a user session. * `'oauth_token'` - authenticates a machine request using OAuth. * `'m2m_token'` - authenticates a machine to machine request. * `'api_key'` - authenticates a machine request using API keys. Can be set to: * A single token type. * An array of token types. * `'any'` to accept all available token types. Defaults to `'session_token'`. * `treatPendingAsSignedOut?`: A boolean that indicates whether to treat pending session status as signed out. Defaults to `true`. ### Example: Protect a route based on token type The following example uses `event.context.auth()` to protect the route based on token type: * It accepts any token type `(acceptsToken: 'any')` from the request. * If the token is a `session_token`, it logs that the request is from a user session. * Otherwise, it logs that the request uses a machine token and specifies its type. ```ts export default eventHandler((event) => { // Use `event.context.auth()` to protect a route based on token type const authObject = event.context.auth({ acceptsToken: 'any' }) if (authObject.tokenType === 'session_token') { console.log('This is a session token from a user') } else { console.log(`This is a ${authObject.tokenType} token`) } return {} }) ``` ## `clerkMiddleware()` The `clerkMiddleware()` helper integrates Clerk authentication and authorization into your Nuxt application through middleware. [Learn more](/docs/reference/nuxt/clerk-middleware). ## `clerkClient()` The `clerkClient()` helper returns an instance of the JS Backend SDK. [Learn more](/docs/nuxt/guides/users/reading). ## Protect pages and API routes To protect pages, use the `useAuth()` helper to protect a single page, or use it with `defineNuxtRouteMiddleware()` alongside the `createRouteMatcher()` helper to protect multiple pages. [Learn more](/docs/guides/secure/protect-pages). To protect API routes (`/api/**`), use the `clerkMiddleware()` helper. [Learn more](/docs/reference/nuxt/clerk-middleware). > \[!QUIZ] > When protecting pages/routes using middleware, what is the difference between using `defineNuxtRouteMiddleware()` and `clerkMiddleware()`? Why not use one or the other? > > *** > > `defineNuxtRouteMiddleware()` is used to protect pages only and cannot protect API routes. `clerkMiddleware()` is used to protect API routes. It can protect pages, **but on initial page reload only**. On subsequent navigations, it won't be triggered because client-side navigation will bypass the middleware. --- title: "`@clerk/nuxt` module" description: The `@clerk/nuxt` module provides session and user context to Clerk's composables and components. sdk: nuxt sdkScoped: "true" canonical: /docs/reference/nuxt/integration lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nuxt notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,vue,ruby,js-backend activeSdk: nuxt sourceFile: /docs/reference/nuxt/integration.mdx --- The `@clerk/nuxt` module is required to integrate Clerk into your Nuxt application, providing session and user context to Clerk's composables and components. ## Usage To configure Clerk with Nuxt, you must add the module to your modules array in your `nuxt.config.ts` file. The `clerk` property accepts optional options, such as `{ signInForceRedirectUrl: '/dashboard' }`. See the [properties section](#properties) for more information. ```ts {{ filename: 'nuxt.config.ts' }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { // It can accept options, such as { signInForceRedirectUrl: '/dashboard' } signInForceRedirectUrl: '/dashboard', }, }) ``` To update Clerk options at runtime, use the updateClerkOptions() function. ## Properties | Property | Type | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `afterMultiSessionSingleSignOutUrl?` | null \| string | The full URL or path to navigate to after signing out the current user is complete. This option applies to [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). | | ~~`afterSignInUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl` or `signInForceRedirectUrl` instead. | | `afterSignOutUrl?` | null \| string | Full URL or path to navigate to after successful sign out. | | ~~`afterSignUpUrl?`~~ | null \| string | **Deprecated.** Use `signUpFallbackRedirectUrl` or `signUpForceRedirectUrl` instead. | | `allowedRedirectOrigins?` | (string \| RegExp)\[] | An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `allowedRedirectProtocols?` | string\[] | An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `appearance?` | [`Appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) | Optional object to style your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `clerkJSUrl?` | `string` | The URL that `@clerk/clerk-js` should be hot-loaded from. | | `clerkJSVariant?` | "" \| "headless" | If your web application only uses Control Components, you can set this value to `'headless'` and load a minimal ClerkJS bundle for optimal page performance. | | `clerkJSVersion?` | `string` | The npm version for `@clerk/clerk-js`. | | `domain?` | string \| (url: URL) => string | **Required if your application is a satellite application**. Sets the domain of the satellite application. | | `experimental?` | `Autocomplete`\<\{ commerce: boolean; persistClient: boolean; rethrowOfflineNetworkErrors: boolean; \}, `Record`\<`string`, `any`\>\> | Enable experimental flags to gain access to new features. These flags are not guaranteed to be stable and may change drastically in between patch or minor versions. | | `initialState?` | `Serializable`\<\{ actor: undefined \| \{ \[x: string]: unknown; sub: string; \}; factorVerificationAge: \[number, number]; organization: undefined \| OrganizationResource; orgId: undefined \| string; orgPermissions: undefined \| string\[]; orgRole: undefined \| string; orgSlug: undefined \| string; session: undefined \| SessionResource; sessionClaims: JwtPayload; sessionId: undefined \| string; sessionStatus: SessionStatusClaim; user: undefined \| UserResource; userId: undefined \| string; \}\> | Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `isSatellite?` | boolean \| (url: URL) => boolean | A boolean that indicates whether the application is a satellite application. | | `localization?` | [`LocalizationResource`](/docs/guides/customizing-clerk/localization) | Optional object to localize your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `newSubscriptionRedirectUrl?` | null \| string | The URL to navigate to after the user completes the checkout and clicks the "Continue" button. | | `nonce?` | `string` | This nonce value will be passed through to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. | | `proxyUrl?` | string \| (url: URL) => string \| (url: URL) => string | **Required for applications that run behind a reverse proxy**. The URL that Clerk will proxy requests to. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). | | `publishableKey` | `string` | The Clerk Publishable 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. | | ~~`redirectUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl`, `signInForceRedirectUrl`, `signUpFallbackRedirectUrl`, or `signUpForceRedirectUrl` instead. | | `routerPush?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "push" navigation. | | `routerReplace?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "replace" navigation. | | `sdkMetadata?` | \{ environment?: string; name: string; version: string; \} | Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `sdkMetadata.environment?` | `string` | Typically this will be the `NODE_ENV` that the SDK is currently running in. | | `sdkMetadata.name` | `string` | The npm package name of the SDK. | | `sdkMetadata.version` | `string` | The npm package version of the SDK. | | `selectInitialSession?` | (client: ClientResource) => null \| SignedInSessionResource | By default, the last signed-in session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. | | `signInFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signInForceRedirectUrl?` | null \| string | 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. | | `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. | | `signUpFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signUpForceRedirectUrl?` | null \| string | 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. | | `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. | | `standardBrowser?` | `boolean` | By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. | | `supportEmail?` | `string` | Optional support email for display in authentication screens. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `taskUrls?` | `Record`\<`"choose-organization"`, `string`\> | Customize the URL paths users are redirected to after sign-in or sign-up when specific session tasks need to be completed. When `undefined`, it uses Clerk's default task flow URLs. Defaults to `undefined`. | | `telemetry?` | false \| \{ debug?: boolean; disabled?: boolean; perEventSampling?: boolean; \} | Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. | | `touchSession?` | `boolean` | By default, the [Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/Sessions#operation/touchSession) is called during page focus to keep the last active session alive. This option allows you to disable this behavior. | | `waitlistUrl?` | `string` | The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). | --- title: clerkMiddleware() | Nuxt description: The clerkMiddleware() helper allows you to protect your Nuxt application using middleware. sdk: nuxt sdkScoped: "true" canonical: /docs/reference/nuxt/clerk-middleware lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nuxt notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,vue,ruby,js-backend activeSdk: nuxt sourceFile: /docs/reference/nuxt/clerk-middleware.mdx --- The `clerkMiddleware()` helper allows you to protect your Nuxt application **on the server-side**. It can be used to validate a user's authentication status or authorization status. > \[!WARNING] > `clerkMiddleware()` should be used to protect API routes only. It's not recommended to use `clerkMiddleware()` to protect pages as it will **only work on initial page reload**. On subsequent navigations, it won't be triggered because client-side navigation will bypass the middleware. To protect pages, see the [dedicated guide](/docs/guides/secure/protect-pages). ## Configure `clerkMiddleware()` By default, the Nuxt SDK **automatically** adds the `clerkMiddleware()` helper to your Nuxt application. To **manually** configure the middleware: 1. In your `nuxt.config.ts` file, under the `clerk` property, set `skipServerMiddleware: true`. ```ts {{ filename: 'nuxt.config.ts', mark: [[3, 5]] }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { skipServerMiddleware: true, }, }) ``` 2. In your `server/middleware/` directory, create a file named `clerk.ts` with the following code: ```ts {{ filename: 'server/middleware/clerk.ts' }} import { clerkMiddleware } from '@clerk/nuxt/server' export default clerkMiddleware() ``` ## Protect API routes You can protect API routes using either or both of the following: * [Authentication-based protection](#authentication-based-protection): Verify if the user is signed in. * [Authorization-based protection](#authorization-based-protection): Verify if the user has the required privileges, such as a Role, Permission, Feature, or Plan. Learn more about [authorization checks](/docs/guides/secure/authorization-checks). You can also [protect multiple routes](#protect-multiple-routes) using the `createRouteMatcher()` helper. ### Authentication-based protection To protect routes based on user authentication status, you can check if the user is signed in by checking the `isAuthenticated` property on the [`auth`](/docs/reference/nuxt/overview#auth-object) object. In the following example, the `clerkMiddleware()` helper checks if the user is signed in and accessing a protected route. If they aren't signed in, an error is thrown using Nuxt's [`createError()`](https://nuxt.com/docs/api/utils/create-error) utility. ```tsx {{ filename: 'server/middleware/clerk.ts' }} import { clerkMiddleware } from '@clerk/nuxt/server' export default clerkMiddleware((event) => { const { isAuthenticated } = event.context.auth() const isAdminRoute = event.path.startsWith('/api/admin') if (!isAuthenticated && isAdminRoute) { throw createError({ statusCode: 401, statusMessage: 'Unauthorized: User not signed in', }) } }) ``` ### Authorization-based protection To protect routes based on user authorization status, you can use the `has()` helper to check if the user has the required [privileges, such as a Role, Permission, Feature, or Plan](/docs/guides/secure/authorization-checks). The `has()` helper is available on the [`auth`](/docs/reference/nuxt/overview#auth-object) object. #### Example: Protect routes based on Custom Permissions In the following example, the `clerkMiddleware()` helper checks if the user is accessing a protected route. If so, it checks if the user has the required Custom Permission. If they don't, an error is thrown using Nuxt's [`createError()`](https://nuxt.com/docs/api/utils/create-error) utility. ```ts {{ filename: 'server/middleware/clerk.ts' }} import { clerkMiddleware } from '@clerk/nuxt/server' export default clerkMiddleware((event) => { const { has } = event.context.auth() const isInvoicesRoute = event.path.startsWith('/api/invoices') const canCreateInvoices = has({ permission: 'org:invoices:create', }) // Check if the user is accessing a protected route if (isInvoicesRoute) { // Check if the user has the required Permission if (!canCreateInvoices) { throw createError({ statusCode: 403, statusMessage: 'Unauthorized: Missing Permission to create invoices', }) } } }) ``` #### Example: Protect routes based on default Roles > \[!WARNING] > It's best practice to use Permission-based authorization over Role-based authorization, as it reduces complexity and increases security. Usually, complex Role checks can be refactored with a single Permission check. In the following example, the `clerkMiddleware()` helper checks if the user is accessing a protected route. If so, it checks if the user has the required admin Role. If they don't, an error is thrown using Nuxt's [`createError()`](https://nuxt.com/docs/api/utils/create-error) utility. ```ts {{ filename: 'server/middleware/clerk.ts' }} import { clerkMiddleware } from '@clerk/nuxt/server' export default clerkMiddleware((event) => { const { has } = event.context.auth() const isAdminRoute = event.path.startsWith('/api/admin') const isAdmin = has({ role: 'org:admin', }) // Check if the user is accessing a protected route if (isAdminRoute) { // Check if the user has the required Role if (!isAdmin) { throw createError({ statusCode: 403, statusMessage: 'Unauthorized: Admin access required', }) } } }) ``` ### Protect multiple routes You can protect multiple routes at once by using Clerk's `createRouteMatcher()` helper function. The `createRouteMatcher()` helper accepts an array of route patterns and checks if the route the user is trying to visit matches one of the patterns passed to it. Let's take the [first example](#authentication-based-protection) from this guide and add the `createRouteMatcher()` helper. Instead of only checking `/api/admin/**` routes, the following example checks both `/api/invoices/**` *and* `/api/admin/**` routes. ```ts {{ filename: 'server/middleware/clerk.ts' }} + import { clerkMiddleware, createRouteMatcher } from '@clerk/nuxt/server' export default clerkMiddleware((event) => { const { isAuthenticated } = event.context.auth() - const isAdminRoute = event.path.startsWith('/api/admin') + const isProtectedRoute = createRouteMatcher(['/api/invoices(.*)', '/api/admin(.*)']) // Check if the user is not signed in // and is trying to access a protected route. If so, throw a 401 error. if (!isAuthenticated && isProtectedRoute(event)) { throw createError({ statusCode: 401, statusMessage: 'Unauthorized: User not signed in', }) } }) ``` Now, let's add authorization-based protection to the example so that you can see how to combine everything you've learned so far. ```ts {{ filename: 'server/middleware/clerk.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nuxt/server' export default clerkMiddleware((event) => { const { isAuthenticated } = event.context.auth() const isProtectedRoute = createRouteMatcher(['/api/invoices(.*)', '/api/admin(.*)']) + const canCreateInvoices = has({ + permission: 'org:invoices:create', + }) // Check if the user is not signed in // and is trying to access a protected route. If so, throw a 401 error. if (!isAuthenticated && isProtectedRoute(event)) { throw createError({ statusCode: 401, statusMessage: 'Unauthorized: User not signed in', }) } + // Check if the user doesn't have the required Permission + // and is accessing a protected route. If so, throw a 403 error. + if (!canCreateInvoices && isProtectedRoute(event)) { + throw createError({ + statusCode: 403, + statusMessage: 'Unauthorized: Missing Permission to create invoices', + }) + } }) ``` ## `clerkMiddleware()` options The `clerkMiddleware()` 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']` *** * `clockSkewInMs?` * `number` Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to 5000 ms (5 seconds). *** * `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/~/api-keys) page in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). *** * `organizationSyncOptions?` * [OrganizationSyncOptions](#organization-sync-options) | undefined Used to activate a specific [Organization](/docs/guides/organizations/overview) or [Personal Account](/docs/guides/dashboard/overview) based on URL path parameters. If there's a mismatch between the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. in the session (e.g., as reported by auth()) and the Organization indicated by the URL, the middleware will attempt to activate the Organization specified in the URL. *** * `proxyUrl?` * `string` Specify the URL of the proxy, if using a proxy. *** * `signInUrl` * `string` The full URL or path to your sign-in page. Needs to point to your primary application on the client-side. **Required 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` The full URL or path to your sign-up page. Needs to point to your primary application on the client-side. **Required 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. *** * `publishableKey` * `string` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `secretKey?` * `string` The Clerk Secret Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The `CLERK_ENCRYPTION_KEY` environment variable must be set when providing `secretKey` as an option, refer to [Dynamic keys](#dynamic-keys). ### `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 Organization 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 OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the 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 \. 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` | ❌ | --- title: "`clerkMiddleware()` | Astro" description: The `clerkMiddleware()` function allows you to protect your Astro application using Middleware. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/clerk-middleware lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/clerk-middleware.mdx --- The `clerkMiddleware()` helper integrates Clerk authentication into your Astro application through middleware. ## Configure `clerkMiddleware()` Create a `middleware.ts` file inside your `src/` directory. ```ts {{ filename: 'src/middleware.ts' }} import { clerkMiddleware } from '@clerk/astro/server' export const onRequest = clerkMiddleware() ``` ## `createRouteMatcher()` `createRouteMatcher()` is a Clerk helper function that allows you to protect multiple routes. `createRouteMatcher()` accepts an array of routes and checks if the route the user is trying to visit matches one of the routes passed to it. The `createRouteMatcher()` helper returns a function that, if called with the `context.request` object from the Middleware, will return `true` if the user is trying to access a route that matches one of the routes passed to `createRouteMatcher()`. In the following example, `createRouteMatcher()` sets all `/dashboard` and `/forum` routes as protected routes. ```ts const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)']) ``` ## Protect routes You can protect routes by checking either or both of the following: * [User authentication status](#protect-routes-based-on-user-authentication-status) -- user is signed in or out * [User authorization status](#protect-routes-based-on-user-authorization-status) -- user has the required Role or Permission ### Protect routes based on user authentication status To protect routes based on user authentication status, use auth().isAuthenticated{{ target: '_blank' }} to check if `isAuthenticated` is true. If it's not, the user is not authenticated, and you can redirect them to the sign-in page. ```tsx {{ filename: 'src/middleware.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server' const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)']) export const onRequest = clerkMiddleware((auth, context) => { const { isAuthenticated, redirectToSignIn } = auth() if (!isAuthenticated && isProtectedRoute(context.request)) { // Add custom logic to run before redirecting return redirectToSignIn() } }) ``` ### Protect routes based on user authorization status To protect routes based on user authorization status, use auth().has(){{ target: '_blank' }} to check if the user has the required Roles or Custom Permissions. ```tsx {{ filename: 'src/middleware.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server' const isProtectedRoute = createRouteMatcher(['/admin(.*)']) export const onRequest = clerkMiddleware((auth, context) => { const { has, redirectToSignIn } = auth() // Restrict admin routes to users with specific Permissions if ( (isProtectedRoute(context.request) && !has({ permission: 'org:admin:example1' })) || !has({ permission: 'org:admin:example2' }) ) { // Add logic to run if the user does not have the required Permissions; for example, redirecting to the sign-in page return redirectToSignIn() } }) ``` ## Protect all routes To protect all routes in your application and define specific routes as public, you can use any of the above methods and simply invert the `if` condition. ```tsx import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server' const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)']) export const onRequest = clerkMiddleware((auth, context) => { const { isAuthenticated, redirectToSignIn, userId } = auth() if (!isPublicRoute(context.request) && !isAuthenticated) { return redirectToSignIn() } }) ``` ## `clerkMiddleware()` options The `clerkMiddleware()` 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']` *** * `clockSkewInMs?` * `number` Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to 5000 ms (5 seconds). *** * `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/~/api-keys) page in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). *** * `organizationSyncOptions?` * [OrganizationSyncOptions](#organization-sync-options) | undefined Used to activate a specific [Organization](/docs/guides/organizations/overview) or [Personal Account](/docs/guides/dashboard/overview) based on URL path parameters. If there's a mismatch between the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. in the session (e.g., as reported by auth()) and the Organization indicated by the URL, the middleware will attempt to activate the Organization specified in the URL. *** * `proxyUrl?` * `string` Specify the URL of the proxy, if using a proxy. *** * `signInUrl` * `string` The full URL or path to your sign-in page. Needs to point to your primary application on the client-side. **Required 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` The full URL or path to your sign-up page. Needs to point to your primary application on the client-side. **Required 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. *** * `publishableKey` * `string` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `secretKey?` * `string` The Clerk Secret Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The `CLERK_ENCRYPTION_KEY` environment variable must be set when providing `secretKey` as an option, refer to [Dynamic keys](#dynamic-keys). ### `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 Organization 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 OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the 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 \. 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` | ❌ | --- title: Use Clerk with Astro and React description: Learn how to user Clerk inside an Astro app with React sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/react lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/react.mdx --- Astro provides an [integration](https://docs.astro.build/en/guides/integrations-guide/react/) that enables server-side rendering and client-side hydration for your React components. This guide demonstrates how to use Clerk with Astro and React. If you have not set up your Astro application to work with Clerk, see the [quickstart guide](/docs/astro/getting-started/quickstart). ## Install `@astrojs/react` Add the [Astro React integration](https://docs.astro.build/en/guides/integrations-guide/react/) to your project: ```npm npx astro add react ``` ## Update `astro.config.mjs` Add Clerk and React integrations to your Astro configuration: ```ts {{ filename: 'astro.config.mjs' }} import { defineConfig } from 'astro/config' import node from '@astrojs/node' import react from '@astrojs/react' import clerk from '@clerk/astro' export default defineConfig({ integrations: [clerk(), react()], output: 'server', adapter: node({ mode: 'standalone' }), }) ``` ## Use Clerk components You can use the prebuilt components in your Astro pages or regular React components. ### Astro pages The following example demonstrates how to use Clerk components in Astro pages. ```astro {{ filename: 'src/layouts/SiteLayout.astro' }} --- import { SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/astro/react' ---
``` ### React components The following example demonstrates how to use Clerk components in React components. ```tsx {{ filename: 'src/components/Header.tsx' }} import { SignInButton, SignedIn, SignedOut, UserButton } from '@clerk/astro/react' export default function Header() { return ( <>

My App

) } ``` ## Use stores in your React components Clerk Astro provides a set of useful [stores](/docs/reference/astro/overview#client-side-helpers) that give you access to the Clerk{{ target: '_blank' }} object, and helper methods for signing in and signing up. The following example demonstrates how to use a Clerk Astro store. ```tsx {{ filename: 'src/components/Header.tsx' }} import { $userStore } from '@clerk/astro/client' export default function Username() { const user = useSyncExternalStore($userStore.listen, $userStore.get, $userStore.get) return <>{user?.firstName} } ```
## Next steps * [Protect content and read user data](/docs/astro/guides/users/reading) * Learn how to use Clerk's hooks and helpers to access the session and user data in your Astro application. *** * [Client-side helpers](/docs/reference/astro/overview#client-side-helpers) * Learn more about Astro client-side helpers and how to use them. --- title: "`updateClerkOptions()`" description: The `updateClerkOptions()` function allows you to update Clerk's options at runtime. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/update-clerk-options lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/update-clerk-options.mdx --- The `updateClerkOptions()` function is used to update Clerk's options at runtime. It can be called at any time after [Clerk has been initialized](/docs/reference/astro/integration). ## Usage ```tsx import { useState } from 'react' import { updateClerkOptions } from '@clerk/astro/client' import { dark } from '@clerk/themes' export function ThemeToggler() { const [isDark, setIsDark] = useState(false) const { setActive } = useClerk() const toggleTheme = () => { const theme = !isDark setIsDark(theme) updateClerkOptions({ appearance: { theme: theme ? dark : undefined, }, }) } return } ``` ## Properties * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `localization` * [Localization](/docs/guides/customizing-clerk/localization) | undefined Optional object to localize your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. [components-ref]: /docs/reference/components/overview [ap-ref]: /docs/guides/customizing-clerk/account-portal --- title: Locals description: Learn how to authenticate your Astro application with Clerk using locals. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/locals lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/locals.mdx --- Through Astro [`locals`](https://docs.astro.build/en/guides/middleware/#storing-data-in-contextlocals), Clerk's Auth and current User{{ target: '_blank' }} objects can be accessed between middlewares and pages. These locals are injected when you configure the provided [middleware](/docs/reference/astro/clerk-middleware). ## `locals.auth()` `Astro.locals.auth()` returns an `Auth` object. This JavaScript object contains important information like session data, your user's ID, as well as the ID of the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Learn more about the `Auth` object here{{ target: '_blank' }}. ### `locals.auth()` options * `opts?` * `{acceptsToken: TokenType, treatPendingAsSignedOut: boolean }` An optional object that can be used to configure the behavior of the `locals.auth()` function. It accepts the following properties: * `acceptsToken?`: The type of authentication token(s) to accept. Valid values are: * `'session_token'` - authenticates a user session. * `'oauth_token'` - authenticates a machine request using OAuth. * `'m2m_token'` - authenticates a machine to machine request. * `'api_key'` - authenticates a machine request using API keys. Can be set to: * A single token type. * An array of token types. * `'any'` to accept all available token types. Defaults to `'session_token'`. * `treatPendingAsSignedOut?`: A boolean that indicates whether to treat pending session status as signed out. Defaults to `true`. ### Example: Protect a page or form You can use the `isAuthenticated` property from the `auth()` local to protect your pages and forms. ```astro {{ filename: 'src/pages/protected.astro' }} --- const { isAuthenticated, userId, redirectToSignIn } = Astro.locals.auth() if (!isAuthenticated) { return redirectToSignIn() } ---
Protected page
``` ```astro {{ filename: 'src/pages/form.astro' }} --- if (Astro.request.method === 'POST') { if (!Astro.locals.auth().isAuthenticated) { throw new Error('You must be signed in to add an item to your cart') } const data = await Astro.request.formData() console.log('add item action', data) } ---
```
### Example: Protect a route based on token type The following example uses `locals.auth()` to protect the route based on token type: * It accepts any token type `(acceptsToken: 'any')` from the request. * If the token is a `session_token`, it logs that the request is from a user session. * Otherwise, it logs that the request uses a machine token and specifies its type. ```ts export const GET: APIRoute = ({ locals }) => { // Use `locals.auth()` to protect a route based on token type const authObject = locals.auth({ acceptsToken: 'any' }) if (authObject.tokenType === 'session_token') { console.log('This is a session token from a user') } else { console.log(`This is a ${authObject.tokenType} token`) } return new Response(JSON.stringify({})) } ``` ## `locals.currentUser()` The `currentUser()` local returns the Backend User object of the currently active user. Under the hood, this local: * calls `fetch()`, so it is automatically deduped per request. * uses the [`GET /v1/users/{user_id}`](/docs/reference/backend-api/tag/users/get/users/\{user_id}){{ target: '_blank' }} endpoint. * counts towards the [Backend API request rate limit](/docs/guides/how-clerk-works/system-limits). > \[!WARNING] > The Backend User object includes a `privateMetadata` field that should not be exposed to the frontend. Avoid passing the full user object returned by `currentUser()` to the frontend. Instead, pass only the specified fields you need. ```astro {{ filename: 'src/pages/form.astro' }} --- if (Astro.request.method === 'POST') { const user = await Astro.locals.currentUser() if (!user) { throw new Error('You must be signed in to use this feature') } const data = await Astro.request.formData() const serverData = { usersHobby: data.get('hobby'), userId: user.id, profileImage: user.imageUrl, } console.log('add item action completed with user details ', serverData) } ---
``` --- title: Integration description: The Astro integration provides session and user context to Clerk's hooks and components. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/integration lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/integration.mdx --- The Clerk integration is required to integrate Clerk into your Astro application, providing session and user context to Clerk's hooks, nanostores, and components. ## Usage To configure Clerk with Astro, you must pass the `clerk()` integration to the `integrations` array in your `astro.config.mjs` file. The `clerk()` integration accepts optional options, such as `{ signInForceRedirectUrl: '/dashboard' }`. See the [properties section](#properties) for more information. > \[!WARNING] > For SSR, there is further configuration required. See the [quickstart](/docs/astro/getting-started/quickstart#update-astro-config-mjs) for more information. ```ts {{ filename: 'astro.config.mjs' }} import { defineConfig } from 'astro/config' import clerk from '@clerk/astro' export default defineConfig({ // Can accept options, such as { signInForceRedirectUrl: '/dashboard' } integrations: [clerk()], }) ``` ## Properties | Property | Type | Description | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
`afterMultiSessionSingleSignOutUrl?` | null \| string | The full URL or path to navigate to after signing out the current user is complete. This option applies to [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). | | ~~`afterSignInUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl` or `signInForceRedirectUrl` instead. | | `afterSignOutUrl?` | null \| string | Full URL or path to navigate to after successful sign out. | | ~~`afterSignUpUrl?`~~ | null \| string | **Deprecated.** Use `signUpFallbackRedirectUrl` or `signUpForceRedirectUrl` instead. | | `allowedRedirectOrigins?` | (string \| RegExp)\[] | An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `allowedRedirectProtocols?` | string\[] | An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. | | `appearance?` | [`Appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) | Optional object to style your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `clerkJSUrl?` | `string` | The URL that `@clerk/clerk-js` should be hot-loaded from. | | `clerkJSVariant?` | "" \| "headless" | If your web application only uses Control Components, you can set this value to `'headless'` and load a minimal ClerkJS bundle for optimal page performance. | | `clerkJSVersion?` | `string` | The npm version for `@clerk/clerk-js`. | | `domain?` | string \| (url: URL) => string | **Required if your application is a satellite application**. Sets the domain of the satellite application. | | `experimental?` | `Autocomplete`\<\{ commerce: boolean; persistClient: boolean; rethrowOfflineNetworkErrors: boolean; \}, `Record`\<`string`, `any`\>\> | Enable experimental flags to gain access to new features. These flags are not guaranteed to be stable and may change drastically in between patch or minor versions. | | `initialState?` | `Serializable`\<\{ actor: undefined \| \{ \[x: string]: unknown; sub: string; \}; factorVerificationAge: \[number, number]; organization: undefined \| OrganizationResource; orgId: undefined \| string; orgPermissions: undefined \| string\[]; orgRole: undefined \| string; orgSlug: undefined \| string; session: undefined \| SessionResource; sessionClaims: JwtPayload; sessionId: undefined \| string; sessionStatus: SessionStatusClaim; user: undefined \| UserResource; userId: undefined \| string; \}\> | Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `isSatellite?` | boolean \| (url: URL) => boolean | A boolean that indicates whether the application is a satellite application. | | `localization?` | [`LocalizationResource`](/docs/guides/customizing-clerk/localization) | Optional object to localize your components. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `newSubscriptionRedirectUrl?` | null \| string | The URL to navigate to after the user completes the checkout and clicks the "Continue" button. | | `nonce?` | `string` | This nonce value will be passed through to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. | | `proxyUrl?` | string \| (url: URL) => string \| (url: URL) => string | **Required for applications that run behind a reverse proxy**. The URL that Clerk will proxy requests to. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). | | `publishableKey` | `string` | The Clerk Publishable 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. | | ~~`redirectUrl?`~~ | null \| string | **Deprecated.** Use `signInFallbackRedirectUrl`, `signInForceRedirectUrl`, `signUpFallbackRedirectUrl`, or `signUpForceRedirectUrl` instead. | | `routerPush?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "push" navigation. | | `routerReplace?` | (to: string, metadata?: \{ windowNavigate: (to: string \| URL) => void; \}) => unknown | A function which takes the destination path as an argument and performs a "replace" navigation. | | `sdkMetadata?` | \{ environment?: string; name: string; version: string; \} | Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). | | `sdkMetadata.environment?` | `string` | Typically this will be the `NODE_ENV` that the SDK is currently running in. | | `sdkMetadata.name` | `string` | The npm package name of the SDK. | | `sdkMetadata.version` | `string` | The npm package version of the SDK. | | `selectInitialSession?` | (client: ClientResource) => null \| SignedInSessionResource | By default, the last signed-in session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. | | `signInFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs in, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signInForceRedirectUrl?` | null \| string | 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. | | `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. | | `signUpFallbackRedirectUrl?` | null \| string | The fallback URL to redirect to after the user signs up, if there's no `redirect_url` in the path already. It's recommended to use the [environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) instead. Defaults to `'/'`. | | `signUpForceRedirectUrl?` | null \| string | 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. | | `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. | | `standardBrowser?` | `boolean` | By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. | | `supportEmail?` | `string` | Optional support email for display in authentication screens. Will only affect Clerk Components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. | | `taskUrls?` | `Record`\<`"choose-organization"`, `string`\> | Customize the URL paths users are redirected to after sign-in or sign-up when specific session tasks need to be completed. When `undefined`, it uses Clerk's default task flow URLs. Defaults to `undefined`. | | `telemetry?` | false \| \{ debug?: boolean; disabled?: boolean; perEventSampling?: boolean; \} | Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. | | `touchSession?` | `boolean` | By default, the [Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/Sessions#operation/touchSession) is called during page focus to keep the last active session alive. This option allows you to disable this behavior. | | `waitlistUrl?` | `string` | The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). | --- title: Clerk Astro SDK description: The Clerk Astro SDK gives you access to prebuilt components, stores, and helpers to make user authentication easier. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/overview.mdx --- The Clerk Astro SDK gives you access to prebuilt components, stores, and helpers to make user authentication easier. Refer to the [quickstart guide](/docs/astro/getting-started/quickstart) to get started. ## Integration To configure Clerk with Astro, you must pass [the `clerk()` integration](/docs/reference/astro/integration) to the `integrations` array in your `astro.config.mjs` file. See the [quickstart](/docs/astro/getting-started/quickstart#update-astro-config-mjs) for more information on configuring the integration. ## `updateClerkOptions()` The `updateClerkOptions()` function is used to update Clerk's options at runtime. It can be called at any time after [Clerk has been initialized](/docs/reference/astro/integration). See the [reference documentation](/docs/reference/astro/update-clerk-options) for more information. ## Client-side helpers The Astro SDK provides [stores](https://github.com/nanostores/nanostores) that give you access to the Clerk object and helper methods for authentication flows. * [`$authStore`](/docs/reference/astro/client-side-helpers/auth-store) * [`$clerkStore`](/docs/reference/astro/client-side-helpers/clerk-store) * [`$userStore`](/docs/reference/astro/client-side-helpers/user-store) * [`$signInStore`](/docs/reference/astro/client-side-helpers/sign-in-store) * [`$signUpStore`](/docs/reference/astro/client-side-helpers/sign-up-store) * [`$sessionStore`](/docs/reference/astro/client-side-helpers/session-store) * [`$sessionListStore`](/docs/reference/astro/client-side-helpers/session-list-store) * [`$organizationStore`](/docs/reference/astro/client-side-helpers/organization-store) ## Server-side helpers The following references show how to integrate Clerk features into your Astro app on the server-side. ### Locals The Astro SDK provides access to Clerk's authentication data through [Astro's `locals`](https://docs.astro.build/en/guides/middleware/#storing-data-in-contextlocals) object. The following references show how to access authentication data in server-side code: * [`Auth`](/docs/reference/astro/locals#locals-auth) * [`CurrentUser`](/docs/reference/astro/locals#locals-current-user) ### `clerkMiddleware()` The `clerkMiddleware()` helper integrates Clerk authentication and authorization into your Astro application through middleware. You can learn more [here](/docs/reference/astro/clerk-middleware). ### `clerkClient()` Clerk's JS Backend SDK provides access to Backend API resources and low-level authentication utilities for JavaScript environments. For example, to retrieve a list of all users in your application, you can use the `users.getUserList()` method from the JS Backend SDK instead of manually making a fetch request to the `https://api.clerk.com/v1/users` endpoint. All resource operations are mounted as sub-APIs on the `clerkClient` object. See the reference documentation{{ target: '_blank' }} for more information. ### Example: Use `clerkClient` to get a user's information The following example uses `clerkClient` to get information about the currently signed-in user. If the user is authenticated, their `userId` is passed to clerkClient.users.getUser(){{ target: '_blank' }} to get the current user's User{{ target: '_blank' }} object. If not authenticated, the user is redirected to the sign-in page. ```tsx import { clerkClient } from '@clerk/astro/server' export async function GET(context) { const { isAuthenticated, userId, redirectToSignIn } = context.locals.auth() if (!isAuthenticated) { return redirectToSignIn() } const user = await clerkClient(context).users.getUser(userId) return new Response(JSON.stringify({ user })) } ``` --- title: "`$authStore`" description: Clerk's $authStore nanostore provides a convenient way to access the current auth state and helper methods for managing the session. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/client-side-helpers/auth-store lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/client-side-helpers/auth-store.mdx --- The `$authStore` store provides a convenient way to access the current auth state and helper methods for managing the session. ## Returns * `userId` * `string` The ID of the current user. *** * `sessionId` * `string` The ID of the current session. *** * `orgId` * `string` The ID of the user's Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `orgRole` * `string` The current user's Role in their Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `orgSlug` * `string` The URL-friendly identifier of the user's Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## How to use the `$authStore` store The following example demonstrates how to use the [`$authStore`](/docs/reference/astro/client-side-helpers/auth-store) to access the current auth state. It uses `userId` to detect if the user is signed in. ```tsx {{ filename: 'components/external-data.tsx' }} import { useStore } from '@nanostores/react' import { $authStore } from '@clerk/astro/client' export default function ExternalData() { const { userId } = useStore($authStore) if (userId === undefined) { // Handle loading state however you like return
Loading...
} if (userId === null) { // Handle signed out state however you like return
Sign in to view this page
} return
...
} ``` ```vue {{ filename: 'components/external-data.vue' }} ``` ```svelte {{ filename: 'components/external-data.svelte' }} {#if $auth.userId === undefined}
Loading...
{:else if $auth.userId === null}
Sign in to view this page
{:else}
...
{/if} ```
--- title: "`$sessionListStore`" description: Clerk's $sessionList store retrieves a list of sessions that have been registered on the client device. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/client-side-helpers/session-list-store lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/client-side-helpers/session-list-store.mdx --- The `$sessionListStore` store returns an array of Session{{ target: '_blank' }} objects that have been registered on the client device. ## How to use the `$sessionListStore` store The following example demonstrates how to use the `$sessionListStore` to create a basic user button component. This component displays the current session's email address and provides a menu to switch between active sessions or sign out of all accounts. ```tsx {{ filename: 'user-button.tsx' }} import { $sessionListStore, $clerkStore } from '@clerk/astro/client' export default function UserButton() { const sessions = useStore($sessionListStore) const { session, setActive, signOut } = useStore($clerkStore) if (sessions === undefined) { // Handle loading state return
Loading sessions...
} return (
{session.user.primaryEmailAddress}
{sessions.map((sess) => ( ))}
) } ``` ```vue {{ filename: 'user-button.vue' }} ``` ```svelte {{ filename: 'session-list.svelte' }} {#if $sessions === undefined}
Loading sessions...
{:else}
{$clerk.session.user.primaryEmailAddress}
{#each $sessions as sess (sess.id)} {/each}
{/if} ```
--- title: "`$sessionStore`" description: Clerk's $sessionStore nanostore provides a convenient way to access the current user Session object, as well as helpers to set the session. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/client-side-helpers/session-store lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/client-side-helpers/session-store.mdx --- The `$sessionStore` store provides a convenient way to access the current user's Session{{ target: '_blank' }} object, as well as helpers for setting the active session. ## How to use the `$sessionStore` store The following example demonstrates how to use the `$sessionStore` store to access the `session` object, which has the `lastActiveAt` property on it. The `lastActiveAt` property is used to display the last active time of the current session to the user. ```tsx {{ filename: 'session.tsx' }} import { useStore } from '@nanostores/react' import { $sessionStore } from '@clerk/astro/client' export default function Session() { const session = useStore($sessionStore) if (session === undefined) { // Add logic to handle loading state return null } if (session === null) { // Add logic to handle not signed in state return null } return (

This session has been active since {session.lastActiveAt.toLocaleString()}

) } ``` ```vue {{ filename: 'session.vue' }} ``` ```svelte {{ filename: 'session.svelte' }} {#if $session === undefined} {:else if $session === null} {:else}

This session has been active since {$session.lastActiveAt.toLocaleString()}

{/if} ```
--- title: "`$signInStore`" description: Clerk's $signInStore nanostore provides a convenient way to access the SignIn object, which allows you to check the current state of a sign-in. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/client-side-helpers/sign-in-store lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/client-side-helpers/sign-in-store.mdx --- The `$signInStore` store provides a convenient way to access the SignIn{{ target: '_blank' }} object, which allows you to check the current state of a sign-in. This is also useful for creating a custom sign-in flow. ## How to use the `$signInStore` store ### Check the current state of a sign-in The following example demonstrates how to use the `$signInStore` store to check the current state of a sign-in. ```tsx {{ filename: 'sign-in-step.tsx' }} import { useStore } from '@nanostores/react' import { $signInStore } from '@clerk/astro/client' export default function SignInStep() { const signIn = useStore($signInStore) if (signIn === undefined) { // Add logic to handle loading state return null } return
The current sign in attempt status is {signIn.status}.
} ``` ```vue {{ filename: 'sign-in-step.vue' }} ``` ```svelte {{ filename: 'sign-in-step.svelte' }} {#if $signIn === undefined} {:else}
The current sign in attempt status is {$signIn.status}.
{/if} ```
The possible values for the `status` property of the `SignIn` resource are listed here. ### Create a custom sign-in flow The `$signInStore` store can also be used to build fully custom sign-in flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-in flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `$signInStore` store to create custom flows, check out the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`$clerkStore`" description: Clerk's $clerkStore nanostore provides a convenient way to access the `Clerk` object. This provides access to some methods that are not available in other stores. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/client-side-helpers/clerk-store lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/client-side-helpers/clerk-store.mdx --- The `$clerkStore` store provides a convenient way to access the Clerk{{ target: '_blank' }} object. This provides access to some methods that are not available in other stores. > \[!WARNING] > This is intended to be used for advanced use cases, like building a completely custom OAuth flow or as an escape hatch for getting access to the `Clerk` object. ## How to use the `$clerkStore` store ```tsx {{ filename: 'components/sign-in.tsx' }} import { useStore } from '@nanostores/react' import { $clerkStore } from '@clerk/astro/client' export default function SignIn() { const clerk = useStore($clerkStore) return } ``` ```vue {{ filename: 'components/sign-in.vue' }} ``` ```svelte {{ filename: 'components/sign-in.svelte' }} ``` --- title: "`$organizationStore`" description: Clerk's $organizationStore store retrieves the currently active Organization. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/client-side-helpers/organization-store lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/client-side-helpers/organization-store.mdx --- The `$organizationStore` store is used to retrieve attributes of the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ## How to use the `$organizationStore` store The following example demonstrates how to use the `$organizationStore` store to access the Organization{{ target: '_blank' }} object, which allows you to access the current Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ```tsx {{ filename: 'organization.tsx' }} import { useStore } from '@nanostores/react' import { $organizationStore } from '@clerk/astro/client' export default function Home() { const organization = useStore($organizationStore) if (organization === undefined) { // Add logic to handle loading state return null } if (organization === null) { // Add logic to handle no Active Organization state return null } return (

This current organization is {organization.name}

) } ``` ```vue {{ filename: 'organization.vue' }} ``` ```svelte {{ filename: 'organization.svelte' }} {#if $organization === undefined} {:else if $organization === null} {:else}

This current organization is {$organization.name}

{/if} ```
## Paginating data The following example demonstrates how to implement pagination for Organization memberships. The `memberships` state will be populated with the first page of the Organization's memberships. When the "Previous page" or "Next page" button is clicked, the `fetchMemberships` function will be called to fetch the previous or next page of memberships. You can implement this pattern to any Clerk function that returns a ClerkPaginatedResponse{{ target: '_blank' }} object. ```tsx {{ filename: 'members.tsx' }} import { useState, useEffect } from 'react' import { $organizationStore } from '@clerk/astro/client' import { useStore } from '@nanostores/react' export default function OrganizationMembers() { const [memberships, setMemberships] = useState([]) const [currentPage, setCurrentPage] = useState(1) const organization = useStore($organizationStore) const pageSize = 10 useEffect(() => { fetchMemberships() }, [currentPage, organization]) const fetchMemberships = async () => { if (!organization) { return } const { data } = await organization.getMemberships({ initialPage: currentPage, pageSize: 5, }) setMemberships(data) } const fetchPrevious = () => setCurrentPage(currentPage - 1) const fetchNext = () => setCurrentPage(currentPage + 1) if (organization === undefined) { // Handle loading state return null } if (organization === null) { // Handle no organization state return null } return (

Organization members

    {memberships.map((membership) => (
  • {membership.publicUserData.firstName} {membership.publicUserData.lastName} < {membership.publicUserData.identifier}> :: {membership.role}
  • ))}
) } ``` ```vue {{ filename: 'members.vue' }} ``` ```svelte {{ filename: 'members.svelte' }} {#if organization === undefined} {:else if organization === null} {:else}

Organization members

    {#each memberships as membership (membership.id)}
  • {membership.publicUserData.firstName} {membership.publicUserData.lastName} < {membership.publicUserData.identifier}> :: {membership.role}
  • {/each}
{/if} ```
--- title: "`$userStore`" description: The $userStore store provides a convenient way to access current user data and helper methods for managing the active user. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/client-side-helpers/user-store lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/client-side-helpers/user-store.mdx --- The `$userStore` store provides a convenient way to access current User{{ target: '_blank' }} data and helper methods for managing the active user. ## How to use the `$userStore` store ### Retrieve the current user data The following example demonstrates how to use the [`$userStore`](/docs/reference/astro/client-side-helpers/user-store) to access the `User` object. It returns `undefined` while Clerk is still loading and `null` if the user is not signed in. For more information, see the User reference{{ target: '_blank' }}. ```tsx {{ filename: 'user.tsx' }} import { useStore } from '@nanostores/react' import { $userStore } from '@clerk/astro/client' export default function User() { const user = useStore($userStore) if (user === undefined) { // Handle loading state however you like return null } if (user === null) { return
Not signed in
} return
Hello {user.fullName}!
} ``` ```vue {{ filename: 'user.vue' }} ``` ```svelte {{ filename: 'user.svelte' }} {#if $user === undefined} {:else if $user === null}
Not signed in
{:else}
Hello {$user.fullName}!
{/if} ```
### Update the current user data The following example demonstrates how to use the `$userStore` store to update the current user's data on the client-side. For more information on the `update()` method, see the User reference{{ target: '_blank' }}. ```tsx {{ filename: 'user.tsx' }} import { useStore } from '@nanostores/react' import { $userStore } from '@clerk/astro/client' export default function User() { const user = useStore($userStore) if (user === undefined) { // Handle loading state however you like return null } if (user === null) return null const updateUser = async () => { await user.update({ firstName: 'John', lastName: 'Doe', }) } return ( <>

user.firstName: {user?.firstName}

user.lastName: {user?.lastName}

) } ``` ```vue {{ filename: 'user.vue' }} ``` ```svelte {{ filename: 'user.svelte' }} {#if $user === undefined} {:else if $user !== null}

user.firstName: {$user.firstName}

user.lastName: {$user.lastName}

{/if} ```
### Reload user data The following example demonstrates how to use the `$userStore` store to reload the current user's data on the client-side. You only need to call `user.reload()` if you've updated the `User` object outside of the `user.update()` method or Clerk hooks; for example, if you made changes through an API endpoint. For more information on the `reload()` method, see the User reference{{ target: '_blank' }}. ```tsx {{ filename: 'user.tsx' }} import { useStore } from '@nanostores/react' import { $userStore } from '@clerk/astro/client' export default function User() { const user = useStore($userStore) if (user === undefined) { // Handle loading state however you like return null } if (user === null) return null const updateUser = async () => { // Update data via an API endpoint const updateMetadata = await fetch('/api/updateMetadata') // Check if the update was successful if (updateMetadata.message !== 'success') { throw new Error('Error updating') } // If the update was successful, reload the user data await user.reload() } return ( <>

user role: {user?.publicMetadata.role}

) } ``` ```vue {{ filename: 'user.vue' }} ``` ```svelte {{ filename: 'user.svelte' }} {#if $user === undefined} {:else if $user !== null}

user role: {$user.publicMetadata?.role}

{/if} ```
--- title: "`$signUpStore`" description: Clerk's $signUpStore nanostore provides a convenient way to access the `SignUp` object, which allows you to check the current state of a sign-up. This is also useful for creating a custom sign-up flow. sdk: astro sdkScoped: "true" canonical: /docs/reference/astro/client-side-helpers/sign-up-store lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: astro notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,nuxt,vue,ruby,js-backend activeSdk: astro sourceFile: /docs/reference/astro/client-side-helpers/sign-up-store.mdx --- The `$signUpStore` store provides a convenient way to access the SignUp{{ target: '_blank' }} object, which allows you to check the current state of a sign-up. This is also useful for creating a custom sign-up flow. ## How to use the `$signUpStore` store ### Check the current state of a sign-up The following example demonstrates how to use the `$signUpStore` store to access the `SignUp` object and check the current state of a sign-up. ```tsx {{ filename: 'sign-up-step.tsx' }} import { useStore } from '@nanostores/react' import { $signUpStore } from '@clerk/astro/client' export default function SignUpStep() { const signUp = useStore($signUpStore) if (signUp === undefined) { // Add logic to handle loading state return null } return
The current sign-up attempt status is {signUp.status}.
} ``` ```vue {{ filename: 'sign-up-step.vue' }} ``` ```svelte {{ filename: 'sign-up-step.svelte' }} {#if $signUp === undefined} {:else}
The current sign-up attempt status is {$signUp.status}.
{/if} ```
The possible values for the `status` property of the `SignUp` resource are listed here{{ target: '_blank' }}. ### Create a custom sign-up flow The `$signUpStore` store can also be used to build fully custom sign-up flows, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the authentication flow. Different sign-up flows include email and password, email and phone codes, email links, and multifactor (MFA). To learn more about using the `$signUpStore` store to create custom flows, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: Clerk Go SDK description: The Clerk Go SDK provides a powerful set of tools and utilities to seamlessly integrate authentication, user management, and Organization management into your Go application. sdk: go sdkScoped: "true" canonical: /docs/reference/go/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: go notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,astro,nuxt,vue,ruby,js-backend activeSdk: go sourceFile: /docs/reference/go/overview.mdx --- The Clerk Go SDK provides a powerful set of tools and utilities to seamlessly integrate authentication, user management, and Organization management into your Go application. Refer to the [quickstart guide](/docs/reference/go/overview) to get started. The Clerk Go SDK is built on top of the [Clerk Backend API](/docs/reference/backend-api){{ target: '_blank' }}, which provides a comprehensive set of endpoints for managing users, Organizations, and other resources. The SDK abstracts away the complexities of making direct API calls and is organized in a resource-based structure similar to the Backend API. Each resource supports specific operations, like `Create` or `List`. For example, the [`actortoken`](https://github.com/clerk/clerk-sdk-go/blob/v2/actortoken/api.go) resource supports the `Create`, `Revoke`, and `GetClient` operations. For the list of supported resources, see [`https://github.com/clerk/clerk-sdk-go/tree/v2`](https://github.com/clerk/clerk-sdk-go/tree/v2) where almost each directory represents a resource. For additional details on how to use this module, see the [Go Documentation](https://pkg.go.dev/github.com/clerk/clerk-sdk-go/v2). --- title: "`auth()`" description: The auth() helper retrieves the authentication state allowing you to protect your API routes or gather relevant data. sdk: tanstack-react-start sdkScoped: "true" canonical: /docs/reference/tanstack-react-start/auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: tanstack-react-start notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/tanstack-react-start/auth.mdx --- The `auth()` helper returns the Auth{{ target: '_blank' }} object of the currently active user. ## Parameters * `opts?` * `{acceptsToken: TokenType, treatPendingAsSignedOut: boolean }` An optional object that can be used to configure the behavior of the `auth()` function. It accepts the following properties: * `acceptsToken?`: The type of authentication token(s) to accept. Valid values are: * `'session_token'` - authenticates a user session. * `'oauth_token'` - authenticates a machine request using OAuth. * `'m2m_token'` - authenticates a machine to machine request. * `'api_key'` - authenticates a machine request using API keys. Can be set to: * A single token type. * An array of token types. * `'any'` to accept all available token types. Defaults to `'session_token'`. * `treatPendingAsSignedOut?`: A boolean that indicates whether to treat pending session status as signed out. Defaults to `true`. ## Returns `auth()` returns the Auth{{ target: '_blank' }} object. ## Usage See the [dedicated guide](/docs/tanstack-react-start/guides/users/reading#server-side) for example usage. --- title: "`clerkMiddleware()`" description: The `clerkMiddleware()` helper integrates Clerk authentication into your TanStack Start application through middleware. sdk: tanstack-react-start sdkScoped: "true" canonical: /docs/reference/tanstack-react-start/clerk-middleware lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: tanstack-react-start notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/tanstack-react-start/clerk-middleware.mdx --- The `clerkMiddleware()` helper integrates Clerk authentication into your TanStack Start application through middleware. ## Configure `clerkMiddleware()` Create a `src/start.ts` file and add `clerkMiddleware()` to the `requestMiddleware` array. ```tsx {{ filename: 'src/start.ts' }} import { clerkMiddleware } from '@clerk/tanstack-react-start/server' import { createStart } from '@tanstack/react-start' export const startInstance = createStart(() => { return { requestMiddleware: [clerkMiddleware()], } }) ``` ## `clerkMiddleware()` options The `clerkMiddleware()` 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']` *** * `clockSkewInMs?` * `number` Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to 5000 ms (5 seconds). *** * `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/~/api-keys) page in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). *** * `organizationSyncOptions?` * [OrganizationSyncOptions](#organization-sync-options) | undefined Used to activate a specific [Organization](/docs/guides/organizations/overview) or [Personal Account](/docs/guides/dashboard/overview) based on URL path parameters. If there's a mismatch between the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. in the session (e.g., as reported by auth()) and the Organization indicated by the URL, the middleware will attempt to activate the Organization specified in the URL. *** * `proxyUrl?` * `string` Specify the URL of the proxy, if using a proxy. *** * `signInUrl` * `string` The full URL or path to your sign-in page. Needs to point to your primary application on the client-side. **Required 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` The full URL or path to your sign-up page. Needs to point to your primary application on the client-side. **Required 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. *** * `publishableKey` * `string` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `secretKey?` * `string` The Clerk Secret Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The `CLERK_ENCRYPTION_KEY` environment variable must be set when providing `secretKey` as an option, refer to [Dynamic keys](#dynamic-keys). --- title: Clerk TanStack React Start SDK description: The Clerk TanStack React Start SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. sdk: tanstack-react-start sdkScoped: "true" canonical: /docs/reference/tanstack-react-start/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: tanstack-react-start notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,go,astro,nuxt,vue,ruby,js-backend activeSdk: tanstack-react-start sourceFile: /docs/reference/tanstack-react-start/overview.mdx --- The Clerk TanStack React Start SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Refer to the [quickstart guide](/docs/tanstack-react-start/getting-started/quickstart) to get started. ## Client-side helpers Because the Tanstack React Start SDK is built on top of the React SDK, you can use the hooks that the React SDK provides. These hooks include access to the Clerk object, User object, Organization object, and a set of useful helper methods for signing in and signing up. Learn more in the React SDK reference. * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() ## Server-side helpers The following references show how to integrate Clerk features into applications using TanStack React Start server functions and API routes. * [`auth()`](/docs/reference/tanstack-react-start/auth) * [`clerkMiddleware()`](/docs/reference/tanstack-react-start/clerk-middleware) ### `Auth` object The `auth()` returns an `Auth` object. This JavaScript object contains important information like session data, your user's ID, as well as their Organization ID. Learn more about the `Auth` object here. --- title: "`ClerkApp`" description: Clerk provides a ClerkApp wrapper to provide the authentication state to your React tree. sdk: remix sdkScoped: "true" canonical: /docs/reference/remix/clerk-app lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: remix notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/remix/clerk-app.mdx --- > \[!WARNING] > The Remix SDK is in maintenance mode and will only receive security updates. Please migrate to the React Router SDK for continued development and new features. Clerk provides a `ClerkApp` wrapper to provide the authentication state to your React tree. This helper works with Remix SSR out-of-the-box and follows the "higher-order component" paradigm. ## Usage ```tsx {{ filename: 'app/root.tsx' }} // The rest of your code function App() { return ( ) } // Wrap your app with `ClerkApp` export default ClerkApp(App) ``` ## Pass configuration options To pass configuration [options](#clerk-app-options) to `ClerkApp`, you can pass an optional argument to the `ClerkApp` function. ```tsx {{ filename: 'app/root.tsx' }} // Wrap your app in ClerkApp(app) export default ClerkApp(App, { publishableKey: import.meta.env.VITE_CLERK_PUBLISHABLE_KEY, }) ``` ## `ClerkApp` options {/* GH file: https://github.com/clerk/javascript/blob/main/packages/react/src/types.ts */} * `afterMultiSessionSingleSignOutUrl` * `string` The full URL or path to navigate to after a signing out from a currently active account in a multi-session app. *** * `afterSignOutUrl` * `string` The full URL or path to navigate to after a successful sign-out. *** * `allowedRedirectOrigins` * `Array` An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. *** * `allowedRedirectProtocols` * `Array` An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. *** * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `clerkJSUrl` * `string` Define the URL that `@clerk/clerk-js` should be hot-loaded from. *** * `clerkJSVariant` * `'headless' | ''` If your web application only uses control components, you can set this value to `headless` and load a minimal ClerkJS bundle for optimal page performance. *** * `clerkJSVersion` * `string` Define the npm version for `@clerk/clerk-js`. *** * `domain` * `string | ((url: URL) => boolean)` **Required if your application is a satellite application.** Sets the domain of the satellite application. *** * `dynamic` * `boolean` (For Next.js only) Indicates whether or not Clerk should make dynamic auth data available based on the current request. Defaults to `false`. Opts the application into dynamic rendering when `true`. For more information, see Next.js rendering modes and Clerk. *** * `initialState` * `InitialState` Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). *** * `isSatellite` * `boolean | ((url: URL) => boolean)` Whether the application is a satellite application. *** * `localization` * [Localization](/docs/guides/customizing-clerk/localization) | undefined Optional object to localize your components. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `nonce` * `string` This nonce value will be passed to the `@clerk/clerk-js` script tag. Use it to implement a [strict-dynamic CSP](/docs/guides/secure/best-practices/csp-headers#implementing-a-strict-dynamic-csp). Requires the `dynamic` prop to also be set. *** * `publishableKey` * `string` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `proxyUrl` * `string | ((url: URL) => string)` The URL that Clerk will proxy requests to. Required for applications that run behind a reverse proxy. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). *** * `routerPush` * `(to: string) => Promise | void` A function which takes the destination path as an argument and performs a "push" navigation. *** * `routerReplace` * `(to: string) => Promise | void` A function which takes the destination path as an argument and performs a "replace" navigation. *** * `sdkMetadata` * `{ name: string; version: string; environment: string }` Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). *** * `selectInitialSession` * `(client: ClientResource) => ActiveSessionResource | null` By default, the last active session is used during client initialization. This option allows you to override that behavior, e.g. by selecting a specific session. *** * `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. *** * `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. *** * `standardBrowser` * `boolean` By default, ClerkJS is loaded with the assumption that cookies can be set (browser setup). On native platforms this value must be set to `false`. *** * `supportEmail` * `string` Optional support email for display in authentication screens. Will only affect Clerk components and not [Account Portal](/docs/guides/customizing-clerk/account-portal) pages. *** * `syncHost` * `string` **Chrome Extension only** To enable, pass the URL of the web application that the extension will sync the authentication state from. See the dedicated guide for more information. *** * `taskUrls` * `Record` The URL paths users are redirected to after sign-up or sign-in when specific session tasks need to be completed. For example, `{ 'choose-organization': '/onboarding/choose-organization' }` redirects users to `/onboarding/choose-organization` after sign-up if they need to choose an organization. *** * `telemetry` * `false | { disabled: boolean; debug: boolean } | undefined` Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). If set to `debug`, telemetry events are only logged to the console and not sent to Clerk. *** * `touchSession` * `boolean` By default, [the Clerk Frontend API `touch` endpoint](/docs/reference/frontend-api/tag/sessions/post/v1/client/sessions/\{session_id}/touch){{ target: '_blank' }} is called during page focus to keep the last active session alive. This option allows you to disable this behavior. *** * `waitlistUrl` * `string` The full URL or path to the waitlist page. If `undefined`, will redirect to the [Account Portal waitlist page](/docs/guides/customizing-clerk/account-portal#waitlist). [components-ref]: /docs/reference/components/overview [ap-ref]: /docs/guides/customizing-clerk/account-portal --- title: "`rootAuthLoader()`" description: The `rootAuthLoader` function is a helper function that provides the authentication state to your Remix application. sdk: remix sdkScoped: "true" canonical: /docs/reference/remix/root-auth-loader lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: remix notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/remix/root-auth-loader.mdx --- > \[!WARNING] > The Remix SDK is in maintenance mode and will only receive security updates. Please migrate to the React Router SDK for continued development and new features. The `rootAuthLoader()` function is a helper function that provides the authentication state to your Remix application. ## Usage 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 To configure Clerk in your Remix app, you must export the `rootAuthLoader()` function as the root `loader()` function. ```tsx {{ filename: 'app/root.tsx', mark: [1, [4, 5], [15, 16]] }} // Your other imports // Import `rootAuthLoader` import { rootAuthLoader } from '@clerk/remix/ssr.server' // Export `rootAuthLoader()` as the root route `loader` export const loader: LoaderFunction = (args) => rootAuthLoader(args) // The rest of your code ``` ### With a callback 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' }} // Your imports export const loader: LoaderFunction = (args) => { return rootAuthLoader(args, ({ req }) => { const { sessionId, userId, getToken } = req.auth // Add logic to fetch data return { yourData: 'here' } }) } // The rest of your code ``` ### 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' }} // Your imports export const loader: LoaderFunction = (args) => { return rootAuthLoader( args, ({ req }) => { const { sessionId, userId, getToken } = req.auth // Add logic to fetch data return { yourData: 'here' } }, { signInForceRedirectUrl: '/dashboard', }, ) } // The rest of your code ``` ## `rootAuthLoader()` options 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/~/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/~/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/~/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. --- title: Clerk Remix SDK description: The Clerk Remix SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. sdk: remix sdkScoped: "true" canonical: /docs/reference/remix/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: remix notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: remix sourceFile: /docs/reference/remix/overview.mdx --- > \[!WARNING] > The Remix SDK is in maintenance mode and will only receive security updates. Please migrate to the React Router SDK for continued development and new features. The Clerk Remix SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Refer to the [quickstart guide](/docs/remix/getting-started/quickstart) to get started. ## `ClerkApp` The `ClerkApp` component is a wrapper that provides Clerk's authentication state to your React tree. It is required to configure Clerk in your Remix application. Learn more in the [reference](/docs/reference/remix/clerk-app). ## `rootAuthLoader()` The `rootAuthLoader()` function is a helper function that provides the authentication state to your Remix application. It is required to configure Clerk in your Remix application. Learn more in the [reference](/docs/reference/remix/root-auth-loader). ## Client-side helpers Because the Remix SDK is built on top of the Clerk React SDK, you can use the hooks that the React SDK provides. These hooks include access to the Clerk object, User object, Organization object, and a set of useful helper methods for signing in and signing up. * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() ## Server-side helpers ### `getAuth()` The `getAuth()` helper retrieves authentication state from the request object. Returns the Auth{{ target: '_blank' }} object. Accepts the following parameters: * `args` The arguments object. *** * `opts?` An optional object that can be used to configure the behavior of the `getAuth()` function. It accepts the following properties: * `secretKey?`: A string that represents the Secret Key used to sign the session token. If not provided, the Secret Key is retrieved from the environment variable `CLERK_SECRET_KEY`. See the [dedicated guide](/docs/remix/guides/users/reading#server-side) for example usage. ## SPA mode Clerk supports [Remix in SPA mode](https://remix.run/docs/en/main/guides/spa-mode) out-of-the-box. Learn more in the [tutorial](/docs/guides/development/spa-mode). --- title: "`getAuth()`" description: Access and manage the current user's authentication state in your React application with Clerk's getAuth() helper. sdk: react-router sdkScoped: "true" canonical: /docs/reference/react-router/get-auth lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: react-router notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/react-router/get-auth.mdx --- The `getAuth()` helper retrieves the current user's authentication state from the request object. ## Parameters * `args` * `LoaderFunctionArgs` The arguments object. *** * `opts?` * `{acceptsToken: TokenType, treatPendingAsSignedOut: boolean }` An optional object that can be used to configure the behavior of the `getAuth()` function. It accepts the following properties: * `acceptsToken?`: The type of authentication token(s) to accept. Valid values are: * `'session_token'` - authenticates a user session. * `'oauth_token'` - authenticates a machine request using OAuth. * `'m2m_token'` - authenticates a machine to machine request. * `'api_key'` - authenticates a machine request using API keys. Can be set to: * A single token type. * An array of token types. * `'any'` to accept all available token types. Defaults to `'session_token'`. * `treatPendingAsSignedOut?`: A boolean that indicates whether to treat pending session status as signed out. Defaults to `true`. ## Returns `getAuth()` returns the `Auth` object. This JavaScript object contains important information like the current user's session ID, user ID, and Organization ID. Learn more about the Auth object{{ target: '_blank' }}. ## Usage See the [dedicated guide](/docs/react-router/guides/users/reading#server-side) for example usage. --- title: "`clerkMiddleware()` | React Router" description: The `clerkMiddleware()` function allows you to protect your React Router application using middleware. sdk: react-router sdkScoped: "true" canonical: /docs/reference/react-router/clerk-middleware lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: react-router notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/react-router/clerk-middleware.mdx --- 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 ``` 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 The `clerkMiddleware()` 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']` *** * `clockSkewInMs?` * `number` Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to 5000 ms (5 seconds). *** * `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/~/api-keys) page in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). *** * `organizationSyncOptions?` * [OrganizationSyncOptions](#organization-sync-options) | undefined Used to activate a specific [Organization](/docs/guides/organizations/overview) or [Personal Account](/docs/guides/dashboard/overview) based on URL path parameters. If there's a mismatch between the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. in the session (e.g., as reported by auth()) and the Organization indicated by the URL, the middleware will attempt to activate the Organization specified in the URL. *** * `proxyUrl?` * `string` Specify the URL of the proxy, if using a proxy. *** * `signInUrl` * `string` The full URL or path to your sign-in page. Needs to point to your primary application on the client-side. **Required 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` The full URL or path to your sign-up page. Needs to point to your primary application on the client-side. **Required 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. *** * `publishableKey` * `string` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `secretKey?` * `string` The Clerk Secret Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The `CLERK_ENCRYPTION_KEY` environment variable must be set when providing `secretKey` as an option, refer to [Dynamic keys](#dynamic-keys). ### `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 Organization 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 OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the 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 \. 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` | ❌ | --- title: Clerk React Router SDK description: The Clerk React Router SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. sdk: react-router sdkScoped: "true" canonical: /docs/reference/react-router/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: react-router notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/react-router/overview.mdx --- The Clerk React Router SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Refer to the [quickstart guide](/docs/react-router/getting-started/quickstart) to get started. ## Client-side helpers Because the React Router SDK is built on top of the React SDK, you can use the hooks that the React SDK provides. These hooks include access to the Clerk object, User object, Organization object, and a set of useful helper methods for signing in and signing up. Learn more in the React SDK reference. * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() ## Server-side helpers 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 React Router can be integrated with Clerk in three ways: * **Framework mode (recommended):** Configure your app using [Clerk's React Router SDK](/docs/react-router/getting-started/quickstart). * **Declarative mode:** Manually integrate React Router into your React + Vite app using [declarative mode](/docs/guides/development/declarative-mode). * **Data mode:** Use React Router's data APIs to load data and manage state in your Clerk app. To use React Router in data mode, see the [demo repository](https://github.com/clerk/clerk-react-quickstart/blob/integrate-react-router-dom-using-data-router-method/src/main.tsx). --- title: "`rootAuthLoader()`" description: The rootAuthLoader() function configures Clerk to handle authentication state for React Router routes. sdk: react-router sdkScoped: "true" canonical: /docs/reference/react-router/root-auth-loader lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: react-router notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react-router sourceFile: /docs/reference/react-router/root-auth-loader.mdx --- The `rootAuthLoader()` function configures Clerk to handle authentication state for React Router routes, allowing easy access to user session information in your app. ## Usage 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 ### 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/server' import type { Route } from './+types/root' export async function loader(args: Route.LoaderArgs) { return rootAuthLoader(args) } ``` ### With a callback 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/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' } }) } ``` --- title: "`clerkPlugin()`" description: The clerkPlugin() function is a Fastify plugin that integrates Clerk's authentication into your application. sdk: fastify sdkScoped: "true" canonical: /docs/reference/fastify/clerk-plugin lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: fastify notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: fastify sourceFile: /docs/reference/fastify/clerk-plugin.mdx --- The `clerkPlugin()` function is a Fastify plugin that integrates Clerk's authentication into your application. The function checks request cookies and headers for a session JWT. If valid, it attaches the Auth{{ target: '_blank' }} object to the `request` object under the `auth` key. You can register the plugin for [all routes](#example-register-clerk-plugin-for-all-routes) or [limit it to specific ones](#example-register-clerk-plugin-for-specific-routes). ### Example: Register `clerkPlugin()` for all routes ```ts import 'dotenv/config' // dotenv must be imported before @clerk/fastify import Fastify from 'fastify' import { clerkPlugin } from '@clerk/fastify' const fastify = Fastify({ logger: true }) fastify.register(clerkPlugin) const start = async () => { try { await fastify.listen({ port: 8080 }) } catch (error) { fastify.log.error(error) process.exit(1) } } start() ``` ### Example: Register `clerkPlugin()` for specific routes To apply Clerk authentication only to specific routes, register the plugin in the scope of those routes. In the following example, the application is split into protected and public routes: ```ts {{ filename: 'index.ts', collapsible: true }} import 'dotenv/config' // dotenv must be imported before @clerk/fastify import Fastify, { FastifyPluginCallback } from 'fastify' import { clerkClient, clerkPlugin, getAuth } from '@clerk/fastify' const fastify = Fastify({ logger: true }) const protectedRoutes: FastifyPluginCallback = (instance, options, done) => { instance.register(clerkPlugin) instance.get('/protected', async (req, reply) => { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(req) // Protect the route from unauthenticated users if (!isAuthenticated) { return reply.code(403).send({ message: 'Access denied. Authentication required.' }) } // Use `clerkClient` to access Clerk's JS Backend SDK methods const user = await clerkClient.users.getUser(userId) // Only authenticated users will see the following message reply.send({ message: 'This is a protected route.', user }) }) done() } const publicRoutes: FastifyPluginCallback = (instance, options, done) => { instance.get('/', async (req, reply) => { reply.send({ message: 'This is a public route.' }) }) done() } fastify.register(protectedRoutes) fastify.register(publicRoutes) const start = async () => { try { await fastify.listen({ port: 8080 }) } catch (error) { fastify.log.error(error) process.exit(1) } } start() ``` ### `clerkPlugin()` options The `clerkPlugin()` function accepts the following options: * `secretKey` (required) * `string` The Clerk Secret Key from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `jwtKey?` * `string` The **JWKS Public Key** from the [**API keys**](https://dashboard.clerk.com/~/api-keys) in the Clerk Dashboard. For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). *** * `publishableKey?` * `string` The Clerk Publishable Key from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `domain?` * `string` The domain of a [satellite application](/docs/guides/dashboard/dns-domains/satellite-domains) in a multi-domain setup. *** * `isSatellite?` * `boolean` Whether the instance is a satellite domain in a multi-domain setup. Defaults to `false`. *** * `proxyUrl?` * `string` The proxy URL from a multi-domain setup. *** * `sdkMetadata?` * `{ name: string, version: string }` Metadata about the SDK. *** * `telemetry?` * `{ disabled: boolean, debug: boolean }` [Telemetry](/docs/guides/how-clerk-works/security/clerk-telemetry) configuration. *** * `userAgent?` * `string` The User-Agent request header passed to the Clerk API. *** * `apiUrl?` * `string` The [Clerk Backend API](/docs/reference/backend-api){{ target: '_blank' }} endpoint. Defaults to `'https://api.clerk.com'`. *** * `apiVersion?` * `string` The version passed to the Clerk API. Defaults to `'v1'`. *** * `audience?` * `string | string[]` A string or list of [audiences](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3). *** * `taskUrls?` * `Record` The URL paths users are redirected to after sign-up or sign-in when specific session tasks need to be completed. For example, `{ 'choose-organization': '/onboarding/choose-organization' }` redirects users to `/onboarding/choose-organization` after sign-up if they need to choose an Organization. * `hookName` * `'onRequest' | 'preHandler'` Determines which of Fastify's [Request/Reply hooks](https://fastify.dev/docs/latest/Reference/Hooks/#requestreply-hooks) Clerk should run. Default: `'preHandler'` #### Example: Pass `hookName` in `clerkPlugin()` options ```ts fastify.register(clerkPlugin, { hookName: 'preHandler', }) ``` --- title: Clerk Fastify SDK description: The Clerk Fastify SDK provides a powerful set of tools and utilities to seamlessly integrate authentication, user management, and Organization management into your Fastify application. sdk: fastify sdkScoped: "true" canonical: /docs/reference/fastify/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: fastify notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: fastify sourceFile: /docs/reference/fastify/overview.mdx --- The Clerk Fastify SDK provides a powerful set of tools and utilities to seamlessly integrate authentication, user management, and Organization management into your Fastify application. Refer to the [quickstart guide](/docs/fastify/getting-started/quickstart) to get started. ## `clerkPlugin()` The `clerkPlugin()` function is required to integrate Clerk's authentication into your application. The function checks request cookies and headers for a session JWT. If valid, it attaches the Auth{{ target: '_blank' }} object to the `request` object under the `auth` key. See the [reference doc](/docs/reference/fastify/clerk-plugin) for more information. ## `getAuth()` The `getAuth()` helper retrieves the current user's authentication state from the `request` object. It returns the Auth object{{ target: '_blank' }}, which includes helpful authentication information like the user's ID, session ID, and Organization ID. It's also useful for protecting routes. See the [reference doc](/docs/reference/fastify/get-auth) for more information. --- title: "`getAuth()`" description: The getAuth() helper retrieves the current user's authentication state from the request object. sdk: fastify sdkScoped: "true" canonical: /docs/reference/fastify/get-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: fastify notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: fastify sourceFile: /docs/reference/fastify/get-auth.mdx --- The `getAuth()` helper retrieves the current user's authentication state from the `request` object. It returns the Auth object{{ target: '_blank' }}. See the Next.js reference documentation{{ target: '_blank' }} for more examples on how to use the returned `Auth` object. ### `getAuth()` options * `request` The request object. *** * `opts?` * `{acceptsToken: TokenType, treatPendingAsSignedOut: boolean }` An optional object that can be used to configure the behavior of the `getAuth()` function. It accepts the following properties: * `acceptsToken?`: The type of authentication token(s) to accept. Valid values are: * `'session_token'` - authenticates a user session. * `'oauth_token'` - authenticates a machine request using OAuth. * `'m2m_token'` - authenticates a machine to machine request. * `'api_key'` - authenticates a machine request using API keys. Can be set to: * A single token type. * An array of token types. * `'any'` to accept all available token types. Defaults to `'session_token'`. * `treatPendingAsSignedOut?`: A boolean that indicates whether to treat pending session status as signed out. Defaults to `true`. ### Example: Use `getAuth()` to retrieve the `userId` The following example uses `getAuth()` to protect a route and load the user's data. If the user is authenticated, their `userId` is passed to clerkClient.users.getUser(){{ target: '_blank' }} to get the current user's User{{ target: '_blank' }} object. If not authenticated, the request is rejected with a `401` status code. ```ts // dotenv must be imported before @clerk/fastify import 'dotenv/config' import Fastify from 'fastify' import { clerkClient, clerkPlugin, getAuth } from '@clerk/fastify' const fastify = Fastify({ logger: true }) fastify.register(clerkPlugin) // Use `getAuth()` to protect this route fastify.get('/protected', async (request, reply) => { try { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(request) // If user isn't authenticated, return a 401 error if (!isAuthenticated) { return reply.code(401).send({ error: 'User not authenticated' }) } // Use `clerkClient` to access Clerk's JS Backend SDK methods // and get the user's User object const user = await clerkClient.users.getUser(userId) return reply.send({ message: 'User retrieved successfully', user, }) } catch (error) { fastify.log.error(error) return reply.code(500).send({ error: 'Failed to retrieve user' }) } }) const start = async () => { try { await fastify.listen({ port: 8080 }) } catch (error) { fastify.log.error(error) process.exit(1) } } start() ``` For examples on how to use `getAuth()` to perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., see the [dedicated guide](/docs/guides/secure/authorization-checks). ### Example: Protect a route based on token type The following example uses `getAuth()` to protect the route based on token type: * It accepts any token type `(acceptsToken: 'any')` from the request. * If the token is a `session_token`, it logs that the request is from a user session. * Otherwise, it logs that the request uses a machine token and specifies its type. ```ts import Fastify from 'fastify' import { getAuth } from '@clerk/fastify' const fastify = Fastify() fastify.get('/path', (request, reply) => { // Use `getAuth()` to protect a route based on token type const authObject = getAuth(req, { acceptsToken: 'any' }) if (authObject.tokenType === 'session_token') { console.log('This is a session token from a user') } else { console.log(`This is a ${authObject.tokenType} token`) } }) ``` --- title: Clerk Express SDK description: The Clerk Express SDK provides a powerful set of tools and utilities to seamlessly integrate authentication, user management, and Organization management into your Express application. sdk: expressjs sdkScoped: "true" canonical: /docs/reference/express/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: expressjs notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expressjs sourceFile: /docs/reference/express/overview.mdx --- The Clerk Express SDK provides a powerful set of tools and utilities to seamlessly integrate authentication, user management, and Organization management into your Express application. Refer to the [quickstart](/docs/expressjs/getting-started/quickstart) to get started. > \[!IMPORTANT] > If you are upgrading from the Node SDK, see the [upgrade guide](/docs/guides/development/upgrading/upgrade-guides/node-to-express) for more information. ## `clerkMiddleware()` The `clerkMiddleware()` middleware checks the request's cookies and headers for a session JWT and if found, attaches the Auth object to the `request` object under the `auth` key. See the [reference doc](/docs/reference/express/clerk-middleware) for more information. ## `requireAuth()` The `requireAuth()` middleware acts similarly to [`clerkMiddleware()`](#clerk-middleware), but also protects your routes by redirecting unauthenticated users to the homepage. See the [reference doc](/docs/reference/express/require-auth) for more information. ## `getAuth()` The `getAuth()` helper retrieves authentication state from the `request` object. It returns the Auth object{{ target: '_blank' }}, which includes helpful authentication information like the user's ID, session ID, and Organization ID. It's also useful for protecting routes. See the [reference doc](/docs/reference/express/get-auth) for more information. ## `clerkClient` Clerk's JS Backend SDK provides access to Backend API resources and low-level authentication utilities for JavaScript environments. For example, to retrieve a list of all users in your application, you can use the `users.getUserList()` method from the JS Backend SDK instead of manually making a fetch request to the `https://api.clerk.com/v1/users` endpoint. All resource operations are mounted as sub-APIs on the `clerkClient` object. See the reference documentation{{ target: '_blank' }} for more information. ### Example: Use `clerkClient` to get a user's information The following example uses `clerkClient` to get information about the currently signed-in user. If the user is authenticated, their `userId` is passed to clerkClient.users.getUser(){{ target: '_blank' }} to get the current user's User{{ target: '_blank' }} object. If not authenticated, the request is rejected with a `401` status code. ```js import { clerkClient, clerkMiddleware, getAuth } from '@clerk/express' import express from 'express' const app = express() const PORT = 3000 // Apply `clerkMiddleware()` to all routes app.use(clerkMiddleware()) app.get('/user', async (req, res) => { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(req) // If user isn't authenticated, return a 401 error if (!isAuthenticated) { return res.status(401).json({ error: 'User not authenticated' }) } // Use `clerkClient` to access Clerk's JS Backend SDK methods // and get the user's User object const user = await clerkClient.users.getUser(userId) res.json(user) }) // Start the server and listen on the specified port app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`) }) ``` --- title: "`clerkMiddleware()`" description: The clerkMiddleware() function checks the request's cookies and headers for a session JWT and if found, attaches the Auth object to the request object under the auth key. sdk: expressjs sdkScoped: "true" canonical: /docs/reference/express/clerk-middleware lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expressjs notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expressjs sourceFile: /docs/reference/express/clerk-middleware.mdx --- The `clerkMiddleware()` function checks the request's cookies and headers for a session JWT and if found, attaches the Auth object to the `request` object under the `auth` key. **It must be set before any other middleware.** > \[!TIP] > Even if you are using [`requireAuth()`](/docs/reference/express/require-auth) middleware, you should still use `clerkMiddleware()` as it will provide authentication state to routes that don't use `requireAuth()`. See the [example](#example-use-clerk-middleware-require-auth-and-get-auth-together). ```js import { clerkMiddleware } from '@clerk/express' const app = express() // Pass no parameters app.use(clerkMiddleware()) // Pass options app.use(clerkMiddleware(options)) ``` ## Example: Use `clerkMiddleware()`, `requireAuth()`, and `getAuth()` together The following example demonstrates how to use `clerkMiddleware()`, [`requireAuth()`](/docs/reference/express/require-auth), and [`getAuth()`](/docs/reference/express/get-auth) together. `clerkMiddleware()` will provide authentication state to routes that don't use `requireAuth()`, `requireAuth()` will provide authentication state to a route and also protect the route based on authentication status, and `getAuth()` can be used in a number of ways. In this example, `getAuth()` is used to protect the route based on authorization status. ```js import { clerkMiddleware, getAuth, requireAuth } from '@clerk/express' import express from 'express' const app = express() const PORT = 3000 // Apply `clerkMiddleware()` to all routes app.use(clerkMiddleware()) // Use `getAuth()` to protect a route based on authorization status const hasPermission = (req, res, next) => { const auth = getAuth(req) // Handle if the user is not authorized if (!auth.has({ permission: 'org:admin:example' })) { return res.status(403).send('Forbidden') } return next() } // Use `requireAuth()` to protect a route based on authentication status // If user is not authenticated, requireAuth() will redirect back to the homepage // Then, use the `hasPermission` function created above to protect the route based on authorization status app.get('/path', requireAuth(), hasPermission, (req, res) => res.json(req.auth)) // This route is not protected but it will have authentication state // attached to the request object because `clerkMiddleware()` was applied to all routes app.get('/path2', (req, res) => res.json(req.auth)) // Start the server and listen on the specified port app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`) }) ``` ### `clerkMiddleware()` options The `clerkMiddleware()` 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']` *** * `clockSkewInMs?` * `number` Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to 5000 ms (5 seconds). *** * `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/~/api-keys) page in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). *** * `organizationSyncOptions?` * [OrganizationSyncOptions](#organization-sync-options) | undefined Used to activate a specific [Organization](/docs/guides/organizations/overview) or [Personal Account](/docs/guides/dashboard/overview) based on URL path parameters. If there's a mismatch between the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. in the session (e.g., as reported by auth()) and the Organization indicated by the URL, the middleware will attempt to activate the Organization specified in the URL. *** * `proxyUrl?` * `string` Specify the URL of the proxy, if using a proxy. *** * `signInUrl` * `string` The full URL or path to your sign-in page. Needs to point to your primary application on the client-side. **Required 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` The full URL or path to your sign-up page. Needs to point to your primary application on the client-side. **Required 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. *** * `publishableKey` * `string` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `secretKey?` * `string` The Clerk Secret Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The `CLERK_ENCRYPTION_KEY` environment variable must be set when providing `secretKey` as an option, refer to [Dynamic keys](#dynamic-keys). * `clerkClient` * ClerkClient An instance of the `ClerkClient` class. This is used to interact with the Clerk API. *** * `debug` * `boolean` A flag to enable debug mode. When set to `true`, the middleware will log debug information to the console. Defaults to `false`. *** * `enableHandshake` * `boolean` 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` 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 Organization 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 OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the 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 \. 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` | ❌ | --- title: "`getAuth()`" description: The getAuth() helper retrieves authentication state from the request object. sdk: expressjs sdkScoped: "true" canonical: /docs/reference/express/get-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expressjs notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expressjs sourceFile: /docs/reference/express/get-auth.mdx --- The `getAuth()` helper retrieves authentication state from the `request` object. See the Next.js reference documentation for more examples on how to use the returned `auth` object. ## Usage The `getAuth()` helper can be used to protect routes based on authentication status, authorization status, and token type. It also offers more granular control over how to handle unauthenticated users - you can redirect them to the sign-in page, return a `401` status code, or perform whatever action you need. Unlike [`requireAuth()`](/docs/reference/express/require-auth), it **can** be used to protect API routes. > \[!QUIZ] > When should you use `getAuth()` instead of [`requireAuth()`](/docs/reference/express/require-auth)? > > *** > > The [`requireAuth()`](/docs/reference/express/require-auth) helper protects a route based on *authentication* status, and redirects unauthenticated users to the sign-in page. It can only be used in full-stack applications, and cannot be used to protect API routes. The `getAuth()` helper offers more options for protecting routes, more granular control over how to protect them, and can be used to protect API routes. ### Example: Protect a route based on authentication status The following example uses `getAuth()` to protect the route based on *authentication* status. ```js import { clerkMiddleware, getAuth } from '@clerk/express' import express from 'express' const app = express() const PORT = 3000 // Apply `clerkMiddleware()` to all routes app.use(clerkMiddleware()) // Use `getAuth()` to protect a route based on authentication status app.get('/path', (req, res) => { const auth = getAuth(req) if (!auth.isAuthenticated) { return res.status(401).send('User not authenticated') } return res.json(auth) }) app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`) }) ``` ### Example: Protect a route based on authorization status The following example demonstrates how to use [`requireAuth()`](/docs/reference/express/require-auth) and `getAuth()` together. `requireAuth()` protects the route based on *authentication* status while `getAuth()` protects the route based on *authorization* status. It also demonstrates how to use both `clerkMiddleware()` and `requireAuth()` together, as `clerkMiddleware()` will provide authentication state to routes that don't use `requireAuth()`. ```js import { clerkMiddleware, getAuth, requireAuth } from '@clerk/express' import express from 'express' const app = express() const PORT = 3000 // Apply `clerkMiddleware()` to all routes app.use(clerkMiddleware()) // Use `getAuth()` to protect a route based on authorization status const hasPermission = (req, res, next) => { const auth = getAuth(req) // Handle if the user is not authorized if (!auth.has({ permission: 'org:admin:example' })) { return res.status(403).send('Forbidden') } return next() } // Use `requireAuth()` to protect a route based on authentication status // If user is not authenticated, requireAuth() will redirect back to the homepage // Then, use the `hasPermission` function created above to protect the route based on authorization status app.get('/path', requireAuth(), hasPermission, (req, res) => res.json(req.auth)) // Start the server and listen on the specified port app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`) }) ``` For more examples on how to use `getAuth()` to perform authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks)., see the [dedicated guide](/docs/guides/secure/authorization-checks). ### Example: Protect a route based on token type The following example uses `getAuth()` to protect the route based on token type: * It accepts any token type `(acceptsToken: 'any')` from the request. * If the token is a `session_token`, it logs that the request is from a user session. * Otherwise, it logs that the request uses a machine token and specifies its type. ```js import express from 'express' import { clerkMiddleware, getAuth } from '@clerk/express' const app = express() const PORT = 3000 // Apply `clerkMiddleware()` to all routes app.use(clerkMiddleware()) app.get('/path', (req, res) => { // Use `getAuth()` to protect a route based on token type const authObject = getAuth(req, { acceptsToken: 'any' }) if (authObject.tokenType === 'session_token') { console.log('This is a session token from a user') } else { console.log(`This is a ${authObject.tokenType} token`) } }) ``` ## `getAuth()` options * `request` The request object. *** * `opts?` * `{acceptsToken: TokenType, treatPendingAsSignedOut: boolean }` An optional object that can be used to configure the behavior of the `getAuth()` function. It accepts the following properties: * `acceptsToken?`: The type of authentication token(s) to accept. Valid values are: * `'session_token'` - authenticates a user session. * `'oauth_token'` - authenticates a machine request using OAuth. * `'m2m_token'` - authenticates a machine to machine request. * `'api_key'` - authenticates a machine request using API keys. Can be set to: * A single token type. * An array of token types. * `'any'` to accept all available token types. Defaults to `'session_token'`. * `treatPendingAsSignedOut?`: A boolean that indicates whether to treat pending session status as signed out. Defaults to `true`. --- title: "`requireAuth()`" description: The requireAuth() middleware protects your routes by redirecting unauthenticated users to the homepage. sdk: expressjs sdkScoped: "true" canonical: /docs/reference/express/require-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expressjs notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expressjs sourceFile: /docs/reference/express/require-auth.mdx --- > \[!WARNING] > The `requireAuth()` helper redirects unauthenticated users to the sign-in page so it should only be used for full-stack Express apps. If your client and server run on different origins, see the [cross-origin requests](/docs/guides/development/making-requests#cross-origin-requests) guide. > > Do not use `requireAuth()` for API routes. For backend API calls, use [`clerkMiddleware()`](/docs/reference/express/overview#clerk-middleware) along with [`getAuth()`](/docs/reference/express/get-auth) to verify sessions and return standard HTTP status codes. The `requireAuth()` middleware functions similarly to `clerkMiddleware()`, in that it checks the request's cookies and headers for a session JWT and if found, attaches the Auth object to the `request` object under the `auth` key. However, its difference is that it also protects your routes by redirecting unauthenticated users to the homepage. It accepts the same [options](/docs/reference/express/clerk-middleware#clerk-middleware-options) as `clerkMiddleware()`. > \[!TIP] > It's recommended to use both `clerkMiddleware()` and `requireAuth()` together, as `clerkMiddleware()` will provide authentication state to routes that don't use `requireAuth()`. See the [example](/docs/reference/express/clerk-middleware#example-use-clerk-middleware-require-auth-and-get-auth-together). You can also specify a custom sign-in URL to redirect unauthenticated users to by setting the `CLERK_SIGN_IN_URL` environment variable or by passing a `signInUrl` option to the middleware. It's recommended to set the environment variable. ```js import { clerkMiddleware, requireAuth } from '@clerk/express' import express from 'express' const app = express() const PORT = 3000 // Apply middleware to all routes app.use(clerkMiddleware()) app.use(requireAuth()) // Apply middleware to a specific route // Redirects to the homepage if the user is not authenticated app.get('/protected', requireAuth(), (req, res) => { res.send('This is a protected route.') }) // Redirects to a custom URL if the user is not authenticated // Requires `CLERK_SIGN_IN_URL` to be set in env vars app.get('/protected', requireAuth({ signInUrl: process.env.CLERK_SIGN_IN_URL }), (req, res) => { res.send('This is a protected route.') }) // Redirects to a custom URL if the user is not authenticated // Uses the `signInUrl` option instead of the environment variable app.get('/protected', requireAuth({ signInUrl: '/sign-in' }), (req, res) => { res.send('This is a protected route.') }) // Start the server and listen on the specified port app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`) }) ``` ## `requireAuth()` options `requireAuth()` accepts the same [options](/docs/reference/express/clerk-middleware#clerk-middleware-options) as `clerkMiddleware()`. --- title: Clerk iOS SDK description: The Clerk iOS SDK provides a set of tools and utilities for handling authentication and user management. sdk: ios sdkScoped: "true" canonical: /docs/reference/ios/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ios notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: ios sourceFile: /docs/reference/ios/overview.mdx --- The Clerk iOS SDK provides a set of tools and utilities for handling authentication and user management. Refer to the [quickstart guide](/docs/ios/getting-started/quickstart) to get started. ## SDK Reference The full SDK Reference is available on [Swift Package Index](https://swiftpackageindex.com/clerk/clerk-ios/main/documentation/clerk). ## Installation with Swift Package Manager To install the Clerk iOS SDK using Swift Package Manager, follow the instructions in the [GitHub README](https://github.com/clerk/clerk-ios?tab=readme-ov-file#-installation). --- title: "`ClerkTheme`" description: Utilize Clerk's ClerkTheme to adjust the general styles of the iOS views, like colors, fonts, and design properties. sdk: ios sdkScoped: "true" canonical: /docs/reference/ios/clerk-theme lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ios notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: ios sourceFile: /docs/reference/ios/clerk-theme.mdx --- The `ClerkTheme` is used to customize the appearance of Clerk iOS views by adjusting colors, fonts, and design properties. It provides a comprehensive theming system that allows you to create a consistent visual experience across all Clerk views. ## Structure `ClerkTheme` consists of three main properties: * **`colors`** - Color properties for various UI elements. * **`fonts`** - Font properties for different text styles. * **`design`** - Design properties like border radius. ## Colors The `colors` property contains the following color options: * `primary` * `Color` The primary color used throughout the views. *** * `background` * `Color` The background color for containers. *** * `input` * `Color` The background color used for input fields. *** * `danger` * `Color` The color used for error states. *** * `success` * `Color` The color used for success states. *** * `warning` * `Color` The color used for warning states. *** * `foreground` * `Color` The color used for text. *** * `mutedForeground` * `Color` The color used for secondary text. *** * `primaryForeground` * `Color` The color used for text on the primary background. *** * `inputForeground` * `Color` The color used for text in input fields. *** * `neutral` * `Color` The color that will be used to generate the neutral shades the views use. *** * `ring` * `Color` The color of the ring when an interactive element is focused. *** * `muted` * `Color` The color used for muted backgrounds. *** * `shadow` * `Color` The base shadow color used in the views. *** * `border` * `Color` The base border color used in the views. ## Fonts The `fonts` property contains the following font options based on iOS Dynamic Type: * `largeTitle` * `Font` *** * `title` * `Font` *** * `title2` * `Font` *** * `title3` * `Font` *** * `headline` * `Font` *** * `subheadline` * `Font` *** * `body` * `Font` *** * `callout` * `Font` *** * `footnote` * `Font` *** * `caption` * `Font` *** * `caption2` * `Font` ## Design The `design` property contains the following design options: * `borderRadius` * `CGFloat` The border radius used throughout the views. By default, this is set to `6.0`. ## Usage You can customize Clerk iOS views by creating a `ClerkTheme` and applying it to the SwiftUI environment. ### Apply a custom theme to all Clerk views To customize all Clerk views in your app, create a `ClerkTheme` and apply it to your root view using the environment. ```swift import SwiftUI import Clerk struct MyApp: App { var body: some Scene { WindowGroup { ContentView() .environment(\.clerkTheme, customTheme) } } let customTheme = ClerkTheme( colors: .init( primary: .blue, ), design: .init( borderRadius: 12.0 ) ) } ``` ### Apply a theme to specific views You can apply a theme to specific Clerk views by using the environment modifier on individual views. The theme used here will apply to all children of this view. ```swift struct SignInView: View { var body: some View { AuthView() .environment(\.clerkTheme, customTheme) } let customTheme = ClerkTheme( colors: .init( primary: .purple, ) ) } ``` ### Adjust a specific property of the theme You can adjust a specific property of the theme by modifying a single property. ```swift struct SignInView: View { var body: some View { AuthView() .environment(\.clerkTheme.colors.primary, .green) } } ``` ### Custom fonts You can customize fonts by providing a font family name or individual font specifications. #### Using a font family name ```swift struct CustomFontView: View { var body: some View { AuthView() .environment(\.clerkTheme, customTheme) } let customTheme = ClerkTheme( fonts: .init(fontFamily: "Helvetica Neue") ) } ``` #### Using individual font specifications ```swift struct CustomFontView: View { var body: some View { AuthView() .environment(\.clerkTheme, customTheme) } let customTheme = ClerkTheme( fonts: .init( largeTitle: .init(name: "Helvetica Neue", size: 34.0), title: .init(name: "Helvetica Neue", size: 28.0), title2: .init(name: "Helvetica Neue", size: 22.0), title3: .init(name: "Helvetica Neue", size: 20.0), headline: .init(name: "Helvetica Neue", size: 18.0), ) ) } ``` ## Light and Dark Mode Support Clerk iOS views automatically support both light and dark mode appearance, adapting seamlessly to the user's system preferences.
![Light Mode](/docs/images/ui-components/ios-user-profile-view.png){{ style: { maxWidth: '230px' } }} ![Dark Mode](/docs/images/ui-components/ios-user-profile-view-dark.png){{ style: { maxWidth: '230px' } }}
### Using Asset Catalog Colors For more sophisticated appearance support, create colors in your Asset Catalog with separate light and dark variants: ```swift extension ClerkTheme { static let brandTheme = ClerkTheme( colors: .init( primary: Color(.brandPrimary), // Asset with light/dark variants background: Color(.brandBackground), foreground: Color(.brandText), danger: Color(.brandDanger) ) ) } ``` If Clerk's prebuilt theming doesn't meet your specific needs, you can create completely custom authentication flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`getToken()`" description: Use Clerk's iOS SDK to retrieve a token for a JWT template that is defined in the Clerk Dashboard. sdk: ios sdkScoped: "true" canonical: /docs/reference/ios/get-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ios notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: ios sourceFile: /docs/reference/ios/get-token.mdx --- The `getToken()` method retrieves the user's [session token](/docs/guides/sessions/session-tokens) or a [custom JWT template](/docs/guides/sessions/jwt-templates). This method uses a cache so a network request will only be made if the token in memory has expired. The TTL for a Clerk token is one minute. Tokens can only be generated if the user is signed in. ```swift {{ filename: 'Session' }} func getToken( _ options: GetTokenOptions = .init() ) async throws -> TokenResource? ``` ## Parameters * `options` * [`GetTokenOptions`](#get-token-options) Options that can be passed as parameters to the `getToken()` function. ### `GetTokenOptions` * `template` * `String?` The name of the JWT template from the [Clerk Dashboard](https://dashboard.clerk.com/~/jwt-templates) to generate a new token from. For example: 'firebase', 'grafbase', or your custom template's name. *** * `expirationBuffer` * `Double` If the cached token will expire within `{expirationBuffer}` seconds, fetch a new token instead. Max is 60 seconds. Defaults to 10 seconds. *** * `skipCache` * `Bool` Whether to skip the cache lookup and force a refresh of the token instead. Useful if the token claims are time-sensitive or depend on data that can be updated (e.g. user fields). Defaults to false. ## Example ```swift let session = Clerk.shared.session if let token = try await session?.getToken()?.jwt { // => "eyJhbGciOiJSUzI1NiIsImtpZC..." headers["Authorization"] = "Bearer \(token)" } ``` --- title: View Reference description: A list of Clerk's comprehensive suite of views designed to seamlessly integrate authentication and multi-tenancy into your application. sdk: ios sdkScoped: "true" canonical: /docs/reference/views/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ios notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: ios sourceFile: /docs/reference/views/overview.mdx --- Clerk offers a comprehensive suite of views designed to seamlessly integrate authentication and multi-tenancy into your application. With Clerk views, you can easily customize the appearance of authentication views and pages, manage the entire authentication flow to suit your specific needs, and even build robust SaaS applications. ## Clerk iOS views * [`AuthView`](/docs/reference/views/authentication/auth-view) - Renders a full authentication interface, supporting multiple sign-up and sign-in methods, multi-factor authentication (MFA), and password recovery flows. * [`UserButton`](/docs/reference/views/user/user-button) - Displays the signed-in user's profile image. * [`UserProfileView`](/docs/reference/views/user/user-profile-view) - Renders a complete user profile interface with personal information, security settings, account switching, and sign-out options. ## Customization To learn how to customize Clerk iOS views, see the [dedicated guide](/docs/reference/ios/clerk-theme). If Clerk's prebuilt views don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). ### Secured by Clerk branding > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By default, Clerk displays a **Secured by Clerk** badge on Clerk views. You can remove this branding by following these steps: 1. In the Clerk Dashboard, navigate to your application's [**Settings**](https://dashboard.clerk.com/~/settings). 2. Under **Branding**, toggle on the **Remove "Secured by Clerk" branding** option. * [Join our Discord](https://clerk.com/discord "Join Discord") * Join our official Discord server to chat with us directly and become a part of the Clerk community. * {} *** * [Need help?](/support "Get help") * Contact us through Discord, Twitter, or email to receive answers to your questions and learn more about Clerk. * {} --- title: "`AuthView`" description: Clerk's AuthView renders a UI for signing in and signing up users on iOS. sdk: ios sdkScoped: "true" canonical: /docs/reference/views/authentication/auth-view lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ios notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: ios sourceFile: /docs/reference/views/authentication/auth-view.mdx --- ![The AuthView renders a comprehensive authentication interface that handles both user sign-in and sign-up flows.](/docs/images/ui-components/ios-auth-view.png){{ style: { maxWidth: '460px' } }} The `AuthView` renders a comprehensive authentication interface with support for multiple sign-up flows and sign-in methods, multi-factor authentication, password reset, and account recovery. The functionality of the `AuthView` is controlled by the instance settings you specify in the [Clerk Dashboard](https://dashboard.clerk.com), such as [sign-in and sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) and [social connections](/docs/guides/configure/auth-strategies/social-connections/all-providers). ## Parameters * `mode` * `AuthView.Mode` The authentication mode that determines which flows are available to the user. Accepts the following values: * `.signInOrUp`: Automatically determines whether to sign users in or sign them up based on whether they already have an account. This is the default mode that provides seamless authentication without requiring users to choose between sign-in and sign-up. * `.signIn`: Restricts the interface to sign-in flows only. Users can only authenticate with existing accounts. * `.signUp`: Restricts the interface to sign-up flows only. Users can only create new accounts. Defaults to `.signInOrUp`. *** * `isDismissable` * `Bool` Whether the view can be dismissed by the user. When `true`, a dismiss button appears and the view closes automatically after successful authentication. When `false`, no dismiss button is shown. Defaults to `true`. ## Usage The following examples show how to use the `AuthView` in your iOS app. ### Basic usage as a dismissable sheet ```swift struct HomeView: View { @Environment(\.clerk) private var clerk @State private var authIsPresented = false var body: some View { ZStack { if clerk.user != nil { UserButton() .frame(width: 36, height: 36) } else { Button("Sign in") { authIsPresented = true } } } .sheet(isPresented: $authIsPresented) { AuthView() } } } ``` ### Full-screen authentication (non-dismissable) ```swift struct ProfileView: View { @Environment(\.clerk) private var clerk var body: some View { if clerk.user != nil { UserProfileView(isDismissable: false) } else { AuthView(isDismissable: false) } } } ``` ## Customization To learn how to customize Clerk iOS views, see the [dedicated guide](/docs/reference/ios/clerk-theme). If Clerk's prebuilt views don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`UserButton`" description: Clerk's UserButton renders a circular button that displays the current user's profile image and opens the user profile when tapped. sdk: ios sdkScoped: "true" canonical: /docs/reference/views/user/user-button lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ios notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: ios sourceFile: /docs/reference/views/user/user-button.mdx --- ![The UserButton is a circular button that displays the signed-in user's profile image.](/docs/images/ui-components/ios-user-button.png) The `UserButton` is a circular button that displays the signed-in user's profile image. When tapped, it presents a sheet with the [`UserProfileView`](/docs/reference/views/user/user-profile-view). > \[!IMPORTANT] > The `UserButton` only appears when a user is signed in. ## Usage The following examples show how to use the `UserButton` in your iOS app. ### Basic usage ```swift struct HomeView: View { @Environment(\.clerk) private var clerk var body: some View { ZStack { if clerk.user != nil { UserButton() .frame(width: 36, height: 36) } } } } ``` ### In a navigation toolbar ```swift struct ContentView: View { @Environment(\.clerk) private var clerk var body: some View { NavigationView { VStack { Text("Welcome!") } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { if clerk.user != nil { UserButton() .frame(width: 36, height: 36) } } } } } } ``` ## Customization To learn how to customize Clerk iOS views, see the [dedicated guide](/docs/reference/ios/clerk-theme). If Clerk's prebuilt views don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`UserProfileView`" description: Clerk's UserProfileView renders a beautiful, full-featured account management UI that allows users to manage their profile and security settings. sdk: ios sdkScoped: "true" canonical: /docs/reference/views/user/user-profile-view lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: ios notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: ios sourceFile: /docs/reference/views/user/user-profile-view.mdx --- ![The UserProfileView renders a comprehensive user profile interface that displays user information and provides account management options.](/docs/images/ui-components/ios-user-profile-view.png){{ style: { maxWidth: '460px' } }} The `UserProfileView` renders a comprehensive user profile interface that displays user information and provides account management options. It includes personal information, security settings, account switching, and sign-out functionality. > \[!IMPORTANT] > The `UserProfileView` only appears when a user is signed in. ## Parameters * `isDismissable` * `Bool` Whether the view can be dismissed by the user. When `true`, a dismiss button appears in the navigation bar and the view can be used in sheets or other dismissable contexts. When `false`, no dismiss button is shown, making it suitable for full-screen usage. Defaults to `true`. ## Usage The following examples show how to use the `UserProfileView` in your iOS app. ### Dismissible sheet presentation Present `UserProfileView` as a dismissible sheet when you want users to be able to close the profile view and return to the previous screen. ```swift struct MainView: View { @Environment(\.clerk) private var clerk @State private var profileIsPresented = false var body: some View { VStack { if clerk.user != nil { Button("Show Profile") { profileIsPresented = true } } } .sheet(isPresented: $profileIsPresented) { UserProfileView() } } } ``` ### Full-screen profile view Use `UserProfileView` as a full-screen view when you want to dedicate the entire screen to profile management. ```swift struct ProfileView: View { @Environment(\.clerk) private var clerk var body: some View { if clerk.user != nil { UserProfileView(isDismissable: false) } } } ``` ## Customization To learn how to customize Clerk iOS views, see the [dedicated guide](/docs/reference/ios/clerk-theme). If Clerk's prebuilt views don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). --- title: "`getToken()`" description: Use Clerk's Android SDK to retrieve a token for a JWT template that is defined in the Clerk Dashboard. sdk: android sdkScoped: "true" canonical: /docs/reference/android/get-token lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: android notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: android sourceFile: /docs/reference/android/get-token.mdx --- The `getToken()` method retrieves the user's [session token](/docs/guides/sessions/session-tokens) or a [custom JWT template](/docs/guides/sessions/jwt-templates). This method uses a cache so a network request will only be made if the token in memory has expired. The TTL for a Clerk token is one minute. Tokens can only be generated if the user is signed in. ```kotlin {{ filename: 'Session.kt' }} suspend fun Session.fetchToken( options: SessionGetTokenOptions = SessionGetTokenOptions() ): TokenResource? { return SessionTokenFetcher().getToken(this, options) } ``` ## Parameters * `options` * [`GetTokenOptions`](#get-token-options) Options that can be passed as parameters to the `getToken()` function. ### `GetTokenOptions` * `template` * `String?` The name of the JWT template from the [Clerk Dashboard](https://dashboard.clerk.com/last-active?path=jwt-templates) to generate a new token from. For example: 'firebase', 'grafbase', or your custom template's name. *** * `expirationBuffer` * `Long` If the cached token will expire within `{expirationBuffer}` seconds, fetch a new token instead. Max is 60 seconds. Defaults to 10 seconds. *** * `skipCache` * `Boolean` Whether to skip the cache lookup and force a refresh of the token instead. Useful if the token claims are time-sensitive or depend on data that can be updated (e.g. user fields). Defaults to false. ## Example ```kotlin val session = Clerk.session scope.launch { val token = session?.fetchToken()?.onSuccess { tokenResource -> headers["Authorization"] = "Bearer ${tokenResource.jwt}" } } ``` --- title: Clerk Android SDK description: The Clerk Android SDK provides a set of tools and utilities for handling authentication and user management. sdk: android sdkScoped: "true" canonical: /docs/reference/android/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: android notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: android sourceFile: /docs/reference/android/overview.mdx --- The Clerk Android SDK provides a set of tools and utilities for handling authentication and user management. Refer to the [quickstart guide](/docs/android/getting-started/quickstart) to get started. ## SDK Reference The full SDK Reference is available in the [Clerk Android SDK documentation](https://clerk-android.clerkstage.dev). --- title: Configure passkeys for Android description: Learn how to configure passkeys for your Android application. sdk: android sdkScoped: "true" canonical: /docs/reference/android/passkeys lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: android notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: android sourceFile: /docs/reference/android/passkeys.mdx --- [Passkeys](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#passkeys) are a secure, passwordless authentication method that use biometrics and a physical device to authenticate users. This guide shows you how to configure passkeys for your Android application. > \[!WARNING] > Android supports passkeys from version 9+. Passkeys will not work with Android emulators. You must use a physical device. ## Enable passkeys To use passkeys, first enable the strategy in the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/user-and-authentication?user_auth_tab=passkeys). ## Set up your Android app links in the Clerk Dashboard 1. In the Clerk Dashboard, navigate to the [**Native Applications**](https://dashboard.clerk.com/last-active?path=user-authentication/native-applications) page. 2. Select the **Android** tab. 3. Select **Add Android app**. 4. Fill out the form with the following information: * The `namespace` (This guide uses the default value `android_app`) * Your Android app's package name. You can find this in your app-level `build.gradle` file, typically formatted like `com.example.myclerkapp`. * The `SHA256 certificate fingerprints`. If you don't know where to find the `SHA256 certificate fingerprints`, see the [Android docs](https://developers.google.com/android/guides/client-auth). 5. After submitting the form, you can verify that your `assetlinks.json` file is properly associated with your app by using [Google's **Statement List Generator and Tester**](https://developers.google.com/digital-asset-links/tools/generator). ## Usage To learn how to use passkeys in your Android application, such as creating, deleting, and authenticating users with passkeys, see the [custom flow guide](/docs/guides/development/custom-flows/authentication/passkeys). --- title: Clerk Expo SDK description: The Clerk Expo SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. sdk: expo sdkScoped: "true" canonical: /docs/reference/expo/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo notAvailableSdks: nextjs,react,js-frontend,chrome-extension,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/expo/overview.mdx --- The Clerk Expo SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Refer to the [quickstart guide](/docs/expo/getting-started/quickstart) to get started. ## Available resources The Expo SDK gives you access to the following resources: ### Hooks The Expo SDK provides the following hooks: * [`useSignInWithApple()`](/docs/reference/expo/use-sign-in-with-apple) * [`useSSO()`](/docs/reference/expo/use-sso) * [`useLocalCredentials()`](/docs/reference/expo/use-local-credentials) Because the Expo SDK is built on top of the Clerk React SDK, you can use the hooks that the React SDK provides. These hooks include access to the Clerk object, User object, Organization object, and a set of useful helper methods for signing in and signing up. * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() ### Components * **Native** apps: * \ * \ * \ * \ * \ * For other components, see the [custom flows](#custom-flows) section for more information. * **Web** apps: * All Clerk components are available. See the component docs for more information. ## Custom flows > \[!WARNING] > Expo does not support email links. You can request this feature on [Clerk's roadmap](https://feedback.clerk.com/). For **native** applications, Clerk's prebuilt components are not supported. You must use the Clerk API to build custom UI's for flows such as signing in and signing up. See the [custom flow](/docs/guides/development/custom-flows/overview) guides for more information. For **web** applications, if Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. See the [custom flow](/docs/guides/development/custom-flows/overview) guides for more information. ## Deploy your app To learn how to deploy your Expo application, see the [dedicated guide](/docs/guides/development/deployment/expo). --- title: "`useLocalCredentials()`" description: Clerk's useLocalCredentials() hook enables you to store and access a user's password credentials on their device. sdk: expo sdkScoped: "true" canonical: /docs/reference/expo/use-local-credentials lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo notAvailableSdks: nextjs,react,js-frontend,chrome-extension,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/expo/use-local-credentials.mdx --- The `useLocalCredentials()` hook enables you to store a user's password credentials on their device and subsequently use biometrics for sign-in. This enhances the user experience by allowing users to sign in using Face ID or another biometric authentication method during future sign-ins. > \[!WARNING] > This hook isn't supported in web apps and can only be used in native apps. > This API is available only for [`@clerk/clerk-expo >=2.2.0`](/docs/guides/development/upgrading/upgrade-guides/expo-v2). > Be aware that this works only for sign-in attempts using a [password](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#password). ## Returns * `hasCredentials` * `boolean` Indicates if there are any credentials stored on the device. *** * `userOwnsCredentials` * `boolean` Indicates if the stored credentials belong to the signed in user. When there is no signed-in user, the value will always be `false`. *** * `biometricType` * `'face-recognition' | 'fingerprint' | null` Indicates the supported enrolled biometric authenticator type. *** * `setCredentials()` * (params: [LocalCredentials](#local-credentials)) => Promise\ Stores the provided credentials on the device if the device has enrolled biometrics. The end user needs to have a passcode set in order for the credentials to be stored, and those credentials will be removed if the passcode gets removed. The promise will reject if the value cannot be stored on the device. *** * `clearCredentials()` * () => Promise\ Removes the stored credentials from the device. The promise will reject if the value cannot be deleted from the device. *** * `authenticate()` * () => Promise\<SignInResource> Attempts to read the stored credentials and creates a sign-in attempt with the password strategy.The promise will resolve to a `SignInResource` if the stored credentials were accessed. Otherwise, the promise will reject. ### `LocalCredentials` * `identifier` * `string?` The identifier of the credentials to be stored on the device. It can be a username, email, phone number, etc. *** * `password` * `string` The password for the identifier to be stored on the device. If an identifier already exists on the device, passing only `password` would update the password for the stored identifier. ## How to use the `useLocalCredentials()` hook To learn how to use the `useLocalCredentials()` hook, see the [reference doc](/docs/guides/development/local-credentials). --- title: Configure passkeys for Expo description: Learn how to configure passkeys for your Expo application. sdk: expo sdkScoped: "true" canonical: /docs/reference/expo/passkeys lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo notAvailableSdks: nextjs,react,js-frontend,chrome-extension,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/expo/passkeys.mdx --- [Passkeys](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#passkeys) are a secure, passwordless authentication method that use biometrics and a physical device to authenticate users. This guide shows you how to configure passkeys for your Expo application. > \[!WARNING] > This API is available only for [`@clerk/clerk-expo >=2.2.0`](/docs/guides/development/upgrading/upgrade-guides/expo-v2). ## Enable passkeys To use passkeys, first enable the strategy in the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/user-and-authentication?user_auth_tab=passkeys). ## Configure passkeys Use the following tabs to configure your passkeys for `iOS` or `Android`. > \[!WARNING] > iOS supports passkeys from version iOS 16+ > > This library includes native code and will not work when running Expo Go. Instead, use a development build by running `npx expo run:ios`. ### Get your App ID Prefix and Bundle ID from Apple To get your **App ID Prefix** and **Bundle ID**, follow these steps: 1. Navigate to the [Apple Developer dashboard](https://developer.apple.com/account). 2. Under **Certificates, IDs and Profiles**, select [**Identifiers**](https://developer.apple.com/account/resources/identifiers/list). 3. In the top-right, select the dropdown and select **App IDs**. 4. Select the **App ID** you want to configure passkeys for. You'll be redirect to the **Review your App ID Configuration** page. 5. At the top of the page, you'll see your **App ID Prefix** and **Bundle ID**. Save these values somewhere secure. ### Set up your associated domain file in the Clerk Dashboard 1. In the Clerk Dashboard, navigate to the [**Native Applications**](https://dashboard.clerk.com/last-active?path=user-authentication/native-applications) page. 2. Select the **iOS** tab. 3. Select **Add iOS App**. 4. Paste the **App ID Prefix** and **Bundle ID** that you copied in the previous step. 5. Select **Add App**. 6. On the right-side, save your **Frontend API URL** somewhere secure. ### Update `app.json` in your Expo app 1. In your app's `app.json` file, under the `ios` object, add the `associatedDomains` property as shown in the following example. Replace `` with the **Frontend API URL** value that you saved in the previous step. ```json {{ filename: 'app.json', mark: [[5, 12], [14, 20]] }} { "expo": { //...existing properties "plugins": [ [ "expo-build-properties", { "ios": { "deploymentTarget": "16.0" // iOS Support passkeys from version iOS 16+ } } ] ], "ios": { //...existing properties "associatedDomains": [ "applinks:", "webcredentials:" ] } } } ``` > \[!WARNING] > Android supports passkeys from version 9+. Passkeys will not work with Android emulators. You must use a physical device. > > This library includes native code and [will not work when running Expo Go](https://docs.expo.dev/workflow/customizing/#using-libraries-that-include-native-code). Instead, use a development build by running `npx expo run:android`. ### Set up your Android app links in the Clerk Dashboard 1. In the Clerk Dashboard, navigate to the [**Native Applications**](https://dashboard.clerk.com/last-active?path=user-authentication/native-applications) page. 2. Select the **Android** tab. 3. Select **Add Android app**. 4. Fill out the form with the following information: * The `namespace` (This guide uses the default value: `android_app`) * Your Android app's package name * The `SHA256 certificate fingerprints`. If you don't know where to find the `SHA256 certificate fingerprints`, see the [Expo docs](https://docs.expo.dev/linking/android-app-links/#create-assetlinksjson-file). 5. After submitting the form, you can verify that your `assetlinks.json` file is properly associated with your app by using [Google's **Statement List Generator and Tester**](https://developers.google.com/digital-asset-links/tools/generator). 6. On the right-side, save your **Frontend API URL** somewhere secure. ### Install `expo-build-properties` in your Expo application ```npm npm install expo-build-properties ``` ### Update `app.json` in your Expo application 1. In your app's `app.json` file, under `android`, add the `intentFilters` property as shown in the following example. Replace `` with the **Frontend API URL** value that you saved in the previous step. ```json {{ filename: 'app.json', mark: [[3, 6], [10, 22]] }} { "expo": { "plugins": [["expo-build-properties"]], "android": { //...existing properties "intentFilters": [ { "action": "VIEW", "autoVerify": true, "data": [ { "scheme": "https", "host": "" } ], "category": ["BROWSABLE", "DEFAULT"] } ] } } } ``` ## Install `@clerk/expo-passkeys` Run the following command to install the `@clerk/expo-passkeys` package: ```npm npm install @clerk/expo-passkeys ``` ## Prebuild Expo project Run the following command to prebuild your Expo project: ```bash {{ filename: 'terminal' }} npx expo prebuild ``` ## Update your `` Pass the `passkeys` object to the `__experimental_passkeys` property of your `` component, as shown in the following example: ```tsx {{ filename: 'app/_layout.tsx', mark: [4, 11] }} import { ClerkProvider } from '@clerk/clerk-expo' import { Slot } from 'expo-router' import { tokenCache } from '@clerk/clerk-expo/token-cache' import { passkeys } from '@clerk/clerk-expo/passkeys' export default function RootLayout() { return ( ) } ``` ## Usage To learn how to use passkeys in your Expo application, such as creating, deleting, and authenticating users with passkeys, see the [custom flow guide](/docs/guides/development/custom-flows/authentication/passkeys). --- title: useOAuth() (deprecated) description: Clerk's useOAuth() hook is used to create a new OAuth flow. sdk: expo sdkScoped: "true" canonical: /docs/reference/expo/use-oauth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: expo notAvailableSdks: nextjs,react,js-frontend,chrome-extension,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: expo sourceFile: /docs/reference/expo/use-oauth.mdx --- > \[!WARNING] > This feature is deprecated. Use [`useSSO()`](/docs/reference/expo/use-sso) instead. The `useOAuth()` hook is used to create a new OAuth flow. It can be used in both web and native apps. ## Parameters * `strategy` * OAuthStrategy The strategy corresponding to the OAuth provider. For example: `oauth_facebook`, `oauth_github`, etc. *** * `redirectUrl?` * `string` The full URL or path to redirect to after the OAuth flow is complete. *** * `unsafeMetadata?` * SignUpUnsafeMetadata Unsafe metadata to be passed to the OAuth provider. ## Returns The `useOAuth()` hook returns the `startOAuthFlow()` method, which you can use to initiate the OAuth flow. The `startOAuthFlow()` method has the following signature: ```ts const startOAuthFlow: ( startOAuthFlowParams?: StartOAuthFlowParams, ) => Promise ``` It accepts the following parameters (`StartOAuthFlowParams`): * `redirectUrl?` * `string` The URL or path to redirect to after the OAuth flow is complete. *** * `unsafeMetadata?` * SignUpUnsafeMetadata Unsafe metadata to be passed to the OAuth provider. ## How to use the `useOAuth()` hook The following example demonstrates how to create a custom OAuth sign-in flow for [Google accounts](/docs/guides/configure/auth-strategies/social-connections/google). ```tsx {{ filename: 'app/(auth)/sign-in.tsx', collapsible: true }} import React from 'react' import * as WebBrowser from 'expo-web-browser' import { Text, View, Button } from 'react-native' import { Link } from 'expo-router' import { useOAuth } from '@clerk/clerk-expo' import * as Linking from 'expo-linking' export const useWarmUpBrowser = () => { React.useEffect(() => { // Warm up the android browser to improve UX // https://docs.expo.dev/guides/authentication/#improving-user-experience void WebBrowser.warmUpAsync() return () => { void WebBrowser.coolDownAsync() } }, []) } WebBrowser.maybeCompleteAuthSession() export default function Page() { useWarmUpBrowser() const { startOAuthFlow } = useOAuth({ strategy: 'oauth_google' }) const onPress = React.useCallback(async () => { try { const { createdSessionId, signIn, signUp, setActive } = await startOAuthFlow({ redirectUrl: Linking.createURL('/dashboard', { scheme: 'myapp' }), }) // If sign in was successful, set the active session if (createdSessionId) { setActive!({ session: createdSessionId }) } else { // Use signIn or signUp returned from startOAuthFlow // for next steps, such as MFA } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } }, []) return ( Home {token &&

Token: {token}

}
) } ``` ### Add a button to the extension to open the new tab Add a button to your Chrome Extension to open the page you created in the previous step as a new tab. This can be added anywhere in your extension. The following example places the button on the home page of the extension. ```tsx {{ filename: 'src/popup/routes/home.tsx' }} export const Home = () => { return ( <>

Clerk + Chrome Extension

) } ``` ### Test the background service worker 1. Run your project with the following command: ```bash {{ filename: 'terminal' }} pnpm dev ``` 2. In your Chrome browser, open the extension popup and sign in. 3. Once you've signed in, select the button that you added and a new tab will open. 4. In the new tab, select the **Get token from service worker** button. The token will be displayed on the page. ## `createClerkClient()` options The `createClerkClient()` function accepts an optional object. The following options are available: * `publishableKey` * `string` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `syncHost?` * `string` The host to sync the session with. For more information, see [the dedicated guide](/docs/guides/sessions/sync-host). --- title: Clerk Chrome Extension SDK description: The Clerk Chrome Extension SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. sdk: chrome-extension sdkScoped: "true" canonical: /docs/reference/chrome-extension/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension notAvailableSdks: nextjs,react,js-frontend,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/reference/chrome-extension/overview.mdx --- The Clerk Chrome Extension SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Refer to the [quickstart guide](/docs/chrome-extension/getting-started/quickstart) to get started. ## Authentication options When creating your Clerk application in the Clerk Dashboard, your authentication options will depend on how you configure your Chrome Extension. You can configure your Chrome Extension to behave as one of the following: * **Popup** - Opens as a popup. This is the default behavior. * **Side Panel** - Opens in a side panel * **Sync Host** - Deployed alongside a web app that uses [Sync Host](/docs/guides/sessions/sync-host). See the following table to determine the authentication options available for each configuration. | | Popup | Side Panel | Sync Host | | - | - | - | - | | Email + OTP | ✅ | ✅ | ✅ | | Email + Link | | | ✅ | | Email + Password | ✅ | ✅ | ✅ | | Username + Password | ✅ | ✅ | ✅ | | SMS + OTP | ✅ | ✅ | ✅ | | OAuth | | | ✅ | | Google One Tap | | | ✅ | | SAML | | | ✅ | | Passkeys | ✅ | ✅ | ✅ | | Web3 | | | ✅ | > \[!WARNING] > Our Chrome Extension SDK currently does not fully support Sync Host on side panels. Currently, if a user authenticates in your web app, they need to close and reopen the side panel to update their auth status. ## Sync auth status between your Chrome Extension and web app Clerk allows you to sync the authentication state from your web app to your Chrome Extension using the Sync Host feature. When a user authenticates in your web app, they will also be authenticated in your Chrome Extension. See [the dedicated guide](/docs/guides/sessions/sync-host) for more information. ## `createClerkClient()` It's recommended to use `createClerkClient()` for Chrome Extension's that need to interact with Clerk in a content script. The `createClerkClient()` helper initializes a new Clerk instance on demand and refreshes the session token if there is a valid, signed-in user. It can be used in a [content script](https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts) or a [background service worker](https://developer.chrome.com/docs/extensions/develop/concepts/service-workers/basics) to access a user's information or session token. [Learn more about `createClerkClient()`](/docs/reference/chrome-extension/create-clerk-client). ## Add React Router [Learn how to add React Router to your Chrome Extension](/docs/guides/development/add-react-router) to enable routing in your application. ## Deploy your extension to production See [the Chrome Extension deployment guide](/docs/guides/development/deployment/chrome-extension) for information about deploying your extension to production. ## Configure a consistent CRX ID A Chrome Extension can be identified by its unique CRX ID, similar to how a website can be identified by its domain. The CRX ID rotates by default, which can cause errors with the Clerk integration. [Learn how to configure a consistent CRX ID](/docs/guides/development/configure-consistent-crx-id) so that your extension will have a stable, unchanging key. ## Frequently asked questions (FAQ) ### Can I use Clerk in a content script? Unfortunately, no. Clerk has strict security restrictions on the allowed origins for requests from the application or extension to Clerk's API. Since a content script could run on any domain, there is no way to enforce origin restrictions. ### Why can't I use OAuth, SAML, or email links with the extension popup or side panel? OAuth and SAML require a redirect back from the Identity Provider (IdP), which is not currently supported by Google Chrome. Email links require the popup to remain open while the user checks their email, copies the link, and returns to paste it. Since popups close as soon as a user clicks outside of them, this flow is not possible. The sign-in status resets when the popup closes. ### Why aren't options like Google One Tap or Web3 available in a popup or side panel? Chrome Extensions can't load code from remote sources. Features like Google One Tap, Web3, and some other authentication options require loading remote code to function. This functionality is removed from the Chrome Extension SDK to ensure extensions using Clerk are not rejected by the Chrome Web Store. ### Why is bot protection not supported in the Chrome Extension SDK? Clerk uses [Cloudflare](https://developers.cloudflare.com/waf/reference/cloudflare-challenges/#mobile-device-emulation) for bot detection, which isn't supported in non-browser environments like Chrome Extension. Because of this limitation, ensure bot protection is disabled in the Clerk Dashboard. [Learn more about bot protection](/docs/guides/secure/bot-protection). --- title: "`Clerk` class" description: The Clerk class is the main entrypoint class for the `@clerk/clerk-js` package. It contains a number of methods and properties for interacting with the Clerk API. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/clerk lastUpdated: 2025-11-21T23:29:30.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/clerk.mdx --- The `Clerk` class is the main entrypoint class for the `@clerk/clerk-js` package. It contains a number of methods and properties for interacting with the Clerk API. ## Properties * `client` * [`Client`](/docs/reference/javascript/client) The `Client` object for the current window. *** * `domain` * `string` The current Clerk app's domain. Prefixed with `clerk.` on production if not already prefixed. Returns `""` when ran on the server. *** * `instanceType` * `'production' | 'development'` Indicates if the Clerk instance is running in production or development mode. *** * `isSatellite` * `boolean` A boolean that indicates if the instance is a satellite app. *** * `isSignedIn` * `boolean` A boolean that indicates if the user is signed in. *** * `loaded` * `boolean` A boolean that indicates if the `Clerk` object is ready for use. Set to `false` when the `status` is `'loading'` or `'error'`. Set to `true` when the `status` is either `'ready'` or `'degraded'`. *** * `organization` * [Organization](/docs/reference/javascript/organization) | null | undefined A shortcut to the last active `Session.user.organizationMemberships` which holds an instance of a `Organization` object. If the session is `null` or `undefined`, the user field will match. *** * `proxyUrl` * `string` Your Clerk app's proxy URL. Required for applications that run behind a reverse proxy. Can be either a relative path (`/__clerk`) or a full URL (`https:///__clerk`). *** * `publishableKey` * `string | undefined` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `sdkMetadata` * `{ name: string; version: string; environment: string }` Contains information about the SDK that the host application is using. You don't need to set this value yourself unless you're [developing an SDK](/docs/guides/development/sdk-development/overview). *** * `session` * [Session](/docs/reference/javascript/session) | null | undefined The currently active `Session`, which is guaranteed to be one of the sessions in `Client.sessions`. If there is no active session, this field will be `null`. If the session is loading, this field will be `undefined`. *** * `status` * `'degraded' | 'error' | 'loading' | 'ready'` The status of the Clerk instance. Possible values are: * `'degraded'`: Set when Clerk is partially operational. * `'error'`: Set when hotloading `clerk-js` failed or `Clerk.load()` failed. * `'loading'`: Set during initialization. * `'ready'`: Set when Clerk is fully operational. *** * `telemetry?` * `{ disabled: boolean, debug: boolean }` [Telemetry](/docs/guides/how-clerk-works/security/clerk-telemetry) configuration. *** * `user` * [User](/docs/reference/javascript/user) | null | undefined A shortcut to `Session.user` which holds the currently active `User` object. If the session is `null` or `undefined`, the user field will match. *** * `version` * `string` The Clerk SDK version. ## Methods ### `addListener()` Registers a listener that triggers a callback whenever a change in the [`Client`](/docs/reference/javascript/client), [`Session`](/docs/reference/javascript/session), or [`User`](/docs/reference/javascript/user) object occurs. This method is primarily used to build frontend SDKs like [`@clerk/clerk-react`](https://www.npmjs.com/package/@clerk/clerk-react). Returns an `UnsubscribeCallback` function that can be used to remove the listener from the `Clerk` object. ```typescript function addListener(listener: (emission: Resources) => void): UnsubscribeCallback ``` #### `Resources` * `client` * [`Client`](/docs/reference/javascript/client) *** * `session` * [Session](/docs/reference/javascript/session) | null | undefined *** * `user` * [User](/docs/reference/javascript/user) | null | undefined *** * `organization` * [Organization](/docs/reference/javascript/organization) | null | undefined *** * `lastOrganizationInvitation` * [OrganizationInvitation](/docs/reference/javascript/types/organization-invitation) | null | undefined *** * `lastOrganizationMember` * [OrganizationMembership](/docs/reference/javascript/types/organization-membership) | null | undefined > \[!NOTE] > Note the following about `User` and `Session`: > > * When there is an active session, `user === session.user`. > * When there is no active session, `User` and `Session` will both be `null`. ### `authenticateWithMetamask()` ```typescript function authenticateWithMetamask({ redirectUrl, signUpContinueUrl, customNavigate, }?: AuthenticateWithMetamaskParams): Promise ``` #### `AuthenticateWithMetamaskParams` * `redirectUrl?` * `string | undefined` The full URL or path to navigate to after a successful sign-in or sign-up. *** * `signUpContinueUrl?` * `string | undefined` The URL to navigate to if the sign-up process is missing user information. *** * `customNavigate?` * `((to: string) => Promise | unknown) | undefined` A function that overrides Clerk's default navigation behavior, allowing custom handling of navigation during sign-up and sign-in flows. ### `authenticateWithCoinbaseWallet()` ```typescript function authenticateWithCoinbaseWallet({ redirectUrl, signUpContinueUrl, customNavigate, }?: AuthenticateWithCoinbaseWalletParams): Promise ``` #### `AuthenticateWithCoinbaseWalletParams` * `redirectUrl?` * `string | undefined` The full URL or path to navigate to after a successful sign-in or sign-up. *** * `signUpContinueUrl?` * `string | undefined` The full URL or path to navigate to if the sign-up process is missing user information. *** * `customNavigate?` * `((to: string) => Promise | unknown) | undefined` A function that overrides Clerk's default navigation behavior, allowing custom handling of navigation during sign-up and sign-in flows. ### `authenticateWithOKXWallet()` Starts a sign-in flow that uses the OKX Wallet to authenticate the user using their Web3 wallet address. ```typescript function authenticateWithOKXWallet(props?: AuthenticateWithOKXWalletParams): Promise ``` #### `AuthenticateWithOKXWalletParams` * `redirectUrl?` * `string | undefined` The full URL or path to navigate to after a successful sign-in or sign-up. *** * `signUpContinueUrl?` * `string | undefined` The full URL or path to navigate to if the sign-up process is missing user information. *** * `customNavigate?` * `((to: string) => Promise | unknown) | undefined` A function that overrides Clerk's default navigation behavior, allowing custom handling of navigation during sign-up and sign-in flows. *** * `unsafeMetadata?` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend. Once the sign-up is complete, the value of this field will be automatically copied to the newly created user's unsafe metadata. One common use case for this attribute is to use it to implement custom fields that can be collected during sign-up and will automatically be attached to the created `User` object. *** * `legalAccepted?` * `boolean` A boolean indicating whether the user has agreed to the [legal compliance](/docs/guides/secure/legal-compliance) documents. ### `authenticateWithBase()` Starts a sign-in flow that uses Base to authenticate the user using their Web3 wallet address. ```typescript function authenticateWithBase(props?: AuthenticateWithBaseParams): Promise ``` #### `AuthenticateWithBaseParams` * `redirectUrl?` * `string | undefined` The full URL or path to navigate to after a successful sign-in or sign-up. *** * `signUpContinueUrl?` * `string | undefined` The full URL or path to navigate to if the sign-up process is missing user information. *** * `customNavigate?` * `((to: string) => Promise | unknown) | undefined` A function that overrides Clerk's default navigation behavior, allowing custom handling of navigation during sign-up and sign-in flows. *** * `unsafeMetadata?` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend. Once the sign-up is complete, the value of this field will be automatically copied to the newly created user's unsafe metadata. One common use case for this attribute is to use it to implement custom fields that can be collected during sign-up and will automatically be attached to the created `User` object. *** * `legalAccepted?` * `boolean` A boolean indicating whether the user has agreed to the [legal compliance](/docs/guides/secure/legal-compliance) documents. ### `authenticateWithWeb3()` ```typescript function authenticateWithWeb3({ redirectUrl, signUpContinueUrl, customNavigate, strategy, }: ClerkAuthenticateWithWeb3Params): Promise ``` #### `ClerkAuthenticateWithWeb3Params` * `redirectUrl?` * `string | undefined` The full URL or path to navigate to after a successful sign in or sign up. *** * `signUpContinueUrl?` * `string | undefined` The full URL or path to navigate to if the sign-up process is missing user information. *** * `customNavigate?` * `((to: string) => Promise | unknown) | undefined` A function that overrides Clerk's default navigation behavior, allowing custom handling of navigation during sign-up and sign-in flows. *** * `strategy` * `Web3Strategy` The Web3 verification strategy. ### `buildCreateOrganizationUrl()` Returns the configured URL where \ is mounted or a custom create-organization page is rendered. ```typescript function buildCreateOrganizationUrl(): string ``` #### Example ```js await clerk.buildCreateOrganizationUrl() ``` ### `buildHomeUrl()` Returns the URL you've configured in the Clerk Dashboard. ```typescript function buildHomeUrl(): string ``` #### Example ```js await clerk.buildHomeUrl() ``` ### `buildOrganizationProfileUrl()` Returns the configured URL where \ is mounted or a custom organization-profile page is rendered. ```typescript function buildOrganizationProfileUrl(): string ``` #### Example ```js await clerk.buildOrganizationProfileUrl() ``` ### `buildSignInUrl()` Returns the configured URL where \ is mounted or a custom sign-in page is rendered. ```typescript function buildSignInUrl(options?: RedirectOptions): string ``` #### Parameters * `options` * [RedirectOptions](/docs/reference/javascript/types/redirect-options) | undefined Options used to control the redirect in the constructed URL. #### Example ```js await clerk.buildSignInUrl({ signInForceRedirectUrl: '/dashboard', signUpForceRedirectUrl: '/dashboard', }) ``` ### `buildSignUpUrl()` Returns the configured URL where \ is mounted or a custom sign-up page is rendered. ```typescript function buildSignUpUrl(options?: RedirectOptions): string ``` #### Parameters * `options` * [RedirectOptions](/docs/reference/javascript/types/redirect-options) | undefined Options used to control the redirect in the constructed URL. #### Example ```js await clerk.buildSignUpUrl({ signInForceRedirectUrl: '/dashboard', signUpForceRedirectUrl: '/dashboard', }) ``` ### `buildUrlWithAuth()` Decorates the provided URL with the auth token for development instances. ```typescript function buildUrlWithAuth(to: string, options?: BuildUrlWithAuthParams): string ``` #### Parameters * `to` * `string` The route to create a URL towards. *** * `options` * [`BuildUrlWithAuthParams`](#build-url-with-auth-params) Options to apply toward the URL builder. #### Example ```js await clerk.buildUrlWithAuth('/dashboard') ``` #### `BuildUrlWithAuthParams` * `useQueryParam` * `boolean | null | undefined` Controls if dev browser JWT is added as a query param. ### `buildUserProfileUrl()` Returns the URL where \ is mounted or a custom user-profile page is rendered. ```typescript function buildUserProfileUrl(): string ``` #### Example ```js await clerk.buildUserProfileUrl() ``` ### `constructor()` Create an instance of the `Clerk` class with dedicated options. This method is only available when importing `Clerk` from `@clerk/clerk-js`, rather than using a Window script. ```typescript class Clerk { constructor(key: string, options?: DomainOrProxyUrl) } ``` #### Parameters * `key` * `string` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `options?` * [DomainOrProxyUrl](#domain-or-proxy-url) | undefined The domain or proxy URL used to connect to Clerk. #### `DomainOrProxyUrl` Only one of the two properties are allowed to be set at a time. * `proxyUrl?` * `never | string | ((url: URL) => string)` The proxy URL used to connect to Clerk. If a function, will be called with a `URL` made from `window.location.href`. *** * `domain?` * `never | string | ((url: URL) => string)` The domain used to connect to Clerk. If a function, will be called with a `URL` made from `window.location.href`. ### `createOrganization()` Creates an Organization programmatically. Returns an [`Organization`](/docs/reference/javascript/organization) object. > \[!NOTE] > For React-based apps, consider using the \ component. ```typescript function createOrganization({ name, slug }: CreateOrganizationParams): Promise ``` #### Parameters * `name` * `string` The name of the Organization to be created. *** * `slug?` * `string` The optional slug of the Organization to be created. #### Example ```js await clerk.createOrganization({ name: 'test' }) ``` ### `getOrganization()` Retrieves information for a specific Organization. ```typescript function getOrganization(organizationId: string): Promise ``` #### Parameters * `organizationId` * `string` The ID of the Organization to be found. #### Example The following example demonstrates how to retrieve information about the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. ```js await clerk.getOrganization(clerk.organization.id) ``` ### `handleEmailLinkVerification()` Handles the completion of an email link verification flow by processing the verification results from the redirect URL query parameters. This method should be called after the user is redirected back from visiting the verification link in their email. ```typescript function handleEmailLinkVerification( params: handleEmailLinkVerificationParams, customNavigate?: ((to: string) => Promise) | undefined, ): Promise ``` The `handleEmailLinkVerification()` method finalizes an email verification flow that begins when a user initiates email verification and ends when they visit the verification link. Email verification can be completed on any device - not necessarily the one where it was initiated. For example, a user could start verification on desktop but click the email link on mobile. When a user visits the verification link, they are redirected to the URL specified during flow initialization. Clerk appends these query parameters to the URL: * `__clerk_status`: The verification outcome: * `verified`: Verification succeeded. * `failed`: Verification failed. * `expired`: Link expired. * `client_mismatch`: Device/browser mismatch (only if [same device verification](/docs/guides/secure/best-practices/protect-email-links) is enabled). * `__clerk_created_session`: ID of any new session created. Since verification can happen on a different device, this session may not appear in [`Client.sessions`](/docs/reference/javascript/client#properties). The method handles the verification outcome as follows: 1. On successful verification, it: * Determines if sign-in/sign-up is complete * Redirects accordingly using the provided URLs (both optional): * `redirectUrlComplete`: URL for completed sign-in/sign-up. * `redirectUrl`: URL if there are further requirements for the sign-in/sign-up attempt, such as MFA. * Executes an optional callback if verification happened on another device. 2. On verification failure: * Throws an [`EmailLinkError`](/docs/guides/development/custom-flows/authentication/email-links). * Error code indicates if link expired or verification failed. Take a look at the function parameters below for more usage details. #### Parameters * `params` * [`handleEmailLinkVerificationParams`](#handle-email-link-verification-params) Allows you to define the URLs where the user should be redirected to on successful verification or pending/completed sign-up or sign-in attempts. If the email link is successfully verified on another device, there's a callback function parameter that allows custom code execution. *** * `customNavigate?` * `(to: string) => Promise` A function that overrides Clerk's default navigation behavior, allowing custom handling of navigation during sign-up and sign-in flows. #### `handleEmailLinkVerificationParams` * `redirectUrlComplete?` * `string | undefined` The full URL to navigate to after successful email link verification on completed sign-up or sign-in on the same device. *** * `redirectUrl?` * `string | undefined` The full URL to navigate to after successful email link verification on the same device, but without completing sign-in or sign-up. *** * `onVerifiedOnOtherDevice?` * `() => void` Callback function to be executed after successful email link verification on another device. #### Example See the [custom flow](/docs/guides/development/custom-flows/authentication/email-links) guide for a comprehensive example of how to use the `handleEmailLinkVerification()` method. ### `handleRedirectCallback()` Completes a custom OAuth flow that was started by calling either [`SignIn.authenticateWithRedirect(params)`](/docs/reference/javascript/sign-in) or [`SignUp.authenticateWithRedirect(params)`](/docs/reference/javascript/sign-up). ```typescript function handleRedirectCallback( params: HandleOAuthCallbackParams, customNavigate?: ((to: string) => Promise) | undefined, ): Promise ``` #### Parameters * `params` * [`HandleOAuthCallbackParams`](#handle-o-auth-callback-params) Additional props that define where the user will be redirected to at the end of a successful OAuth flow. *** * `customNavigate` * `(to: string) => Promise` A function that overrides Clerk's default navigation behavior, allowing custom handling of navigation during sign-up and sign-in flows. #### `HandleOAuthCallbackParams` * `continueSignUpUrl?` * `string | undefined | null` The full URL or path to navigate to if the sign up requires additional information. *** * `signInUrl?` * `string` The full URL or path where the `` component is mounted. *** * `signUpUrl?` * `string` The full URL or path where the `` component is mounted. *** * `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. *** * `firstFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if first factor verification is required. *** * `secondFactorUrl?` * `string | undefined` The full URL or path to navigate to during sign in, if [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) is enabled. *** * `resetPasswordUrl?` * `string` The full URL or path to navigate to during sign in, if the user is required to reset their password. *** * `transferable?` * `boolean` A boolean that indicates whether or not sign in attempts are transferable to the sign up flow. Defaults to `true`. When set to `false`, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. *** * `verifyEmailAddressUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting email verification. *** * `verifyPhoneNumberUrl?` * `string | undefined | null` The full URL or path to navigate to after requesting phone verification. #### Example ```js await clerk.handleRedirectCallback({ signInForceRedirectUrl: '/dashboard', signUpForceRedirectUrl: '/dashboard', }) ``` See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) guide for implementation details on how to implement a custom OAuth flow. ### `handleUnauthenticated()` Handles a 401 response from [Frontend API](/docs/reference/frontend-api){{ target: '_blank' }} by refreshing the client and session object accordingly. ```typescript function handleUnauthenticated(opts?: { broadcast: boolean }): Promise ``` #### Example ```js await clerk.handleUnauthenticated() ``` ### `joinWaitlist()` Create a new waitlist entry programmatically. Requires that you set your app's sign-up mode to [**Waitlist**](/docs/guides/secure/restricting-access#waitlist) in the Clerk Dashboard. ```typescript function joinWaitlist({ emailAddress }: JoinWaitlistParams): Promise ``` #### Parameters * `emailAddress` * `string` The email address of the user you want to add in the waitlist. #### Example ```js await clerk.joinWaitlist({ emailAddress: 'user@example.com' }) ``` ### `load()` Initializes the `Clerk` object and loads all necessary environment configuration and instance settings from the [Frontend API](/docs/reference/frontend-api){{ target: '_blank' }}. You must call this method before using the `Clerk` object in your code. Refer to the [quickstart guide](/docs/js-frontend/getting-started/quickstart) for more information. ```typescript function load(options?: ClerkOptions): Promise ``` #### `ClerkOptions` The `load()` method accepts an optional object that accepts the following props. All props are optional. * `appearance` * [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined Optional object to style your components. Will only affect \[Clerk components]\[components-ref] and not \[Account Portal]\[ap-ref] pages. *** * `localization` * [Localization](/docs/guides/customizing-clerk/localization) | undefined Optional object to localize your components. Will only affect \[Clerk components]\[components-ref] and not \[Account Portal]\[ap-ref] pages. *** * `routerPush?` * `(to: string) => Promise | void` A function which takes the destination path as an argument and performs a "push" navigation. *** * `routerReplace?` * `(to: string) => Promise | void` A function which takes the destination path as an argument and performs a "replace" navigation. *** * `polling` * `boolean | undefined` Dictates if we should poll against Clerk's backend every 5 minutes. Defaults to `true`. *** * `selectInitialSession` * ((client: \[Client]\[client-ref]) => Session | null) | undefined An optional function which allows you to control which active session is the initial session to base a user's state off of. Defaults to the first session in the client's sessions array. *** * `standardBrowser` * `boolean | undefined` Controls if ClerkJS will load with the standard browser set up using Clerk cookies. Defaults to `true`. *** * `supportEmail` * `string | undefined` Optional support email for display in authentication screens. *** * `touchSession` * `boolean | undefined` Indicates whether the session should be "touched" when user interactions occur, used to record these interactions. Defaults to `true`. *** * `signInUrl` * `string | undefined` The default URL to use to direct to when 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. *** * `signUpUrl` * `string | undefined` The default URL to use to direct to when 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. *** * `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. *** * `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. *** * `afterSignOutUrl?` * `string` The full URL or path to navigate to after a successful sign-out. *** * `allowedRedirectOrigins?` * `Array` An optional array of domains to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. *** * `allowedRedirectProtocols?` * `Array` An optional array of protocols to validate user-provided redirect URLs against. If no match is made, the redirect is considered unsafe and the default redirect will be used with a warning logged in the console. *** * `isSatellite` * `boolean | ((url: URL) => boolean) | undefined` Clerk flag for satellite apps. Experimental. *** * `telemetry?` * `false | { disabled?: boolean; debug?: boolean } | undefined` Controls whether or not Clerk will collect [telemetry data](/docs/guides/how-clerk-works/security/clerk-telemetry). #### Example ```js await clerk.load() ``` ### `navigate()` Helper method which will use the custom push navigation function of your application to navigate to the provided URL or relative path. Returns a promise that can be `await`ed in order to listen for the navigation to finish. The inner value should not be relied on, as it can change based on the framework it's used within. ```typescript function navigate(to: string | undefined): Promise ``` #### Example ```js await clerk.navigate('/dashboard') ``` #### Parameters * `to` * `string | undefined` The route to navigate to. ### `on()` Registers an event handler for a specific Clerk event. ```ts type OnEventListener = ( event: E, handler: EventHandler, opt?: { notify: boolean }, ) => void ``` #### Example ```js window.Clerk.on('status', (status) => {}) window.Clerk.on('status', (status) => {}, { notify: true }) ``` #### Parameters * `event` * `E` The event to listen to. Currently, the only supported event is `status`. *** * `handler` * `EventHandler` The handler to call when the event is triggered. *** * `opt?` * `{ notify: boolean }` An optional object to control the behavior of the event handler. If true, and the event was previously dispatched, handler will be called immediately with the latest payload ### `off()` Removes an event handler for a specific Clerk event. ```ts type OffEventListener = (event: E, handler: EventHandler) => void ``` #### Example ```js window.Clerk.off('status') window.Clerk.off('status', (status) => {}) ``` #### Parameters * `event` * `E` The event to remove the handler from. Currently, the only supported event is `status`. *** * `handler` * `EventHandler` The handler to remove. ### `redirectToCreateOrganization()` Redirects to the configured URL where \ is mounted. This method uses the [`navigate()`](#navigate) method under the hood. Returns a promise that can be `await`ed in order to listen for the navigation to finish. The inner value should not be relied on, as it can change based on the framework it's used within. ```typescript function redirectToCreateOrganization(): Promise ``` #### Example ```js await clerk.redirectToCreateOrganization() ``` ### `redirectToOrganizationProfile()` Redirects to the configured URL where \ is mounted. This method uses the [`navigate()`](#navigate) method under the hood. Returns a promise that can be `await`ed in order to listen for the navigation to finish. The inner value should not be relied on, as it can change based on the framework it's used within. ```typescript function redirectToOrganizationProfile(): Promise ``` #### Example ```js await clerk.redirectToOrganizationProfile() ``` ### `redirectToSignIn()` Redirects to the sign-in URL, as configured in your application's instance settings. This method uses the [`navigate()`](#navigate) method under the hood. Returns a promise that can be `await`ed in order to listen for the navigation to finish. The inner value should not be relied on, as it can change based on the framework it's used within. ```typescript function redirectToSignIn(options?: SignInRedirectOptions): Promise ``` #### Parameters * `options?` * [SignInRedirectOptions](/docs/reference/javascript/types/sign-in-redirect-options) | undefined Options to use in the redirect, such as `signInForceRedirectUrl` and `signInFallbackRedirectUrl`. #### Example ```js await clerk.redirectToSignIn({ signInForceRedirectUrl: '/dashboard', signUpForceRedirectUrl: '/dashboard', }) ``` ### `redirectToSignUp()` Redirects to the sign-up URL, as configured in your application's instance settings. This method uses the [`navigate()`](#navigate) method under the hood. Returns a promise that can be `await`ed in order to listen for the navigation to finish. The inner value should not be relied on, as it can change based on the framework it's used within. ```typescript function redirectToSignUp(options?: SignUpRedirectOptions): Promise ``` #### Parameters * `options?` * [SignUpRedirectOptions](/docs/reference/javascript/types/sign-up-redirect-options) | undefined Options to use in the redirect, such as `signUpForceRedirectUrl` and `signUpFallbackRedirectUrl`. #### Example ```js await clerk.redirectToSignUp({ signUpForceRedirectUrl: '/dashboard', signUpFallbackRedirectUrl: '/dashboard', }) ``` ### `redirectToUserProfile()` Returns a promise that can be `await`ed in order to listen for the navigation to finish. The inner value should not be relied on, as it can change based on the framework it's used within. ```typescript function redirectToUserProfile(): Promise ``` #### Example ```js await clerk.redirectToUserProfile() ``` ### `redirectWithAuth()` Redirects to the provided URL after appending authentication credentials. For development instances, this method decorates the URL with an auth token to maintain authentication state. For production instances, the standard session cookie is used. Returns a promise that can be `await`ed in order to listen for the navigation to finish. The inner value should not be relied on, as it can change based on the framework it's used within. ```typescript function redirectWithAuth(to: string): Promise ``` #### Parameters * `to` * `string | undefined` The route to navigate to #### Example ```js await clerk.redirectWithAuth('/dashboard') ``` ### `setActive()` A method used to set the current session and/or Organization for the client. Accepts a [`SetActiveParams`](/docs/reference/javascript/types/set-active-params) object. ```typescript function setActive(params: SetActiveParams): Promise ``` #### Example The `setActive()` method is most commonly used when building a [custom flow](/docs/guides/development/custom-flows/overview) for your application. For example, during authentication, when a user signs in or signs up successfully, a new session is created. `setActive()` needs to be used to set the new session as the active session. See the implementation of this in the [Custom authentication flow](/docs/guides/development/custom-flows/overview) guide. Another example is when a user switches Organizations in a multi-Organization application. `setActive()` needs to be used to set the new Organization as the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. See the implementation of this in the [Custom Organization switcher](/docs/guides/development/custom-flows/organizations/organization-switcher) guide. ### `signOut()` * In a [multi-session application](/docs/guides/secure/session-options#multi-session-applications): Signs out the active user from all sessions * In a single-session context: Signs out the active user from the current session The current client will be deleted. You can specify a specific session to sign out by passing the `sessionId` parameter. ```typescript function signOut(options?: SignOutOptions): Promise // OR function signOut( signOutCallback?: () => void | Promise, options?: SignOutOptions, ): Promise ``` #### `SignOutOptions` * `sessionId?` * `string` Specify a specific session to sign out. Useful for multi-session applications. *** * `redirectUrl?` * `string` The full URL or path to navigate to after sign out is complete. #### Example ```js await clerk.signOut() ``` ## Components The `Clerk` class also contains a number of methods for interacting with prebuilt components. ### `` * mountSignIn() * unmountSignIn() * openSignIn() * closeSignIn() ### `` * mountSignUp() * unmountSignUp() * openSignUp() * closeSignUp() ### `` * openGoogleOneTap() * closeGoogleOneTap() * authenticateWithGoogleOneTap() * handleGoogleOneTapCallback() ### `` * mountUserAvatar() * unmountUserAvatar() ### `` * mountUserButton() * unmountUserButton() ### `` * mountUserProfile() * unmountUserProfile() * openUserProfile() * closeUserProfile() ### `` * mountOrganizationProfile() * unmountOrganizationProfile() * openOrganizationProfile() * closeOrganizationProfile() ### `` * mountOrganizationSwitcher() * unmountOrganizationSwitcher() ### `` * mountCreateOrganization * unmountCreateOrganization * openCreateOrganization * closeCreateOrganization ### `` * mountOrganizationList * unmountOrganizationList ### `` * mountWaitlist() * unmountWaitlist() * openWaitlist() * closeWaitlist() [client-ref]: /docs/reference/javascript/client [session-ref]: /docs/reference/javascript/session [user-ref]: /docs/reference/javascript/user [organization-ref]: /docs/reference/javascript/organization [components-ref]: /docs/reference/components/overview [ap-ref]: /docs/guides/customizing-clerk/account-portal --- title: "`SignIn`" description: The SignIn object holds all the state of the current sign in and provides helper methods to navigate and complete the sign in process. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/sign-in lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/sign-in.mdx --- The `SignIn` object holds the state of the current sign-in and provides helper methods to navigate and complete the sign-in process. It is used to manage the sign-in lifecycle, including the first and second factor verification, and the creation of a new session. The following steps outline the sign-in process: 1. Initiate the sign-in process by collecting the user's authentication information and passing the appropriate parameters to the [`create()`](#create) method. 2. Prepare the first factor verification by calling [`SignIn.prepareFirstFactor()`](#prepare-first-factor). Users *must* complete a first factor verification. This can be something like providing a password, an email link, a one-time code (OTP), a Web3 wallet address, or providing proof of their identity through an external social account (SSO/OAuth). 3. Attempt to complete the first factor verification by calling [`SignIn.attemptFirstFactor()`](#attempt-first-factor). 4. Optionally, if you have enabled [multi-factor](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) for your application, you will need to prepare the second factor verification by calling [`SignIn.prepareSecondFactor()`](#prepare-second-factor). 5. Attempt to complete the second factor verification by calling [`SignIn.attemptSecondFactor()`](#attempt-second-factor). 6. If verification is successful, set the newly created session as the active session by passing the `SignIn.createdSessionId` to the [`setActive()`](/docs/reference/javascript/clerk#set-active) method on the `Clerk` object. ## Properties * `status` * `SignInStatus` The current status of the sign-in. `SignInStatus` supports the following values: * `'complete'`: The user is signed in and the custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). can proceed to `setActive()` to create a session. * `'needs_identifier'`: The user's identifier (e.g., email address, phone number, username) hasn't been provided. * `'needs_first_factor'`: One of the following [first factor verification strategies](/docs/reference/javascript/sign-in) is missing: `'email_link'`, `'email_code'`, `'phone_code'`, `'web3_base_signature'`, `'web3_metamask_signature'`, `'web3_coinbase_wallet_signature'` or `'oauth_provider'`. * `'needs_second_factor'`: One of the following [second factor verification strategies](/docs/reference/javascript/sign-in) is missing: `'phone_code'` or `'totp'`. * `'needs_new_password'`: The user needs to set a new password. *** * `supportedIdentifiers` * `SignInIdentifier[]` Array of all the authentication identifiers that are supported for this sign in. `SignInIdentifier` supports the following values: * `'email_address'` * `'phone_number'` * `'web3_wallet'` * `'username'` *** * `identifier` * `string | null` **Optional** if the `strategy` is set to `'oauth_'` or `'enterprise_sso'`. **Required** otherwise. The authentication identifier value for the current sign-in. *** * `supportedFirstFactors` * [SignInFirstFactor](/docs/reference/javascript/types/sign-in-first-factor)\[] Array of the first factors that are supported in the current sign-in. Each factor contains information about the verification strategy that can be used. See the [`SignInFirstFactor`](/docs/reference/javascript/types/sign-in-first-factor) type reference for more information. *** * `supportedSecondFactors` * [SignInSecondFactor](/docs/reference/javascript/types/sign-in-second-factor)\[] Array of the second factors that are supported in the current sign-in. Each factor contains information about the verification strategy that can be used. This property is populated only when the first factor is verified. See the [`SignInSecondFactor`](/docs/reference/javascript/types/sign-in-second-factor) type reference for more information. *** * `firstFactorVerification` * [`Verification`](/docs/reference/javascript/types/verification) The state of the verification process for the selected first factor. Initially, this property contains an empty verification object, since there is no first factor selected. You need to call the [`prepareFirstFactor`](/docs/reference/javascript/sign-in#prepare-first-factor) method in order to start the verification process. *** * `secondFactorVerification` * [`Verification`](/docs/reference/javascript/types/verification) The state of the verification process for the selected second factor. Initially, this property contains an empty verification object, since there is no second factor selected. For the `phone_code` strategy, you need to call the [`prepareSecondFactor`](/docs/reference/javascript/sign-in#prepare-second-factor) method in order to start the verification process. For the `totp` strategy, you can directly attempt. *** * `userData` * `UserData` An object containing information about the user of the current sign-in. This property is populated only once an identifier is given to the `SignIn` object. *** * `createdSessionId` * `string | null` The identifier of the session that was created upon completion of the current sign-in. The value of this property is `null` if the sign-in status is not `'complete'`. ## Methods ### `attemptFirstFactor()` Attempts to complete the first factor verification process. This is a required step in order to complete a sign in, as users should be verified at least by one factor of authentication. Make sure that a `SignIn` object already exists before you call this method, either by first calling [`SignIn.create()`](#create) or [`SignIn.prepareFirstFactor()`](#prepare-first-factor). The only strategy that does not require a verification to have already been prepared before attempting to complete it is the `password` strategy. Depending on the strategy that was selected when the verification was prepared, the method parameters will be different. Returns a `SignIn` object. Check the `firstFactorVerification` attribute for the status of the first factor verification process. ```typescript function attemptFirstFactor(params: AttemptFirstFactorParams): Promise ``` #### `AttemptFirstFactorParams` * `strategy` * `'email_code' | 'phone_code' | 'password' | 'web3_base_signature' | 'web3_metamask_signature' | 'web3_coinbase_wallet_signature' | 'web3_okx_wallet_signature' | 'passkey' | 'reset_password_phone_code' | 'reset_password_email_code'` The `strategy` value depends on the `SignIn.identifier` value. Each authentication identifier supports different verification strategies. The following strategies are supported: * `'email_code'`: User will receive a one-time authentication code via email. At least one email address should be on file for the user. * `'phone_code'`: User will receive a one-time code via SMS. At least one phone number should be on file for the user. * `'password'`: The verification will attempt to be completed with the user's password. * `'web3_base_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Base](https://docs.base.org/base-account/guides/authenticate-users). * `'web3_metamask_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Metamask](https://metamask.io/). * `'web3_coinbase_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Coinbase Wallet](https://www.coinbase.com/wallet). * `'web3_okx_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [OKX Wallet](https://www.okx.com/help/section/faq-web3-wallet). * `'passkey'`: The verification will attempt to be completed using the user's passkey. * `'reset_password_phone_code'`: Used when the user is trying to reset their password. The user will receive a one-time code via SMS. * `'reset_password_email_code'`: Used when the user is trying to reset their password. The user will receive a one-time code via email. *** * `code?` * `string` **Required** if `strategy` is set to `'email_code'`, `'phone_code'`, `'reset_password_phone_code'`, or `'reset_password_email_code'`. The one-time code that was sent to the user. *** * `password?` * `string` **Required** if `strategy` is set to `'password'`. The user's password string to be verified. *** * `signature?` * `string` **Required** if `strategy` is set to `'web3_base_signature'`, `'web3_metamask_signature'`, `'web3_coinbase_wallet_signature'`, or `'web3_okx_wallet_signature'`. The Web3 wallet generated signature to be verified. #### Example ```js const signIn = await clerk.signIn.attemptFirstFactor({ strategy: 'email_code', code: '123456', }) ``` For comprehensive examples, see the [custom flow guides](/docs/guides/development/custom-flows/overview). ### `attemptSecondFactor()` Attempts to complete the second factor (2FA) verification process, also known as 2FA, or [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication). > \[!NOTE] > For the `phone_code` strategy, make sure that a verification has already been prepared before you call this method, by first calling [`SignIn.prepareSecondFactor`](#prepare-second-factor). Returns a `SignIn` object. Check the `secondFactorVerification` attribute for the status of the second factor verification process. ```typescript function attemptSecondFactor(params: AttemptSecondFactorParams): Promise ``` #### `AttemptSecondFactorParams` * `strategy` * `'phone_code' | 'totp'` The strategy to be used for second factor verification. Possible `strategy` values are * `'phone_code'`: User will receive a one-time authentication code via SMS. At least one phone number should be on file for the user. * `'totp'`: User must provide a 6-digit TOTP code generated by their authenticator app. The user must have previously created a TOTP secret and registered it in their authenticator app using a QR code, URI, or by manually entering the secret. *** * `code` * `string` {/* Comment to prevent lists from being merged into one */} * For the `'phone_code'` strategy: The one-time code that was sent to the user as part of the `prepareSecondFactor()` step. * For the `'totp'` strategy: The TOTP generated by the user's authenticator app. #### Example ```js const signIn = await clerk.signIn.attemptSecondFactor({ strategy: 'phone_code', code: '123456', }) ``` For a comprehensive example, see the [custom flow for multi-factor authentication](/docs/guides/development/custom-flows/authentication/email-password-mfa). ### `authenticateWithBase()` Initiates an authentication flow using Base, allowing users to authenticate via their Web3 wallet address. This method prompts the user to connect their Base account and sign a message to verify ownership of the wallet address. ```typescript function authenticateWithBase(): Promise ``` ### `authenticateWithCoinbaseWallet()` Initiates an authentication flow using the Coinbase Wallet browser extension, allowing users to authenticate via their Web3 wallet address. This method prompts the user to connect their Coinbase Wallet and sign a message to verify ownership of the wallet address. ```typescript function authenticateWithCoinbaseWallet(): Promise ``` #### Example ```js const signIn = await clerk.signIn.authenticateWithCoinbaseWallet() ``` ### `authenticateWithMetamask()` Initiates an authentication flow using the MetaMask browser extension, allowing users to authenticate via their Ethereum wallet address. This method prompts the user to connect their MetaMask wallet and sign a message to verify ownership of the wallet address. ```typescript function authenticateWithMetamask(): Promise ``` #### Example ```js const signIn = await clerk.signIn.authenticateWithMetamask() ``` ### `authenticateWithOKXWallet()` Initiates an authentication flow using the OKX Wallet browser extension, allowing users to authenticate via their Web3 wallet address. This method prompts the user to connect their OKX Wallet and sign a message to verify ownership of the wallet address. ```typescript function authenticateWithOKXWallet(): Promise ``` #### Example ```js const signIn = await clerk.signIn.authenticateWithOKXWallet() ``` ### `authenticateWithPasskey()` Initiates a passkey-based authentication flow, enabling users to authenticate using a previously registered passkey. When called without parameters, this method requires a prior call to `SignIn.create({ strategy: 'passkey' })` to initialize the sign-in context. This pattern is particularly useful in scenarios where the authentication strategy needs to be determined dynamically at runtime. ```ts function authenticateWithPasskey(params?: AuthenticateWithPasskeyParams): Promise ``` ##### `AuthenticateWithPasskeyParams` * `flow` * `'autofill' | 'discoverable'` The flow to use for the passkey sign-in. * `'autofill'`: The client prompts your users to select a passkey before they interact with your app. * `'discoverable'`: The client requires the user to interact with the client. #### Example ```js const signIn = await clerk.signIn.authenticateWithPasskey({ flow: 'discoverable' }) ``` ### `authenticateWithRedirect()` Signs in a user via a Single Sign On (SSO) connection, such as OAuth or SAML, where an external account is used for verifying the user's identity. ```typescript function authenticateWithRedirect(params: AuthenticateWithRedirectParams): Promise ``` #### `AuthenticateWithRedirectParams` * `strategy` * [OAuthStrategy](/docs/reference/javascript/types/sso#o-auth-strategy) | 'saml' | 'enterprise\_sso' The strategy to use for authentication. The following strategies are supported: * `'oauth_'`: The user will be authenticated with their [social connection account](/docs/guides/configure/auth-strategies/social-connections/all-providers). See a list of [supported values for ``](/docs/reference/javascript/types/sso). * `'saml'` (deprecated): **Deprecated in favor of `'enterprise_sso'`.** The user will be authenticated with their [SAML account](/docs/guides/configure/auth-strategies/enterprise-connections/overview#saml). * `'enterprise_sso'`: The user will be authenticated either through SAML or OIDC depending on the configuration of their [enterprise SSO account](/docs/guides/configure/auth-strategies/enterprise-connections/overview). *** * `redirectUrl` * `string` The full URL or path that the OAuth provider should redirect to, on successful authorization on their part. Typically, this will be a simple `/sso-callback` route that calls [`Clerk.handleRedirectCallback`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. *** * `redirectUrlComplete` * `string` The full URL or path that the user will be redirected to once the sign-in is complete. *** * `identifier` * `string | undefined` The ID used to target an enterprise connection during sign-in. *** * `emailAddress` * `string | undefined` The email address used to target an enterprise connection during sign-in. *** * `legalAccepted` * `boolean | undefined` A boolean indicating whether the user has agreed to the [legal compliance](/docs/guides/secure/legal-compliance) documents. #### Example For OAuth connections, see the [custom flow for OAuth connections](/docs/guides/development/custom-flows/authentication/oauth-connections). For enterprise connections, see the [custom flow for enterprise connections](/docs/guides/development/custom-flows/authentication/enterprise-connections). ### `authenticateWithPopup()` Opens a popup window to allow a user to sign in via a Single Sign On (SSO) connection, such as OAuth or SAML, where an external account is used for verifying the user's identity. ```typescript function authenticateWithPopup(params: AuthenticateWithPopupParams): Promise ``` #### `AuthenticateWithPopupParams` * `redirectUrl` * `string` The full URL or path that the OAuth provider should redirect to after successful authorization on their part. Typically, this will be a simple `/sso-callback` route that either calls [`Clerk.handleRedirectCallback`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. *** * `redirectUrlComplete` * `string` The full URL or path to navigate to after the OAuth or SAML flow completes. *** * `strategy` * `'oauth_' | 'saml' | 'enterprise_sso'` The strategy to use for authentication. The following strategies are supported: * `'oauth_'`: The user will be authenticated with their [social connection account](/docs/guides/configure/auth-strategies/social-connections/all-providers). See a list of [supported values for ``](/docs/reference/javascript/types/sso). * `'saml'` (deprecated): **Deprecated in favor of `'enterprise_sso'`.** The user will be authenticated with their [SAML account](/docs/guides/configure/auth-strategies/enterprise-connections/overview#saml). * `'enterprise_sso'`: The user will be authenticated either through SAML or OIDC depending on the configuration of their [enterprise SSO account](/docs/guides/configure/auth-strategies/enterprise-connections/overview). *** * `popup` * `Window` A reference to a popup window opened via `window.open()`. *** * `continueSignUp?` * `boolean | undefined` Whether to continue (i.e. PATCH) an existing `SignUp` (if present) or create a new `SignUp`. *** * `emailAddress?` * `string | undefined` Email address to use for targeting an enterprise connection at sign-up. *** * `identifier?` * `string | undefined` Identifier to use for targeting an enterprise connection at sign-up. *** * `legalAccepted?` * `boolean` A boolean indicating whether the user has agreed to the [legal compliance](/docs/guides/secure/legal-compliance) documents. *** * `unsafeMetadata?` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend. Once the sign-up is complete, the value of this field will be automatically copied to the newly created user's unsafe metadata. One common use case for this attribute is to use it to implement custom fields that can be collected during sign-up and will automatically be attached to the created `User` object. #### Example ```js await clerk.signIn.authenticateWithPopup({ popup: window.open('https://example.com', '_blank'), strategy: 'oauth_google', redirectUrl: '/sso-callback', redirectUrlComplete: '/home', }) ``` ### `authenticateWithWeb3()` Initiates a Web3 authentication flow by verifying the user's ownership of a blockchain wallet address through cryptographic signature verification. This method enables decentralized authentication without requiring traditional credentials. ```typescript function authenticateWithWeb3(params: AuthenticateWithWeb3Params): Promise ``` #### `AuthenticateWithWeb3Params` * `identifier` * `string` The user's Web3 ID. *** * `generateSignature` * `(opts: GenerateSignatureParams) => Promise` The method of how to generate the signature for the Web3 sign-in. See [`GenerateSignatureParams`](#generate-signature-params) for more information. *** * `strategy?` * `Web3Strategy` The Web3 verification strategy. ##### `GenerateSignatureParams` * `identifier` * `string` The user's Web3 wallet address. *** * `nonce` * `string` The [cryptographic nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) used in the sign-in. *** * `provider?` * `Web3Provider` The Web3 provider to generate the signature with. #### Example ```js const signIn = await clerk.signIn.authenticateWithWeb3({ identifier: '0x1234567890123456789012345678901234567890', }) ``` ### `create()` Creates and returns a new `SignIn` instance initialized with the provided parameters. The instance maintains the sign-in lifecycle state through its `status` property, which updates as the authentication flow progresses. This method serves as the entry point for initiating a sign-in flow. What you must pass to `params` depends on which [sign-in options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) you have enabled in your app's settings in the Clerk Dashboard. You can complete the sign-in process in one step if you supply the required fields to `create()`. Otherwise, Clerk's sign-in process provides great flexibility and allows users to easily create multi-step sign-in flows. > \[!WARNING] > Once the sign-in process is complete, pass the `createdSessionId` to the [`setActive()`](/docs/reference/javascript/clerk#set-active) method on the `Clerk` object. This will set the newly created session as the active session. ```typescript function create(params: SignInCreateParams): Promise ``` #### `SignInCreateParams` * `strategy?` * `'password' | 'email_link' | 'email_code' | 'phone_code' | 'oauth_' | 'saml' | 'enterprise_sso' | 'passkey' | 'web3_base_signature' | 'web3_metamask_signature' | 'web3_coinbase_wallet_signature' | 'web3_okx_wallet_signature' | 'ticket' | 'google_one_tap'` The first factor verification strategy to use in the sign-in flow. Depends on the `SignIn.identifier` value. Each authentication identifier supports different verification strategies. The following strategies are supported: * `'password'`: The verification will attempt to be completed using the user's password. * `'email_link'`: User will receive an email magic link via email. The `identifier` parameter can also be specified to select one of the user's known email addresses. The `redirectUrl` parameter can also be specified. * `'email_code'`: User will receive a one-time authentication code via email. The `identifier` parameter can also be specified to select one of the user's known email addresses. * `'phone_code'`: User will receive a one-time authentication code via SMS. The `identifier` parameter can also be specified to select one of the user's known phone numbers. * `'oauth_'`: The user will be authenticated with their [social connection account](/docs/guides/configure/auth-strategies/social-connections/all-providers). See a list of [supported values for ``](/docs/reference/javascript/types/sso). * `'saml'` (deprecated): **Deprecated in favor of `'enterprise_sso'`.** The user will be authenticated with their [SAML account](/docs/guides/configure/auth-strategies/enterprise-connections/overview#saml). * `'enterprise_sso'`: The user will be authenticated either through SAML or OIDC depending on the configuration of their [enterprise SSO account](/docs/guides/configure/auth-strategies/enterprise-connections/overview). * `'passkey'`: The user will be authenticated with their [passkey](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#passkeys). * `'web3_base_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Base](https://docs.base.org/base-account/guides/authenticate-users). The `identifier` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'web3_metamask_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Metamask](/docs/guides/configure/auth-strategies/web3/metamask). The `identifier` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'web3_coinbase_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Coinbase Wallet](/docs/guides/configure/auth-strategies/web3/coinbase-wallet). The `identifier` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'web3_okx_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [OKX Wallet](/docs/guides/configure/auth-strategies/web3/okx-wallet). The `identifier` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'ticket'`: The user will be authenticated via the ticket *or token* generated from the Backend API. * `'google_one_tap'`: The user will be authenticated with the Google One Tap UI. It's recommended to use authenticateWithGoogleOneTap() instead, as it will also set the user's current session as active for you. *** * `identifier` * `string` The authentication identifier for the sign-in. This can be the value of the user's email address, phone number, username, or Web3 wallet address. *** * `password?` * `string` The user's password. Only supported if `strategy` is set to `'password'` and [**Password**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#password) is enabled. *** * `ticket?` * `string` **Required** if `strategy` is set to `'ticket'`. The [ticket *or token*](/docs/guides/development/custom-flows/authentication/embedded-email-links#generate-a-sign-in-token) generated from the Backend API. *** * `redirectUrl?` * `string` If `strategy` is set to `'oauth_'` or `'enterprise_sso'`, this specifies the full URL or path that the OAuth provider should redirect to after successful authorization on their part. Typically, this will be a simple `/sso-callback` route that either calls [`Clerk.handleRedirectCallback`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. If `strategy` is set to `'email_link'`, this specifies the URL that the user will be redirected to when they visit the email link. See the [custom flow](/docs/guides/development/custom-flows/authentication/email-links) for implementation details. *** * `actionCompleteRedirectUrl?` * `string` **Optional** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The URL that the user will be redirected to, after successful authorization from the OAuth provider and Clerk sign-in. *** * `transfer?` * `boolean` When set to `true`, the `SignIn` will attempt to retrieve information from the active `SignUp` instance and use it to complete the sign-in process. This is useful when you want to seamlessly transition a user from a sign-up attempt to a sign-in attempt. *** * `oidcPrompt?` * `string` **Optional** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The value to pass to the [OIDC `prompt` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=prompt,reauthentication%20and%20consent.) in the generated OAuth redirect URL. *** * `oidcLoginHint?` * `string` **Optional** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The value to pass to the [OIDC `login_hint` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=login_hint,in%20\(if%20necessary\).) in the generated OAuth redirect URL. #### Example ```js await clerk.signIn.create({ strategy: 'email_link', identifier: 'test@example.com', }) ``` For comprehensive examples, see the [custom flow guides](/docs/guides/development/custom-flows/overview). ### `createEmailLinkFlow()` Creates a flow for authenticating users via email links. This method returns functions for initiating and canceling the email link verification process; see the [returns](#returns) section for more information. ```typescript function createEmailLinkFlow(): { startEmailLinkFlow: (params: SignInStartEmailLinkFlowParams) => Promise cancelEmailLinkFlow: () => void } ``` #### Returns `createEmailLinkFlow` returns an object with two functions: * `startEmailLinkFlow` * (params: [SignInStartEmailLinkFlowParams](#sign-in-start-email-link-flow-params)) => Promise\ Function to start the email link flow. It prepares an email link verification and polls for the verification result. *** * `cancelEmailLinkFlow` * `() => void` Function to cleanup the email link flow. Stops waiting for verification results. #### `SignInStartEmailLinkFlowParams` * `emailAddressId` * `string` The ID of the user's email address that's going to be used as the first factor identification for verification. *** * `redirectUrl` * `string` The full URL that the user will be redirected to when they visit the email link. #### Example ```js const { startEmailLinkFlow, cancelEmailLinkFlow } = clerk.signIn.createEmailLinkFlow() ``` For a comprehensive example, see the [custom flow for email links](/docs/guides/development/custom-flows/authentication/email-links). ### `prepareFirstFactor()` Begins the first factor verification process. This is a required step in order to complete a sign in, as users should be verified at least by one factor of authentication. Common scenarios are one-time code (OTP) or social account (SSO) verification. This is determined by the accepted `strategy` parameter values. Each authentication identifier supports different strategies. Returns a `SignIn` object. Check the `firstFactorVerification` attribute for the status of the first factor verification process. ```typescript function prepareFirstFactor(params: PrepareFirstFactorParams): Promise ``` #### `PrepareFirstFactorParams` * `strategy` * `'email_link' | 'email_code' | 'phone_code' | 'web3_base_signature' | 'web3_metamask_signature' | 'web3_coinbase_wallet_signature' | 'web3_okx_wallet_signature' | 'passkey' | 'oauth_' | 'saml' | 'enterprise_sso' | 'reset_password_phone_code' | 'reset_password_email_code'` The `strategy` value depends on the `SignIn.identifier` value. Each authentication identifier supports different verification strategies. The following strategies are supported: * `'email_link'`: User will receive an email magic link via email. * `'email_code'`: User will receive a one-time authentication code via email. Requires `emailAddressId` parameter to be set. * `'phone_code'`: User will receive a one-time authentication code via SMS. Requires `phoneNumberId` parameter to be set. * `'web3_base_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Base](https://docs.base.org/base-account/guides/authenticate-users). Requires `web3WalletId` parameter to be set. * `'web3_metamask_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Metamask](https://metamask.io/). Requires `web3WalletId` parameter to be set. * `'web3_coinbase_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Coinbase Wallet](https://www.coinbase.com/wallet). Requires `web3WalletId` parameter to be set. * `'web3_okx_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [OKX Wallet](https://www.okx.com/help/section/faq-web3-wallet). Requires `web3WalletId` parameter to be set. * `'passkey'`: The verification will attempt to be completed using the user's passkey. * `'oauth_'`: The user will be authenticated with their [social connection account](/docs/guides/configure/auth-strategies/social-connections/all-providers). See a list of [supported values for ``](/docs/reference/javascript/types/sso). * `'saml'` (deprecated): **Deprecated in favor of `'enterprise_sso'`.** The user will be authenticated with their [SAML account](/docs/guides/configure/auth-strategies/enterprise-connections/overview#saml). * `'enterprise_sso'`: The user will be authenticated either through SAML or OIDC depending on the configuration of their [enterprise SSO account](/docs/guides/configure/auth-strategies/enterprise-connections/overview). * `'reset_password_phone_code'`: Used when the user is trying to reset their password. The user will receive a one-time code via SMS. Requires `phoneNumberId` parameter to be set. * `'reset_password_email_code'`: Used when the user is trying to reset their password. The user will receive a one-time code via email. Requires `emailAddressId` parameter to be set. *** * `emailAddressId?` * `string` **Required** if `strategy` is set to `'email_code'` or `'reset_password_email_code'`. The ID for the user's email address that will receive an email with the one-time authentication code. *** * `phoneNumberId?` * `string` **Required** if `strategy` is set to `'phone_code'` or `'reset_password_phone_code'`. The ID for the user's phone number that will receive an SMS message with the one-time authentication code. *** * `web3WalletId?` * `string` **Required** if `strategy` is set to `'web3_base_signature'`, `'web3_metamask_signature'`, `'web3_coinbase_wallet_signature'`, or `'web3_okx_wallet_signature'`. The ID for the user's Web3 wallet address. *** * `redirectUrl?` * `string` **Required** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The full URL or path that the OAuth provider should redirect to after successful authorization on their part. Typically, this will be a simple `/sso-callback` route that either calls [`Clerk.handleRedirectCallback()`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. **Required** if `strategy` is set to `'email_link'`. The full URL that the user will be redirected to when they visit the email link. See the [custom flow](/docs/guides/development/custom-flows/authentication/email-links) for implementation details. *** * `actionCompleteRedirectUrl?` * `string` **Required** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The URL that the user will be redirected to once the first factor verification is complete. #### Example ```js const signIn = await clerk.signIn.prepareFirstFactor({ strategy: 'email_link', identifier: 'test@example.com', }) ``` For comprehensive examples, see the [custom flow guides](/docs/guides/development/custom-flows/overview). ### `prepareSecondFactor()` Begins the second factor (2FA) verification process. Clerk calls this [multi-factor authentication (MFA)](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication). > \[!NOTE] > If the `strategy` was set to `totp` (e.g. `SignIn.create({ strategy: 'totp' })`), it does not require preparation. You can directly attempt the second factor verification by calling [`SignIn.attemptSecondFactor`](#attempt-second-factor). Returns a `SignIn` object. Check the `secondFactorVerification` attribute for the status of the second factor verification process. ```typescript function prepareSecondFactor(params: PrepareSecondFactorParams): Promise ``` #### `PrepareSecondFactorParams` * `strategy` * `'phone_code'` The strategy used for second factor verification. Supported strategies are: * `'phone_code'`: User will receive a one-time authentication code via SMS. At least one phone number should be on file for the user. *** * `phoneNumberId` * `string` The ID for the user's phone number that will receive an SMS message with the one-time authentication code. #### Example ```js const signIn = await clerk.signIn.prepareSecondFactor({ strategy: 'phone_code', phoneNumberId: '123', }) ``` For a comprehensive example, see the [custom flow for multi-factor authentication](/docs/guides/development/custom-flows/authentication/email-password-mfa). ### `resetPassword()` Resets a user's password. It's recommended to use the [custom flow for resetting a user's password](/docs/guides/development/custom-flows/account-updates/forgot-password) instead. ```typescript function resetPassword(params: ResetPasswordParams): Promise ``` #### `ResetPasswordParams` * `password` * `string` The user's current password. *** * `signOutOfOtherSessions?` * `boolean | undefined` If `true`, signs the user out of all other authenticated sessions. #### Example ```js await clerk.signIn.resetPassword({ password: 'new-password', }) ``` --- title: Clerk JavaScript SDK description: The Clerk JavaScript SDK is Clerk's foundational library for building user management and authentication. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/overview.mdx --- The Clerk JavaScript SDK, or ClerkJS, is our foundational JavaScript library for building user management and authentication. It enables you to register, sign in, verify, and manage users for your application using highly customizable flows. It powers the other JavaScript SDKs, such as the React and Next.js SDKs. The following sections will introduce you to the main objects that power the JavaScript SDK. As you're building your application, you'll likely interact with these objects, either directly or through helpers provided by the other SDKs, like React hooks or Vue composables. ## Installation Follow the instructions in the [JavaScript quickstart](/docs/js-frontend/getting-started/quickstart) to add the JavaScript SDK to your project. ## Main objects ### `Clerk` The [`Clerk`](/docs/reference/javascript/clerk) class is the main entry point for the Clerk JavaScript SDK. All other objects are accessible from the `Clerk` object. ### `Client` A client represents the current device or software accessing an application such as your web browser, native application, or Chrome Extension. It is represented by the [`Client`](/docs/reference/javascript/client) object. ### `Session` A session is a secure representation of the authentication state of the current user. Each client can hold multiple sessions on the same device. It is represented by the [`Session`](/docs/reference/javascript/session) object. ### `User` The [`User`](/docs/reference/javascript/user) object represents the current user of the session. It holds all the basic user information such as the user's name, email addresses, and phone numbers, and including their public, private, and unsafe metadata. ### `SignIn` The [`SignIn`](/docs/reference/javascript/sign-in) object holds the state of the current sign-in and provides helper methods to navigate and complete the sign-in process. It is used to manage the sign-in lifecycle, including the first and second factor verification, and the creation of a new session. ### `SignUp` The [`SignUp`](/docs/reference/javascript/sign-up) object holds the state of the current sign-up and provides helper methods to navigate and complete the sign-up process. Once a sign-up is complete, a new user is created. ### `Organization` Organizations are a flexible and scalable way to manage users and their access to resources within your Clerk application. With Organizations, you can assign specific Roles and Permissions to users, making them useful for managing projects, coordinating teams, or facilitating partnerships. Users can belong to many Organizations. One of them will be the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. of the session. It is represented by the [`Organization`](/docs/reference/javascript/organization) object. To learn about Organizations, see the [dedicated guide](/docs/guides/organizations/overview). --- title: "`Organization` object" description: The Organization object holds information about an Organization, as well as methods for managing it. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/organization lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/organization.mdx --- The `Organization` object holds information about an Organization, as well as methods for managing it. To use these methods, you must have the **Organizations** feature [enabled in your app's settings in the Clerk Dashboard](/docs/guides/organizations/overview#enable-organizations-in-your-application). ## Properties * `id` * `string` The unique identifier of the related Organization. *** * `name` * `string` The name of the related Organization. *** * `slug` * `string | null` The Organization slug. If supplied, it must be unique for the instance. *** * `imageUrl` * `string` Holds the Organization logo or default logo. Compatible with Clerk's [Image Optimization](/docs/guides/development/image-optimization). *** * `hasImage` * `boolean` A getter boolean to check if the Organization has an uploaded image. Returns `false` if Clerk is displaying an avatar for the Organization. *** * `membersCount` * `number` The number of members the associated Organization contains. *** * `pendingInvitationsCount` * `number` The number of pending invitations to users to join the Organization. *** * `adminDeleteEnabled` * `boolean` A getter boolean to check if the admin of the Organization can delete it. *** * `maxAllowedMemberships` * `number` The maximum number of memberships allowed for the Organization. A value of `0` means there is no limit on the number of members in the Organization, allowing an unlimited number of members to join. *** * `createdAt` * `Date` The date when the Organization was created. *** * `updatedAt` * `Date` The date when the Organization was last updated. *** * `publicMetadata` * [`OrganizationPublicMetadata`](/docs/reference/javascript/types/metadata#organization-public-metadata) Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. ## Methods ### `addMember()` Adds a user as a member to an organization. A user can only be added to an organization if they are not already a member of it and if they already exist in the same instance as the organization. Only administrators can add members to an organization. Returns an [`OrganizationMembership`](/docs/reference/javascript/types/organization-membership) object. ```typescript function addMember(params: AddMemberParams): Promise ``` #### `AddMemberParams` * `userId` * `string` The ID of the user to be added as a member to the Organization. *** * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) that the user will have in the Organization. #### Example ```js await organization.addMember({ userId: 'user_123', role: 'org:admin' }) ``` ### `createDomain()` Creates a new domain for the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Returns an [`OrganizationDomain`](/docs/reference/javascript/types/organization-domain) object. > \[!WARNING] > You must have [**Verified domains**](/docs/guides/organizations/verified-domains) enabled in your app's settings in the Clerk Dashboard. ```ts function createDomain(domainName: string): Promise ``` #### Parameters * `domainName` * `string` The domain name that will be added to the Organization. #### Example ```js await clerk.organization.createDomain('test-domain.com') ``` ### `destroy()` Deletes the Organization. Only administrators can delete an Organization. Deleting an Organization will also delete all memberships and invitations. **This is not reversible.** ```typescript function destroy(): Promise ``` #### Example ```js await clerk.organization.destroy() ``` ### `getDomain()` Retrieves a domain for an Organization based on the given domain ID. Returns an [`OrganizationDomain`](/docs/reference/javascript/types/organization-domain) object. > \[!WARNING] > You must have [**Verified domains**](/docs/guides/organizations/verified-domains) enabled in your app's settings in the Clerk Dashboard. ```typescript function getDomain(params: GetDomainParams): Promise ``` #### `GetDomainParams` * `domainId` * string The ID of the domain that will be fetched. #### Example ```js await clerk.organization.getDomain({ domainId: 'domain_123' }) ``` ### `getDomains()` Retrieves the list of domains for the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Returns a [`ClerkPaginatedResponse`](/docs/reference/javascript/types/clerk-paginated-response) of [`OrganizationDomain`](/docs/reference/javascript/types/organization-domain) objects. > \[!WARNING] > You must have [**Verified domains**](/docs/guides/organizations/verified-domains) enabled in your app's settings in the Clerk Dashboard. ```typescript function getDomains(params?: GetDomainsParams): Promise> ``` #### `GetDomainsParams` * `initialPage?` * `number` A number that can be used to skip the first n-1 pages. For example, if `initialPage` is set to 10, it is will skip the first 9 pages and will fetch the 10th page. *** * `pageSize?` * `number` A number that indicates the maximum number of results that should be returned for a specific page. *** * `enrollmentMode?` * `'manual_invitation' | 'automatic_invitation' | 'automatic_suggestion'` An [enrollment mode](/docs/guides/organizations/verified-domains#enrollment-mode) will change how new users join an organization. #### Example ```js await clerk.organization.getDomains() ``` ### `getInvitations()` Retrieves the list of invitations for the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Returns a [`ClerkPaginatedResponse`](/docs/reference/javascript/types/clerk-paginated-response) of [`OrganizationInvitation`](/docs/reference/javascript/types/organization-invitation) objects. ```typescript function getInvitations( params?: GetInvitationsParams, ): Promise> ``` #### `GetInvitationsParams` * `initialPage?` * `number` A number that can be used to skip the first n-1 pages. For example, if `initialPage` is set to 10, it is will skip the first 9 pages and will fetch the 10th page. *** * `pageSize?` * `number` A number that indicates the maximum number of results that should be returned for a specific page. *** * `status?` * `'pending' | 'accepted' | 'revoked'` The status an invitation can have. #### Example ```js await clerk.organization.getInvitations() ``` ### `getMemberships()` Retrieves the list of memberships for the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Returns a [`ClerkPaginatedResponse`](/docs/reference/javascript/types/clerk-paginated-response) of [`OrganizationMembership`](/docs/reference/javascript/types/organization-membership) objects. ```typescript function getMemberships( params?: GetMembersParams, ): Promise> ``` #### `GetMembersParams` * `initialPage?` * `number` A number that can be used to skip the first n-1 pages. For example, if `initialPage` is set to 10, it is will skip the first 9 pages and will fetch the 10th page. *** * `pageSize?` * `number` A number that indicates the maximum number of results that should be returned for a specific page. *** * `role?` * [OrganizationCustomRoleKey](/docs/reference/javascript/types/organization-custom-role-key)\[] The [Roles](/docs/guides/organizations/roles-and-permissions) of memberships that will be included in the response. #### Example For an example on how to use `getMemberships()`, see the [custom flow on managing Organization Roles](/docs/guides/development/custom-flows/organizations/manage-roles). ### `getMembershipRequests()` Retrieve the list of membership requests for the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Returns a [`ClerkPaginatedResponse`](/docs/reference/javascript/types/clerk-paginated-response) of [`OrganizationMembershipRequest`](/docs/reference/javascript/types/organization-membership)-request) objects. > \[!WARNING] > You must have [**Organizations**](/docs/guides/organizations/overview#enable-organizations-in-your-application), and [**Verified domains** and **Automatic suggestion**](/docs/guides/organizations/verified-domains) enabled in your app's settings in the Clerk Dashboard. ```ts function getMembershipRequests( params?: GetMembershipRequestParams, ): Promise> ``` #### `GetMembershipRequestParams` * `initialPage?` * `number` A number that can be used to skip the first n-1 pages. For example, if `initialPage` is set to 10, it is will skip the first 9 pages and will fetch the 10th page. *** * `pageSize?` * `number` A number that indicates the maximum number of results that should be returned for a specific page. *** * `status?` * `string` The status of the membership requests that will be included in the response. #### Example For an example on how to use `getMembershipRequests()`, see the [custom flow guide on managing membership requests](/docs/guides/development/custom-flows/organizations/manage-membership-requests). ### `getRoles()` Returns a paginated list of Roles in the Organization. Returns a [`ClerkPaginatedResponse`](/docs/reference/javascript/types/clerk-paginated-response) of [`RoleResource`](/docs/reference/javascript/types/role) objects. ```ts function getRoles(params?: GetRolesParams): Promise> ``` #### `GetRolesParams` * `initialPage?` * `number` A number that can be used to skip the first n-1 pages. For example, if `initialPage` is set to 10, it is will skip the first 9 pages and will fetch the 10th page. *** * `pageSize?` * `number` A number that indicates the maximum number of results that should be returned for a specific page. #### Example ```js await clerk.organization.getRoles() ``` ### `inviteMember()` Creates and sends an invitation to the target email address for becoming a member with the Role passed on the function parameters. Returns an [`OrganizationInvitation`](/docs/reference/javascript/types/organization-invitation) object. ```typescript function inviteMember(params: InviteMemberParams): Promise ``` #### `InviteMemberParams` * `emailAddress` * `string` The email address to invite. *** * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) of the new member. #### Example ```js await clerk.organization.inviteMember({ emailAddress: 'test@test.com', role: 'org:member' }) ``` ### `inviteMembers()` Creates and sends an invitation to the target email addresses for becoming a member with the Role passed in the parameters. Returns an array of [`OrganizationInvitation`](/docs/reference/javascript/types/organization-invitation) objects. ```typescript function inviteMembers(params: InviteMembersParams): Promise ``` #### `InviteMembersParams` * `emailAddresses` * `string[]` The email addresses to invite. *** * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) of the new members. #### Example ```js await clerk.organization.inviteMembers({ emailAddresses: ['test@test.com', 'test2@test.com'], role: 'org:member', }) ``` ### `removeMember()` Removes a member from the Organization based on the `userId`. Returns an [`OrganizationMembership`](/docs/reference/javascript/types/organization-membership) object. ```typescript function removeMember(userId: string): Promise ``` #### Parameters * `userId` * `string` The ID of the user to remove from the Organization. #### Example ```js await organization.removeMember('user_123') ``` ### `setLogo()` Sets or replaces an Organization's logo. The logo must be an image and its size cannot exceed 10MB. Returns an `Organization` object. ```typescript function setLogo(params: SetOrganizationLogoParams): Promise ``` #### `SetOrganizationLogoParams` * `file` * `File | Blob | null` An image file or blob which cannot exceed 10MB. Passing `null` will delete the Organization's current logo. #### Example ```js await clerk.organization.setLogo({ file }) ``` ### `update()` Updates an Organization's attributes. Returns an `Organization` object. ```typescript function update(params: UpdateOrganizationParams): Promise ``` #### `UpdateOrganizationParams` * `name` * `string` The Organization name. *** * `slug?` * `string | undefined` The Organization slug. *** * `maxAllowedMemberships?` * `number | undefined` The maximum number of memberships allowed for the Organization. Setting this value to `0` removes any limit, allowing an unlimited number of memberships. *** * `publicMetadata?` * [`OrganizationPublicMetadata`](/docs/reference/javascript/types/metadata#organization-public-metadata) Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API. *** * `privateMetadata?` * [`OrganizationPrivateMetadata`](/docs/reference/javascript/types/metadata#organization-private-metadata) Metadata that is only visible to your [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. #### Example ```js await clerk.organization.update({ name: 'New Name' }) ``` ### `updateMember()` Updates a member. Currently, only a user's Role can be updated. Returns an [`OrganizationMembership`](/docs/reference/javascript/types/organization-membership) object. ```typescript function updateMember(params: UpdateMembershipParams): Promise ``` #### `UpdateMembershipParams` * `userId` * `string` The ID of the user to update. *** * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) of the new member. #### Example ```js await organization.updateMember({ userId: 'user_123', role: 'org:admin' }) ``` [org-domain-ref]: /docs/reference/javascript/types/organization-domain [org-inv-ref]: /docs/reference/javascript/types/organization-invitation [org-mem-ref]: /docs/reference/javascript/types/organization-membership [roles-perms-ref]: /docs/guides/organizations/roles-and-permissions [pag-ref]: /docs/reference/javascript/types/clerk-paginated-response [verified-domains-ref]: /docs/guides/organizations/verified-domains --- title: Session description: The Session object is an abstraction over an HTTP session. It models the period of information exchange between a user and the server. search: rank: 1 keywords: - getToken() sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/session lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/session.mdx --- The `Session` object is an abstraction over an HTTP session. It models the period of information exchange between a user and the server. The `Session` object includes methods for recording session activity and ending the session client-side. For security reasons, sessions can also expire server-side. As soon as a [`User`](/docs/reference/javascript/user) signs in, Clerk creates a `Session` for the current [`Client`](/docs/reference/javascript/client). Clients can have more than one sessions at any point in time, but only one of those sessions will be **active**. In certain scenarios, a session might be replaced by another one. This is often the case with [multi-session applications](/docs/guides/secure/session-options#multi-session-applications). All sessions that are **expired**, **removed**, **replaced**, **ended** or **abandoned** are not considered valid. > \[!NOTE] > For more information regarding the different session states, see the [guide on session management](/docs/guides/secure/session-options). ## Properties * `id` * `string` The unique identifier for the session. *** * `user` * [`User`](/docs/reference/javascript/user) The user associated with the session. *** * `publicUserData` * [`PublicUserData`](/docs/reference/javascript/types/public-user-data) Public information about the user that this session belongs to. *** * `status` * [`SessionStatus`](/docs/reference/javascript/types/session-status) The current state of the session. *** * `lastActiveAt` * `Date` The time the session was last active on the [`Client`](/docs/reference/javascript/client). *** * `abandonAt` * `Date` The time when the session was abandoned by the user. *** * `expireAt` * `Date` The time the session expires and will cease to be active. *** * `updatedAt` * `Date` The last time the session recorded activity of any kind. *** * `createdAt` * `Date` The date when the session was created. *** * `lastActiveToken` * `TokenResource | null` The last active token for the session *** * `lastActiveOrganizationId` * `string | null` The ID of the last Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. *** * `factorVerificationAge` * `[number, number] | null` An array where each item represents the number of minutes since the last verification of a first or second factor: `[firstFactorAge, secondFactorAge]`. *** * `actor` * `ActJWTClaim | null` The JWT actor for the session. Holds identifier for the user that is impersonating the current user. Read more about [impersonation](/docs/guides/users/impersonation). *** * `currentTask` * [SessionTask](/docs/reference/javascript/types/session-task) | null The current pending task for the session. Read more about [session tasks](/docs/guides/configure/session-tasks). ## Methods ### `attemptFirstFactorVerification()` Attempts to complete the first factor verification process. Returns a [`SessionVerification`](/docs/reference/javascript/types/session-verification) instance with its status and supported factors. ```typescript function attemptFirstFactorVerification( params: SessionVerifyAttemptFirstFactorParams, ): Promise ``` #### `SessionVerifyAttemptFirstFactorParams` ```ts type SessionVerifyAttemptFirstFactorParams = EmailCodeAttempt | PhoneCodeAttempt | PasswordAttempt type EmailCodeAttempt = { strategy: 'email_code' code: string } type PhoneCodeAttempt = { strategy: 'phone_code' code: string } type PasswordAttempt = { strategy: 'password' password: string } ``` #### Example ```js await clerk.session.attemptFirstFactorVerification({ strategy: 'email_code', code: '123456', }) ``` ### `attemptSecondFactorVerification()` Attempts to complete the second factor verification process. Returns a [`SessionVerification`](/docs/reference/javascript/types/session-verification) instance with its status and supported factors. ```typescript function attemptSecondFactorVerification( params: SessionVerifyAttemptSecondFactorParams, ): Promise ``` #### `SessionVerifyAttemptSecondFactorParams` ```ts type SessionVerifyAttemptSecondFactorParams = PhoneCodeAttempt | TOTPAttempt | BackupCodeAttempt type PhoneCodeAttempt = { strategy: 'phone_code' code: string } type TOTPAttempt = { strategy: 'totp' code: string } type BackupCodeAttempt = { strategy: 'backup_code' code: string } ``` #### Example ```js await clerk.session.attemptSecondFactorVerification({ strategy: 'phone_code', code: '123456', }) ``` ### `checkAuthorization()` Checks if the user is [authorized for the specified Role, Permission, Feature, or Plan](/docs/guides/secure/authorization-checks) or requires the user to [reverify their credentials](/docs/guides/secure/reverification) if their last verification is older than allowed. ```ts function checkAuthorization(param: CheckAuthorizationParams): boolean ``` #### `CheckAuthorizationParams` ```typescript type WithReverification = T & { /** * The reverification configuration to check for. This feature is currently in public beta. **It is not recommended for production use.** */ reverification?: ReverificationConfig } type CheckAuthorizationParams = WithReverification< | { /** * The [Role](https://clerk.com/docs/guides/organizations/roles-and-permissions) to check for. */ role: OrganizationCustomRoleKey /** * The [Permission](https://clerk.com/docs/guides/organizations/roles-and-permissions) to check for. */ permission?: never /** * The [Feature](https://clerk.com/docs/guides/billing/overview) to check for. */ feature?: never /** * The [Plan](https://clerk.com/docs/guides/billing/overview) to check for. */ plan?: never } | { role?: never permission: OrganizationPermissionKey feature?: never plan?: never } | { role?: never permission?: never feature: Autocomplete<`user:${string}` | `org:${string}`> plan?: never } | { role?: never permission?: never feature?: never plan: Autocomplete<`user:${string}` | `org:${string}`> } | { role?: never; permission?: never; feature?: never; plan?: never } > ``` * `role` * `string` Accepts [Role](/docs/guides/organizations/roles-and-permissions#roles) key. *** * `permission` * `string` Accepts [Permission](/docs/guides/organizations/roles-and-permissions#permissions) key. *** * `feature` * `string` Accepts [Feature](/docs/guides/secure/features) key. *** * `plan` * `string` Accepts [Plan](/docs/guides/billing/overview) key. *** * `reverification?` * ReverificationConfig The reverification configuration to check for. This feature is currently in public beta. **It is not recommended for production use**. #### Example: Authorization For more information, see the [guide on authorization checks](/docs/guides/secure/authorization-checks). ```js // Check if the current user has the 'admin' Role await clerk.session.checkAuthorization({ role: 'admin', }) ``` #### Example: Reverification For more information, see the [guide on reverification](/docs/guides/secure/reverification). ```js // Require the user to reverify their first factor after 2 minutes await clerk.session.checkAuthorization({ reverification: { afterMinutes: 2, level: 'first_factor' }, }) ``` ### `end()` Terminates the current session, invalidating it for this `Client` instance. Upon completion, the session's status transitions to **ended** and all associated authentication tokens are revoked. This operation cannot be undone and requires re-authentication to establish a new session. ```typescript function end(): Promise ``` #### Example ```js await clerk.session.end() ``` ### `getToken()` Retrieves the current user's [session token](/docs/guides/sessions/session-tokens) or a [custom JWT template](/docs/guides/sessions/jwt-templates). This method uses a cache so a network request will only be made if the token in memory has expired. The TTL for a Clerk token is one minute. Tokens can only be generated if the user is signed in. ```typescript function getToken(options?: GetTokenOptions): Promise ``` #### `GetTokenOptions` * `leewayInSeconds` * `number` The number of seconds to allow the token to be cached for. *** * `template?` * `string` The name of the JWT template from the [Clerk Dashboard](https://dashboard.clerk.com/~/jwt-templates) to generate a new token from. E.g. 'firebase', 'grafbase', or your custom template's name. *** * `throwOnError?` * `boolean` Whether to throw an error or return an empty string, if an error occurs. *** * `skipCache?` * `boolean` Whether to skip the cache lookup and force a call to the server instead, even within the TTL. Useful if the token claims are time-sensitive or depend on data that can be updated (e.g. user fields). Defaults to `false`. *** * `organizationId?` * `string` The Organization associated with the generated session token. *Does not modify the session's currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization..* #### Example ```js await clerk.session.getToken({ template: 'Test' }) ``` ### `prepareFirstFactorVerification()` Initiates the first factor verification process. This is a required step to complete a reverification flow when using a preparable factor. Returns a [`SessionVerification`](/docs/reference/javascript/types/session-verification) instance with its status and supported factors. ```typescript function prepareFirstFactorVerification( params: SessionVerifyPrepareFirstFactorParams, ): Promise ``` #### `SessionVerifyPrepareFirstFactorParams` ```ts type SessionVerifyPrepareFirstFactorParams = EmailCodeConfig | PhoneCodeConfig type EmailCodeConfig = { strategy: 'email_code' primary?: boolean | undefined emailAddressId: string } type PhoneCodeConfig = { strategy: 'phone_code' phoneNumberId: string primary?: boolean default?: boolean } ``` #### Example ```js await clerk.session.prepareFirstFactorVerification({ strategy: 'email_code', emailAddressId: 'email_address_123', }) ``` ### `prepareSecondFactorVerification()` Initiates the second factor verification process. This is a required step to complete a reverification flow when using a preparable factor. Returns a [`SessionVerification`](/docs/reference/javascript/types/session-verification) instance with its status and supported factors. ```typescript function prepareSecondFactorVerification( params: SessionVerifyPrepareSecondFactorParams, ): Promise ``` #### `SessionVerifyPrepareSecondFactorParams` ```ts type SessionVerifyPrepareSecondFactorParams = PhoneCodeSecondFactorConfig type PhoneCodeSecondFactorConfig = { strategy: 'phone_code' phoneNumberId?: string } ``` #### Example ```js await clerk.session.prepareSecondFactorVerification({ strategy: 'phone_code', }) ``` ### `remove()` Invalidates the current session by marking it as removed. Once removed, the session will be deactivated for the current Client instance and its `status` will be set to `removed`. This operation cannot be undone. ```typescript function remove(): Promise ``` #### Example ```js await clerk.session.remove() ``` ### `startVerification()` Initiates the reverification flow. Returns a [`SessionVerification`](/docs/reference/javascript/types/session-verification) instance with its status and supported factors. ```typescript function startVerification(params: SessionVerifyCreateParams): Promise ``` #### `SessionVerifyCreateParams` ```typescript type SessionVerifyCreateParams = { level: 'first_factor' | 'second_factor' | 'multi_factor' } ``` #### Example ```js await clerk.session.startVerification({ level: 'first_factor', }) ``` ### `touch()` Updates the session's last active timestamp to the current time. This method should be called periodically to indicate ongoing user activity and prevent the session from becoming stale. The updated timestamp is used for session management and analytics purposes. ```typescript function touch(): Promise ``` #### Example ```js await clerk.session.touch() ``` [client-ref]: /docs/reference/javascript/client --- title: "`Client`" description: The Client object keeps track of the authenticated sessions in the current device. The device can be a browser, a native application or any other medium that is usually the requesting part in a request/response architecture. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/client lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/client.mdx --- The `Client` object keeps track of the authenticated sessions in the current device. The device can be a browser, a native application or any other medium that is usually the requesting part in a request/response architecture. The `Client` object also holds information about any sign in or sign up attempts that might be in progress, tracking the sign in or sign up progress. ## Properties * `signIn` * [SignIn](/docs/reference/javascript/sign-in) | null The current sign in attempt, or `null` if there is none. *** * `signUp` * [SignUp](/docs/reference/javascript/sign-up) | null The current sign up attempt, or `null` if there is none. *** * `sessions` * [`Session[]`](/docs/reference/javascript/session) A list of sessions that have been created on this client. *** * `activeSessions` * [`Session[]`](/docs/reference/javascript/session) A list of active sessions on this client. *** * `lastActiveSessionId` * `string` The ID of the last active [`Session`](/docs/reference/javascript/session) on this client. *** * `lastAuthenticationStrategy` * [LastAuthenticationStrategy](/docs/reference/javascript/types/last-authentication-strategy) | null The last authentication strategy used by the client, or `null` if there is none. *** * `updatedAt` * `Date` Timestamp of last update for the client. ## Methods ### `isNew()` Returns `true` if this client hasn't been saved (created) yet in the Frontend API. Returns `false` otherwise. ```typescript function isNew(): boolean ``` ### `create()` Creates a new client for the current instance along with its cookie. ```typescript function create(): Promise ``` ### `destroy()` Deletes the client. All sessions will be reset. ```typescript function destroy(): Promise ``` --- title: "`SignUp`" description: The SignUp object holds the state of the current sign-up and provides helper methods to navigate and complete the sign-up flow. Once a sign-up is complete, a new user is created. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/sign-up lastUpdated: 2025-11-21T22:25:46.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/sign-up.mdx --- The `SignUp` object holds the state of the current sign-up and provides helper methods to navigate and complete the sign-up process. Once a sign-up is complete, a new user is created. The following steps outline the sign-up process: 1. Initiate the sign-up process by collecting the user's authentication information and passing the appropriate parameters to the [`create()`](#create) method. 2. Prepare the verification. 3. Attempt to complete the verification. 4. If the verification is successful, set the newly created session as the active session by passing the `SignIn.createdSessionId` to the [`setActive()`](/docs/reference/javascript/clerk#set-active) method on the `Clerk` object. ## Properties * `id` * `string | undefined` The unique identifier of the current sign-up. *** * `status` * `'missing_requirements' | 'complete' | 'abandoned' | null` The status of the current sign-up. The following values are supported: * `complete:` The user has been created and the custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview). can proceed to `setActive()` to create session. * `missing_requirements:` A requirement is unverified or missing from the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) settings. For example, in the Clerk Dashboard, the **Password** setting is required but a password wasn't provided in the custom flow. * `abandoned:` The sign-up has been inactive for over 24 hours. *** * `requiredFields` * `string[]` An array of all the required fields that need to be supplied and verified in order for this sign-up to be marked as complete and converted into a user. *** * `optionalFields` * `string[]` An array of all the fields that can be supplied to the sign-up, but their absence does not prevent the sign-up from being marked as complete. *** * `missingFields` * `string[]` An array of all the fields whose values are not supplied yet but they are mandatory in order for a sign-up to be marked as complete. *** * `unverifiedFields` * `string[]` An array of all the fields whose values have been supplied, but they need additional verification in order for them to be accepted. Examples of such fields are `emailAddress` and `phoneNumber`. *** * `verifications` * `SignUpVerifications` An object that contains information about all the verifications that are in-flight. *** * `username` * `string | null` The [username](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#username) supplied to the current sign-up. Only supported if username is enabled in the instance settings. *** * `emailAddress` * `string | null` The email address supplied to the current sign-up. Only supported if [email address](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) is enabled in the instance settings. *** * `phoneNumber` * `string | null` The user's phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164). Only supported if [phone number](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#phone) is enabled in the instance settings. *** * `web3Wallet` * `string | null` The Web3 wallet address, made up of 0x + 40 hexadecimal characters. Only supported if [Web3 authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#web3-authentication) is enabled in the instance settings. *** * `hasPassword` * `boolean` The value of this attribute is true if a password was supplied to the current sign-up. Only supported if [**Password**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#password) is enabled in the instance settings. *** * `firstName` * `string | null` The first name supplied to the current sign-up. Only supported if [**First and last name**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#user-model) is enabled in the instance settings. *** * `lastName` * `string | null` The last name supplied to the current sign-up. Only supported if [**First and last name**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#user-model) is enabled in the instance settings. *** * `unsafeMetadata` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend. Once the sign-up is complete, the value of this field will be automatically copied to the newly created user's unsafe metadata. One common use case for this attribute is to use it to implement custom fields that can be collected during sign-up and will automatically be attached to the created `User` object. *** * `createdSessionId` * `string | null` The identifier of the newly-created session. This attribute is populated only when the sign-up is complete. *** * `createdUserId` * `string | null` The identifier of the newly-created user. This attribute is populated only when the sign-up is complete. *** * `abandonAt` * `number | null` The epoch numerical time when the sign-up was abandoned by the user. ## Methods ### `attemptEmailAddressVerification()` Attempts to verify an email address by validating the one-time verification code provided by the user against the code sent during the prepare verification step. This is a convenience method that wraps [`SignUp.attemptVerification()`](/docs/reference/javascript/sign-up#attempt-verification) with the `'email_code'` strategy. By default, this method is equivalent to calling `SignUp.attemptVerification({ strategy: 'email_code', code })`. The verification attempt will fail if the code is invalid or has expired. ```typescript function attemptEmailAddressVerification( params: AttemptEmailAddressVerificationParams, ): Promise ``` #### `AttemptEmailAddressVerificationParams` * `code` * `string` The code that was sent to the user via email. ### `attemptPhoneNumberVerification()` Attempts to verify a phone number by validating the one-time verification code provided by the user against the code sent during the prepare verification step. This is a convenience method that wraps [`SignUp.attemptVerification()`](#attempt-verification) with the `'phone_code'` strategy. By default, this method is equivalent to calling `SignUp.attemptVerification({ strategy: 'phone_code', code })`. The verification attempt will fail if the code is invalid or has expired. ```typescript function attemptPhoneNumberVerification( params: AttemptPhoneNumberVerificationParams, ): Promise ``` #### `AttemptPhoneNumberVerificationParams` * `code` * `string` The code that was sent to the user via SMS. ### `attemptVerification()` Attempts to complete a pending verification process for the specified verification strategy. This method must be called after initiating verification via [`SignUp.prepareVerification()`](#prepare-verification). The verification attempt will validate the provided verification parameters (code, signature, etc.) against the pending verification request. Depending on the strategy, the method parameters could differ. ```typescript function attemptVerification(params: AttemptVerificationParams): Promise ``` #### `AttemptVerificationParams` * `strategy` * `'phone_code' | 'email_code' | 'web3_base_signature' | 'web3_metamask_signature' | 'web3_coinbase_wallet_signature' | 'web3_okx_wallet_signature'` The verification strategy to complete the user's sign-up request against. The following strategies are supported: * `'phone_code'`: Validates an SMS with a unique token to input. * `'email_code'`: Validates an email with a unique token to input. * `'web3_base_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Base](https://docs.base.org/base-account/guides/authenticate-users). The `web3_wallet_id` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'web3_metamask_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Metamask](https://metamask.io/). The `web3_wallet_id` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'web3_coinbase_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Coinbase Wallet](https://www.coinbase.com/wallet). The `web3_wallet_id` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'web3_okx_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [OKX Wallet](https://www.okx.com/help/section/faq-web3-wallet). The `web3_wallet_id` parameter can also be specified to select which of the user's known Web3 wallets will be used. *** * `code` * `string` **Required** if `strategy` is set to `'phone_code'` or `'email_code'`. The code that was sent to the user. *** * `signature` * `string` **Required** if `strategy` is set to `'web3_base_signature'`, `'web3_metamask_signature'`, `'web3_coinbase_wallet_signature'`, or `'web3_okx_wallet_signature'`. The signature that was sent to the user via the Web3 verification strategy. ### `attemptWeb3WalletVerification()` Attempts to verify a Web3 wallet address by validating the cryptographic signature generated by the wallet against the nonce provided during the prepare verification step. This is a convenience method that wraps [`SignUp.attemptVerification()`](#attempt-verification) with Web3 wallet strategies. By default, this method is equivalent to calling `SignUp.attemptVerification({ strategy: 'web3_metamask_signature', signature })`. The verification attempt will fail if the signature is invalid or the nonce has expired. ```typescript function attemptWeb3WalletVerification(params: AttemptWeb3WalletVerificationParams): Promise ``` #### `AttemptWeb3WalletVerificationParams` * `signature` * `string` The signature that was generated after [`prepareVerification`](#prepare-verification) was called. ### `authenticateWithBase()` Initiates an authentication flow using Base, allowing users to authenticate via their Web3 wallet address. This method prompts the user to connect their Base account and sign a message to verify ownership of the wallet address. ```typescript function authenticateWithBase(params?: SignUpAuthenticateWithWeb3Params): Promise ``` ### `authenticateWithCoinbaseWallet()` Initiates an authentication flow using the Coinbase Wallet browser extension, allowing users to authenticate via their Web3 wallet address. This method prompts the user to connect their Coinbase Wallet and sign a message to verify ownership of the wallet address. ```typescript function authenticateWithCoinbaseWallet( params?: SignUpAuthenticateWithWeb3Params, ): Promise ``` #### Example ```js const signUp = await clerk.signUp.authenticateWithCoinbaseWallet() ``` ### `authenticateWithMetamask()` Initiates an authentication flow using the MetaMask browser extension, allowing users to authenticate via their Ethereum wallet address. This method prompts the user to connect their MetaMask wallet and sign a message to verify ownership of the wallet address. ```typescript function authenticateWithMetamask( params?: SignUpAuthenticateWithWeb3Params, ): Promise ``` #### Example ```js const signUp = await clerk.signUp.authenticateWithMetamask() ``` ### `authenticateWithOKXWallet()` Initiates an authentication flow using the OKX Wallet browser extension, allowing users to authenticate via their Web3 wallet address. This method prompts the user to connect their OKX Wallet and sign a message to verify ownership of the wallet address. ```typescript function authenticateWithOKXWallet( params?: SignUpAuthenticateWithWeb3Params, ): Promise ``` #### `SignUpAuthenticateWithWeb3Params` * `unsafeMetadata` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend and the backend. Once the sign-up is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the sign-up process and store it in this property. Read more about [unsafe metadata](/docs/guides/users/extending#unsafe-metadata). #### Example ```js const signUp = await clerk.signUp.authenticateWithOKXWallet() ``` ### `authenticateWithRedirect()` Signs up a user via a Single Sign On (SSO) connection, such as OAuth or SAML, where an external account is used for verifying the user's identity. ```typescript function authenticateWithRedirect(params: AuthenticateWithRedirectParams): Promise ``` #### `AuthenticateWithRedirectParams` * `redirectUrl` * `string` The full URL or path that the OAuth provider should redirect to after successful authorization on their part. Typically, this will be a simple `/sso-callback` route that either calls [`Clerk.handleRedirectCallback`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. *** * `redirectUrlComplete` * `string` The full URL or path to navigate to after the OAuth or SAML flow completes. *** * `continueSignUp` * `boolean | undefined` Whether to continue (i.e. PATCH) an existing `SignUp` (if present) or create a new `SignUp`. *** * `strategy` * `'oauth_' | 'saml' | 'enterprise_sso'` The strategy to use for authentication. The following strategies are supported: * `'oauth_'`: The user will be authenticated with their [social connection account](/docs/guides/configure/auth-strategies/social-connections/all-providers). See a list of [supported values for ``](/docs/reference/javascript/types/sso). * `'saml'` (deprecated): **Deprecated in favor of `'enterprise_sso'`.** The user will be authenticated with their [SAML account](/docs/guides/configure/auth-strategies/enterprise-connections/overview#saml). * `'enterprise_sso'`: The user will be authenticated either through SAML or OIDC depending on the configuration of their [enterprise SSO account](/docs/guides/configure/auth-strategies/enterprise-connections/overview). *** * `identifier` * `string | undefined` Identifier to use for targeting an enterprise connection at sign-up. *** * `emailAddress` * `string | undefined` Email address to use for targeting an enterprise connection at sign-up. *** * `legalAccepted?` * `boolean` A boolean indicating whether the user has agreed to the [legal compliance](/docs/guides/secure/legal-compliance) documents. *** * `unsafeMetadata` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend. Once the sign-up is complete, the value of this field will be automatically copied to the newly created user's unsafe metadata. One common use case for this attribute is to use it to implement custom fields that can be collected during sign-up and will automatically be attached to the created `User` object. #### Example For OAuth connections, see the [custom flow for OAuth connections](/docs/guides/development/custom-flows/authentication/oauth-connections). For enterprise connections, see the [custom flow for enterprise connections](/docs/guides/development/custom-flows/authentication/enterprise-connections). ### `authenticateWithPopup()` Opens a popup window to allow a user to sign up via a Single Sign On (SSO) connection, such as OAuth or SAML, where an external account is used for verifying the user's identity. ```typescript function authenticateWithPopup(params: AuthenticateWithPopupParams): Promise ``` #### `AuthenticateWithPopupParams` * `redirectUrl` * `string` The full URL or path that the OAuth provider should redirect to after successful authorization on their part. Typically, this will be a simple `/sso-callback` route that either calls [`Clerk.handleRedirectCallback`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. *** * `redirectUrlComplete` * `string` The full URL or path to navigate to after the OAuth or SAML flow completes. *** * `strategy` * `'oauth_' | 'saml' | 'enterprise_sso'` The strategy to use for authentication. The following strategies are supported: * `'oauth_'`: The user will be authenticated with their [social connection account](/docs/guides/configure/auth-strategies/social-connections/all-providers). See a list of [supported values for ``](/docs/reference/javascript/types/sso). * `'saml'` (deprecated): **Deprecated in favor of `'enterprise_sso'`.** The user will be authenticated with their [SAML account](/docs/guides/configure/auth-strategies/enterprise-connections/overview#saml). * `'enterprise_sso'`: The user will be authenticated either through SAML or OIDC depending on the configuration of their [enterprise SSO account](/docs/guides/configure/auth-strategies/enterprise-connections/overview). *** * `popup` * `Window` A reference to a popup window opened via `window.open()`. *** * `continueSignUp?` * `boolean | undefined` Whether to continue (i.e. PATCH) an existing `SignUp` (if present) or create a new `SignUp`. *** * `emailAddress?` * `string | undefined` Email address to use for targeting an enterprise connection at sign-up. *** * `identifier?` * `string | undefined` Identifier to use for targeting an enterprise connection at sign-up. *** * `legalAccepted?` * `boolean` A boolean indicating whether the user has agreed to the [legal compliance](/docs/guides/secure/legal-compliance) documents. *** * `unsafeMetadata?` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend. Once the sign-up is complete, the value of this field will be automatically copied to the newly created user's unsafe metadata. One common use case for this attribute is to use it to implement custom fields that can be collected during sign-up and will automatically be attached to the created `User` object. #### Example ```js await clerk.signUp.authenticateWithPopup({ popup: window.open('https://example.com', '_blank'), strategy: 'oauth_google', redirectUrl: '/sso-callback', redirectUrlComplete: '/home', }) ``` ### `authenticateWithWeb3()` Initiates a Web3 authentication flow by verifying the user's ownership of a blockchain wallet address through cryptographic signature verification. This method enables decentralized authentication without requiring traditional credentials. ```typescript function authenticateWithWeb3(params: AuthenticateWithWeb3Params): Promise ``` #### `AuthenticateWithWeb3Params` * `identifier` * `string` The user's Web3 ID *** * `generateSignature` * (opts: [GenerateSignatureParams](#generate-signature-params)) => Promise\ The method of how to generate the signature for the Web3 sign-in. See [`GenerateSignatureParams`](#generate-signature-params) for more information. *** * `strategy?` * `Web3Strategy` The Web3 verification strategy. *** * `legalAccepted?` * `boolean` A boolean indicating whether the user has agreed to the [legal compliance](/docs/guides/secure/legal-compliance) documents. *** * `unsafeMetadata` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend. Once the sign-up is complete, the value of this field will be automatically copied to the newly created user's unsafe metadata. One common use case for this attribute is to use it to implement custom fields that can be collected during sign-up and will automatically be attached to the created `User` object. #### `GenerateSignatureParams` * `identifier` * `string` The user's Web3 wallet address. *** * `nonce` * `string` The [cryptographic nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) used in the sign-in. *** * `provider?` * `Web3Provider` The Web3 provider to generate the signature with. *** * `legalAccepted?` * `boolean` A boolean indicating whether the user has agreed to the [legal compliance](/docs/guides/secure/legal-compliance) documents. #### Example ```js const signUp = await clerk.signUp.authenticateWithWeb3({ identifier: '0x1234567890123456789012345678901234567890', }) ``` ### `create()` Returns a new `SignUp` object based on the `params` you pass to it, stores the sign-up lifecycle state in the `status` property, and deactivates any existing sign-up process the client may already have in progress. Use this method to initiate a new sign-up process. What you must pass to `params` depends on which [sign-up options](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) you have enabled in your Clerk application instance. Optionally, you can complete the sign-up process in one step if you supply the required fields to `create()`. Otherwise, Clerk's sign-up process provides great flexibility and allows users to easily create multi-step sign-up flows. > \[!WARNING] > Once the sign-up process is complete, pass the `createdSessionId` to the [`setActive()`](/docs/reference/javascript/clerk#set-active) method on the `Clerk` object. This will set the newly created session as the active session. ```typescript function create(params: SignUpCreateParams): Promise ``` #### `SignUpCreateParams` * `strategy` * `'oauth_' | 'saml' | 'enterprise_sso' | 'ticket' | 'google_one_tap'` The strategy to use for the sign-up flow. The following strategies are supported: * `'oauth_'`: The user will be authenticated with their [social connection account](/docs/guides/configure/auth-strategies/social-connections/all-providers). See a list of [supported values for ``](/docs/reference/javascript/types/sso). * `'saml'` (deprecated): **Deprecated in favor of `'enterprise_sso'`.** The user will be authenticated with their [SAML account](/docs/guides/configure/auth-strategies/enterprise-connections/overview#saml). * `'enterprise_sso'`: The user will be authenticated either through SAML or OIDC depending on the configuration of their [enterprise SSO account](/docs/guides/configure/auth-strategies/enterprise-connections/overview). * `'ticket'`: The user will be authenticated via the ticket *or token* generated from the Backend API. * `'google_one_tap'`: The user will be authenticated with the Google One Tap UI. It's recommended to use authenticateWithGoogleOneTap() instead, as it will also set the user's current session as active for you. *** * `firstName` * `string | null` The user's first name. Only supported if [**First and last name**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) is enabled. *** * `lastName` * `string | null` The user's last name. Only supported if [**First and last name**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) is enabled. *** * `password` * `string | null` The user's password. Only supported if [**Password**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#password) is enabled. *** * `emailAddress` * `string | null` The user's email address. Only supported if [**Email address**](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) is enabled. Keep in mind that the email address requires an extra verification process. *** * `phoneNumber` * `string | null` The user's phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164). Only supported if [phone number](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#phone) is enabled. Keep in mind that the phone number requires an extra verification process. *** * `web3Wallet` * `string | null` **Required** if [Web3 authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#web3-authentication) is enabled. The Web3 wallet address, made up of 0x + 40 hexadecimal characters. *** * `username` * `string | null` The user's [username](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#username). Only supported if username is enabled in the instance settings. *** * `unsafeMetadata` * [`SignUpUnsafeMetadata`](/docs/reference/javascript/types/metadata#sign-up-unsafe-metadata) Metadata that can be read and set from the frontend. Once the sign-up is complete, the value of this field will be automatically copied to the newly created user's unsafe metadata. One common use case for this attribute is to use it to implement custom fields that can be collected during sign-up and will automatically be attached to the created `User` object. *** * `redirectUrl` * `string` If `strategy` is set to `'oauth_'` or `'enterprise_sso'`, this specifies full URL or path that the OAuth provider should redirect to after successful authorization on their part. Typically, this will be a simple `/sso-callback` route that either calls [`Clerk.handleRedirectCallback()`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. If `strategy` is set to `'email_link'`, this specifies The full URL that the user will be redirected to when they visit the email link. See the [custom flow](/docs/guides/development/custom-flows/authentication/email-links) for implementation details. *** * `actionCompleteRedirectUrl` * `string` **Optional** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The full URL or path that the user will be redirected to after successful authorization from the OAuth provider and Clerk sign-in. *** * `ticket` * `string` **Required** if `strategy` is set to `'ticket'`. The [ticket *or token*](/docs/guides/development/custom-flows/authentication/application-invitations) generated from the Backend API. *** * `transfer` * `boolean` When set to `true`, the `SignUp` will attempt to retrieve information from the active `SignIn` instance and use it to complete the sign-up process. This is useful when you want to seamlessly transition a user from a sign-in attempt to a sign-up attempt. *** * `legalAccepted` * `boolean` A boolean indicating whether the user has agreed to the [legal compliance](/docs/guides/secure/legal-compliance) documents. *** * `oidcPrompt` * `string` **Optional** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The value to pass to the [OIDC `prompt` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=prompt,reauthentication%20and%20consent.) in the generated OAuth redirect URL. *** * `oidcLoginHint` * `string` **Optional** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The value to pass to the [OIDC `login_hint` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=login_hint,in%20\(if%20necessary\).) in the generated OAuth redirect URL. ### `createEmailLinkFlow()` ```typescript function createEmailLinkFlow(): { startEmailLinkFlow: (params: StartEmailLinkFlowParams) => Promise cancelEmailLinkFlow: () => void } ``` Sets up a sign-up with email link flow. Calling `createEmailLinkFlow()` will return two functions. The first function is async and starts the email link flow, preparing an email link verification. It sends the email link email and starts polling for verification results. The signature is `startEmailLinkFlow({ redirectUrl: string }) => Promise`. The second function can be used to stop polling at any time, allowing for full control of the flow and cleanup. The signature is `cancelEmailLinkFlow() => void`. ```typescript function createEmailLinkFlow(): { startEmailLinkFlow: (params: StartEmailLinkFlowParams) => Promise cancelEmailLinkFlow: () => void } ``` #### `createEmailLinkFlow()` returns `createEmailLinkFlow` returns an object with two functions: * `startEmailLinkFlow` * (params: [StartEmailLinkFlowParams](#start-email-link-flow-params)) => Promise\ Function to start the email link flow. It prepares an email link verification and polls for the verification result. #### `StartEmailLinkFlowParams` * `redirectUrl` * `string` The full URL that the user will be redirected to when they visit the email link. ### `prepareEmailAddressVerification()` Initiates an email verification process by sending a one-time verification code to the email address associated with the current sign-up attempt. This is a convenience method that wraps [`SignUp.prepareVerification()`](#prepare-verification) with the `'email_code'` strategy. By default, this method is equivalent to calling `SignUp.prepareVerification({ strategy: 'email_code' })`. It can be customized via the `PrepareEmailAddressVerificationParams` to use alternative verification strategies like email links. ```typescript function prepareEmailAddressVerification( params?: PrepareEmailAddressVerificationParams, ): Promise ``` #### `PrepareEmailAddressVerificationParams` * `strategy` * `'email_code' | 'email_link'` The verification strategy to validate the user's sign-up request. The following strategies are supported: * `'email_code'`: Send an email with a unique token to input. * `'email_link'`: Send an email with a link which validates sign-up. *** * `redirectUrl` * `string` **Required** if `strategy` is set to `'email_link'`. The full URL that the user will be redirected to when they visit the email link. See the [custom flow](/docs/guides/development/custom-flows/authentication/email-links) for implementation details. ### `preparePhoneNumberVerification()` Initiates a phone number verification process by sending a one-time verification code (OTP) via SMS to the phone number associated with the current sign-up attempt. This is a convenience method that wraps [`SignUp.prepareVerification()`](#prepare-verification) with the `'phone_code'` strategy. By default, this method is equivalent to calling `SignUp.prepareVerification({ strategy: 'phone_code' })`. The verification process will fail if the phone number is invalid, unreachable, or has already been verified. The sent verification code has a limited validity period and can only be used once. ```typescript function preparePhoneNumberVerification( params?: PreparePhoneNumberVerificationParams, ): Promise ``` #### `PreparePhoneNumberVerificationParams` * `strategy` * `'phone_code'` The verification strategy to validate the user's sign-up request. The following strategies are supported: * `'phone_code'`: Send an SMS with a unique token to input. ### `prepareVerification()` Initiates the verification process for a field that requires validation during sign-up. This method prepares the necessary verification flow based on the specified strategy, such as sending verification codes, generating OAuth URLs, or preparing Web3 wallet signatures. ```typescript function prepareVerification(params: PrepareVerificationParams): Promise ``` #### `PrepareVerificationParams` * `strategy` * `'phone_code' | 'email_code' | 'email_link' | 'oauth_' | 'saml' | 'enterprise_sso' | 'web3_base_signature' | 'web3_metamask_signature' | 'web3_coinbase_wallet_signature' | 'web3_okx_wallet_signature'` The verification strategy to validate the user's sign-up request. The following strategies are supported: * `'phone_code'`: User will receive a one-time authentication code via SMS. * `'email_code'`: Send an email with a unique token to input. * `'email_link'`: Send an email with a link which validates sign-up. * `'oauth_'`: The user will be authenticated with their [social connection account](/docs/guides/configure/auth-strategies/social-connections/all-providers). See a list of [supported values for ``](/docs/reference/javascript/types/sso). * `'saml'` (deprecated): **Deprecated in favor of `'enterprise_sso'`.** The user will be authenticated with their [SAML account](/docs/guides/configure/auth-strategies/enterprise-connections/overview#saml). * `'enterprise_sso'`: The user will be authenticated either through SAML or OIDC depending on the configuration of their [enterprise SSO account](/docs/guides/configure/auth-strategies/enterprise-connections/overview). * `'web3_base_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Base](https://docs.base.org/base-account/guides/authenticate-users). The `web3_wallet_id` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'web3_metamask_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Metamask](https://metamask.io/). The `web3_wallet_id` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'web3_coinbase_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [Coinbase Wallet](https://www.coinbase.com/wallet). The `web3_wallet_id` parameter can also be specified to select which of the user's known Web3 wallets will be used. * `'web3_okx_wallet_signature'`: The verification will attempt to be completed using the user's Web3 wallet address via [OKX Wallet](https://www.okx.com/help/section/faq-web3-wallet). The `web3_wallet_id` parameter can also be specified to select which of the user's known Web3 wallets will be used. *** * `redirectUrl` * `string` If `strategy` is set to `'oauth_'` or `'enterprise_sso'`, this specifies the full URL or path that the OAuth provider should redirect to after successful authorization. Typically, this will be a simple `/sso-callback` route that either calls [`Clerk.handleRedirectCallback()`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. If `strategy` is set to `'email_link'`, this specifies The full URL that the user will be redirected to when they visit the email link. See the [custom flow](/docs/guides/development/custom-flows/authentication/email-links) for implementation details. *** * `actionCompleteRedirectUrl?` * `string` The full URL or path that the user will be redirected to after successful authorization from the OAuth provider and Clerk sign-in. *** * `oidcPrompt?` * `string` **Optional** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The value to pass to the [OIDC `prompt` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=prompt,reauthentication%20and%20consent) in the generated OAuth redirect URL. *** * `oidcLoginHint?` * `string` **Optional** if `strategy` is set to `'oauth_'` or `'enterprise_sso'`. The value to pass to the [OIDC `login_hint` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=login_hint,in%20\(if%20necessary\).) in the generated OAuth redirect URL. ### `prepareWeb3WalletVerification()` Initiates a verification process for a Web3 wallet by sending the wallet address to the server and retrieving a nonce that must be cryptographically signed by the wallet. This is a convenience method that wraps [`SignUp.prepareVerification()`](#prepare-verification) with Web3 wallet strategies. By default, this method is equivalent to calling `SignUp.prepareVerification({ strategy: 'web3_metamask_signature' })`. The verification process will fail if the wallet address is invalid or has already been verified. The returned nonce has a limited validity period and can only be used once. ```typescript function prepareWeb3WalletVerification( params?: PrepareWeb3WalletVerificationParams, ): Promise ``` #### `PrepareWeb3WalletVerificationParams` * `strategy` * `'web3_base_signature'` | `'web3_metamask_signature'` | `'web3_coinbase_wallet_signature'` | `'web3_okx_wallet_signature'` The verification strategy to validate the user's sign-up request. The following strategies are supported: * `'web3_base_signature'`: User will need to sign a message and generate a signature using Base popup. * `'web3_metamask_signature'`: User will need to sign a message and generate a signature using MetaMask browser extension. * `'web3_coinbase_wallet_signature'`: User will need to sign a message and generate a signature using Coinbase Wallet. * `'web3_okx_wallet_signature'`: User will need to sign a message and generate a signature using OKX Wallet. ### `update()` Updates the current `SignUp`. ```typescript function update(params: SignUpUpdateParams): Promise ``` #### `SignUpUpdateParams` `SignUpUpdateParams` is a mirror of [`SignUpCreateParams`](#sign-up-create-params) with the same fields and types, depending on the configuration of the instance. --- title: "`User` object" description: The User object holds all the information for a user of your application and provides a set of methods to manage their account. Users have a unique authentication identifier which might be their email address, phone number or a username. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/user lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/user.mdx --- The `User` object holds all of the information for a single user of your application and provides a set of methods to manage their account. Each `User` has at least one authentication identifier, which might be their email address, phone number, or a username. A user can be contacted at their primary email address or primary phone number. They can have more than one registered email address, but only one of them will be their primary email address (`User.primaryEmailAddress`). This goes for phone numbers as well; a user can have more than one, but only one phone number will be their primary (`User.primaryPhoneNumber`). At the same time, a user can also have one or more external accounts by connecting to [social providers](/docs/guides/configure/auth-strategies/social-connections/all-providers) such as Google, Apple, Facebook, and many more (`User.externalAccounts`). Finally, a `User` object holds profile data like the user's name, profile picture, and a set of [metadata](/docs/guides/users/extending) that can be used internally to store arbitrary information. The metadata are split into `publicMetadata` and `privateMetadata`. Both types are set from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but public metadata can also be accessed from the [Frontend API](/docs/reference/frontend-api){{ target: '_blank' }}. The ClerkJS SDK provides some helper [methods](#methods) on the `User` object to help retrieve and update user information and authentication status. ## Properties * `backupCodeEnabled` * `boolean` A boolean indicating whether the user has enabled backup codes for their account. *** * `createdAt` * `Date` The date when the user was first created. *** * `createOrganizationEnabled` * `boolean` A boolean indicating whether the Organization creation permission is enabled for the user. Defaults to `false`. *** * `createOrganizationsLimit` * `number` A number indicating the number of Organizations that can be created by the user. If the value is `0`, then the user can create unlimited Organizations. Defaults to `null`. *** * `deleteSelfEnabled` * `boolean` A boolean indicating whether the user is able to delete their own account. *** * `emailAddresses` * [EmailAddress](/docs/reference/javascript/types/email-address)\[] An array of all the `EmailAddress` objects associated with the user. Includes the primary. *** * `enterpriseAccounts` * [EnterpriseAccount](/docs/reference/javascript/types/enterprise-account)\[] An array of all the `EnterpriseAccount` objects associated with the user. *** * `externalAccounts` * [ExternalAccount](/docs/reference/javascript/types/external-account)\[] An array of all the `ExternalAccount` objects associated with the user via OAuth. This includes both verified & unverified external accounts. *** * `externalId` * `string | null` The user's ID as used in your external systems. Must be unique across your instance. *** * `firstName` * `string | null` The user's first name. *** * `fullName` * `string | null` The user's full name. *** * `hasImage` * `boolean` A boolean that indicates whether the user has uploaded an image or one was copied from OAuth. Returns `false` if Clerk is displaying an avatar for the user. *** * `hasVerifiedEmailAddress` * `boolean` A boolean that indicates whether the user has verified an email address. *** * `hasVerifiedPhoneNumber` * `boolean` A boolean that indicates whether the user has verified a phone number. *** * `id` * `string` The user's unique identifier. *** * `imageUrl` * `string` Holds the default avatar or user's uploaded profile image. Compatible with Clerk's [Image Optimization](/docs/guides/development/image-optimization). *** * `lastSignInAt` * `Date | null` The date when the user last signed in. `null` if the user has never signed in. *** * `lastName` * `string | null` The user's last name. *** * `legalAcceptedAt` * `Date` The date when the user accepted the legal documents. `null` if [**Require express consent to legal documents**](/docs/guides/secure/legal-compliance) is not enabled. *** * `organizationMemberships` * [OrganizationMembership](/docs/reference/javascript/types/organization-membership)\[] A list of `OrganizationMembership`s representing the list of Organizations the user is a member of. *** * `passkeys` * [PasskeyResource](/docs/reference/javascript/types/passkey-resource)\[] | null An array of passkeys associated with the user's account. *** * `passwordEnabled` * `boolean` A boolean indicating whether the user has a password on their account. *** * `phoneNumbers` * [PhoneNumber](/docs/reference/javascript/types/phone-number)\[] An array of all the `PhoneNumber` objects associated with the user. Includes the primary. *** * `primaryEmailAddress` * [EmailAddress](/docs/reference/javascript/types/email-address) | null Information about the user's primary email address. *** * `primaryEmailAddressId` * `string | null` The ID for the `EmailAddress` that the user has set as primary. *** * `primaryPhoneNumber` * [PhoneNumber](/docs/reference/javascript/types/phone-number) | null Information about the user's primary phone number. *** * `primaryPhoneNumberId` * `string | null` The ID for the `PhoneNumber` that the user has set as primary. *** * `primaryWeb3Wallet` * [Web3Wallet](/docs/reference/javascript/types/web3-wallet) | null The `Web3Wallet` that the user signed up with. *** * `primaryWeb3WalletId` * `string | null` The ID for the [`Web3Wallet`](/docs/reference/javascript/types/web3-wallet) that the user signed up with. *** * `privateMetadata` * [`UserPrivateMetadata`](/docs/reference/javascript/types/metadata#user-private-metadata) Metadata that can be read and set only from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}. *** * `publicMetadata` * [`UserPublicMetadata`](/docs/reference/javascript/types/metadata#user-public-metadata) Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. *** * `samlAccounts` (deprecated) * [SamlAccount](/docs/reference/javascript/types/saml-account)\[] **Deprecated in favor of `enterpriseAccounts`.** An array of all the `SamlAccount` objects associated with the user. *** * `totpEnabled` * `boolean` A boolean indicating whether the user has enabled TOTP by generating a TOTP secret and verifying it via an authenticator app. *** * `twoFactorEnabled` * `boolean` A boolean indicating whether the user has enabled two-factor authentication. *** * `unsafeMetadata` * [`UserUnsafeMetadata`](/docs/reference/javascript/types/metadata#user-unsafe-metadata) Metadata that can be read and set from the Frontend API. It's considered unsafe because it can be modified from the frontend. There is also an `unsafeMetadata` attribute in the [`SignUp`](/docs/reference/javascript/sign-up) object. The value of that field will be automatically copied to the user's unsafe metadata once the sign up is complete. *** * `updatedAt` * `Date` The date when the user was last updated. *** * `verifiedExternalAccounts` * [ExternalAccount](/docs/reference/javascript/types/external-account)\[] An array of all the `ExternalAccount` objects associated with the user via OAuth that are verified. *** * `verifiedWeb3Wallets` * [Web3Wallet](/docs/reference/javascript/types/web3-wallet)\[] An array of all the `Web3Wallet` objects associated with the user that are verified. *** * `unverifiedExternalAccounts` * [ExternalAccount](/docs/reference/javascript/types/external-account)\[] An array of all the `ExternalAccount` objects associated with the user via OAuth that are not verified. *** * `username` * `string | null` The user's [username](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#username). Only supported if username is enabled in the instance settings. *** * `web3Wallets` * [Web3Wallet](/docs/reference/javascript/types/web3-wallet)\[] An array of all the `Web3Wallet` objects associated with the user. Includes the primary. ## Methods ### `createBackupCode()` Generates a fresh new set of backup codes for the user. Every time the method is called, it will replace the previously generated backup codes. Returns a [`BackupCodeResource`](/docs/reference/javascript/types/backup-code) object. > \[!WARNING] > Can only be created for the user if the user has *another* multi-factor authentication method enabled for their account, in the Clerk Dashboard, as backup codes are a fallback for when the user is unable to use their primary MFA method. ```typescript function createBackupCode(): Promise ``` #### Example ```js await clerk.user.createBackupCode() ``` ### `createEmailAddress()` Adds an email address for the user. A new [`EmailAddress`](/docs/reference/javascript/types/email-address) will be created and associated with the user. > \[!WARNING] > [**Email** must be enabled](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#email) in your app's settings in the Clerk Dashboard. ```ts function createEmailAddress(params: CreateEmailAddressParams): Promise ``` #### `CreateEmailAddressParams` * `email` * `string` The email address to be added to the user. #### Example ```js await clerk.user.createEmailAddress({ email: 'test@test.com' }) ``` ### `createExternalAccount()` Adds an external account for the user. A new [`ExternalAccount`](/docs/reference/javascript/types/external-account) will be created and associated with the user. This method is useful if you want to allow an already signed-in user to connect their account with an external provider, such as Facebook, GitHub, etc., so that they can sign in with that provider in the future. > \[!WARNING] > The social provider that you want to connect to [must be enabled](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#sso-connections) in your app's settings in the Clerk Dashboard. ```ts function createExternalAccount(params: CreateExternalAccountParams): Promise ``` #### `CreateExternalAccountParams` * `strategy` * [`OAuthStrategy`](/docs/reference/javascript/types/sso#o-auth-strategy) The strategy corresponding to the OAuth provider. For example: `'oauth_facebook'`, `'oauth_github'`, etc. *** * `redirectUrl?` * `string` The full URL or path that the OAuth provider should redirect to, on successful authorization on their part. Typically, this will be a simple `/sso-callback` route that calls [`Clerk.handleRedirectCallback`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. *** * `additionalScopes?` * `string[]` Additional scopes for your user to be prompted to approve. *** * `oidcPrompt?` * `string` The value to pass to the [OIDC `prompt` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=prompt,reauthentication%20and%20consent.) in the generated OAuth redirect URL. *** * `oidcLoginHint?` * `string` The value to pass to the [OIDC `login_hint` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=login_hint,in%20\(if%20necessary\).) in the generated OAuth redirect URL. #### Example After calling `createExternalAccount`, the initial `state` of the returned `ExternalAccount` will be `unverified`. To initiate the connection with the external provider, redirect the user to the `externalAccount.verification.externalVerificationRedirectURL` contained in the result of `createExternalAccount`. Upon return, inspect within the `user.externalAccounts` the entry that corresponds to the requested strategy: * If the connection succeeded, then `externalAccount.verification.status` will be `verified`. * If the connection failed, then the `externalAccount.verification.status` will not be `verified` and the `externalAccount.verification.error` will contain the error encountered, which you can present to the user. To learn more about the properties available on `verification`, see the [`verification`](/docs/reference/javascript/types/verification) reference. The following example demonstrates how to add a Notion account as an external account for the user. When the user selects the "Add Notion as a social connection" button, the user will be redirected to Notion to connect their account. After connecting their account, they will be redirected to the `/` route of your application, and the status of the connection will be displayed. ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

Notion verification status:

``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Find the external account for the provider const externalAccount = clerk.user.externalAccounts.find((p) => p.provider === 'notion') // If the external account exists, display its status document.getElementById('notion-status').innerHTML = externalAccount.verification.status // When the button is clicked, initiate the connection with the provider document.getElementById('add-notion').addEventListener('click', async () => { clerk.user .createExternalAccount({ strategy: 'oauth_notion', redirect_url: '/' }) .then((externalAccount) => { window.location.href = externalAccount.verification.externalVerificationRedirectURL }) .catch((error) => { console.log('An error occurred:', error.errors) }) }) } else { document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ```
### `createPasskey()` Creates a passkey for the signed-in user. Returns a [`PasskeyResource`](/docs/reference/javascript/types/passkey-resource) object. > \[!NOTE] > When creating a passkey for a user in a multi-domain Clerk app, `createPasskey()` must be called from the primary domain. ```ts function createPasskey(): Promise ``` #### Example For an example on how to use `createPasskey()`, see the [custom flow guide on passkeys](/docs/guides/development/custom-flows/authentication/passkeys#create-user-passkeys). ### `createPhoneNumber()` Adds a phone number for the user. A new [`PhoneNumber`](/docs/reference/javascript/types/phone-number) will be created and associated with the user. > \[!WARNING] > [**Phone** must be enabled](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#phone) in your app's settings in the Clerk Dashboard. ```ts function createPhoneNumber(params: CreatePhoneNumberParams): Promise ``` #### `CreatePhoneNumberParams` * `phoneNumber` * `string` The phone number to be added to the user. Must be in E.164 format. ### Example ```js await clerk.user.createPhoneNumber({ phoneNumber: '1234567890' }) ``` ### `createTOTP()` Generates a TOTP secret for a user that can be used to register the application on the user's authenticator app of choice. If this method is called again (while still unverified), it replaces the previously generated secret. Returns a [`TOTPResource`](/docs/reference/javascript/types/totp) object. > \[!WARNING] > The **Authenticator application** multi-factor strategy must be enabled in your app's settings in the Clerk Dashboard. See the [Multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) section to learn more. ```typescript function createTOTP(): Promise ``` #### Example ```js await clerk.user.createTOTP() ``` ### `delete()` Deletes the current user. ```ts {{ prettier: false }} function delete(): Promise ``` #### Example ```js await clerk.user.delete() ``` ### `disableTOTP()` Disables TOTP by deleting the user's TOTP secret. Returns a [`DeletedObjectResource`](/docs/reference/javascript/types/deleted-object-resource) object. > \[!WARNING] > The **Authenticator application** multi-factor strategy must be enabled in your app's settings in the Clerk Dashboard. See the [Multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) section to learn more. ```typescript function disableTOTP(): Promise ``` #### Example ```js await clerk.user.disableTOTP() ``` ### `getOrganizationInvitations()` Retrieves a list of Organization invitations for the user. Returns a [`ClerkPaginatedResponse`](/docs/reference/javascript/types/clerk-paginated-response) of [`UserOrganizationInvitation`](/docs/reference/javascript/types/user-organization-invitation) objects. ```ts function getOrganizationInvitations( params?: GetUserOrganizationInvitationsParams, ): Promise> ``` #### `GetUserOrganizationInvitationsParams` * `initialPage?` * `number` A number that can be used to skip the first n-1 pages. For example, if `initialPage` is set to 10, it is will skip the first 9 pages and will fetch the 10th page. *** * `pageSize?` * `number` A number that indicates the maximum number of results that should be returned for a specific page. *** * `status?` * `'pending' | 'accepted' | 'revoked'` The status an invitation can have. #### Example ```js await clerk.user.getOrganizationInvitations() ``` ### `getOrganizationMemberships()` Retrieves a list of Organization memberships for the user. Returns a [`ClerkPaginatedResponse`](/docs/reference/javascript/types/clerk-paginated-response) of [`OrganizationMembershipResource`](/docs/reference/javascript/types/organization-membership) objects. ```ts function getOrganizationMemberships( params?: GetUserOrganizationMembershipParams, ): Promise> ``` #### `GetUserOrganizationMembershipParams` * `initialPage?` * `number` A number that can be used to skip the first n-1 pages. For example, if `initialPage` is set to 10, it is will skip the first 9 pages and will fetch the 10th page. *** * `pageSize?` * `number` A number that indicates the maximum number of results that should be returned for a specific page. #### Example ```js await clerk.user.getOrganizationMemberships() ``` ### `getOrganizationSuggestions()` Retrieves a list of Organization suggestions for the user. Returns a [`ClerkPaginatedResponse`](/docs/reference/javascript/types/clerk-paginated-response) of [`OrganizationSuggestion`](/docs/reference/javascript/types/organization-suggestion) objects. ```ts function getOrganizationSuggestions( params?: GetUserOrganizationSuggestionsParams, ): Promise> ``` #### `GetUserOrganizationSuggestionsParams` * `initialPage?` * `number` A number that can be used to skip the first n-1 pages. For example, if `initialPage` is set to 10, it is will skip the first 9 pages and will fetch the 10th page. *** * `pageSize?` * `number` A number that indicates the maximum number of results that should be returned for a specific page. *** * `status?` * `'pending' | 'accepted' | ['pending' | 'accepted']` The status an invitation can have. #### Example ```js await clerk.user.getOrganizationSuggestions() ``` ### `getSessions()` Retrieves all **active** sessions for this user. This method uses a cache so a network request will only be triggered only once. Returns an array of [`SessionWithActivities`](/docs/reference/javascript/types/session-with-activities) objects. ```ts function getSessions(): Promise ``` #### Example ```js await clerk.user.getSessions() ``` ### `isPrimaryIdentification()` A check whether or not the given resource is the primary identifier for the user. ```ts function isPrimaryIdentification( ident: EmailAddressResource | PhoneNumberResource | Web3WalletResource, ): boolean ``` #### Parameters * `ident` * [EmailAddress](/docs/reference/javascript/types/email-address) | [PhoneNumber](/docs/reference/javascript/types/phone-number) | [Web3Wallet](/docs/reference/javascript/types/web3-wallet) The resource checked against the user to see if it is the primary identifier. #### Example ```js await clerk.user.isPrimaryIdentification(clerk.user.emailAddresses[0]) ``` ### `reload()` Reloads the user's data from Clerk's API. Useful for when you want to refresh the user's data after performing some form of mutation. You only need to call `user.reload()` if you've updated the `User` object outside of the `user.update()` method or Clerk hooks; for example, if you made changes through an API endpoint. ```ts function reload(p?: ClerkResourceReloadParams): Promise ``` #### `ClerkResourceReloadParams` * `rotatingTokenNonce?` * `string` A nonce to use for rotating the user's token. Used in native application OAuth flows to allow the native client to update its JWT once despite changes in its rotating token. #### Example ```js await clerk.user.reload() ``` ### `removePassword()` Removes the user's password. ```ts function removePassword(params: RemoveUserPasswordParams): Promise ``` #### `RemoveUserPasswordParams` * `currentPassword` * `string` The user's current password. #### Example ```js await clerk.user.removePassword({ currentPassword: 'current-password' }) ``` ### `setProfileImage()` Adds the user's profile image or replaces it if one already exists. This method will upload an image and associate it with the user. ```ts function setProfileImage(params: SetProfileImageParams): Promise ``` #### `SetProfileImageParams` * `file` * `Blob | File | string | null` The file to set as the user's profile image, or `null` to remove the current image. ##### `ImageResource` * `id?` * `string` The unique identifier of the image. *** * `name` * `string | null` The name of the image. *** * `publicUrl` * `string | null` The publicly accessible url for the image. #### Example ```js await clerk.user.setProfileImage({ file: profileImage }) ``` ### `update()` Updates the user's attributes. Use this method to save information you collected about the user. The appropriate settings must be enabled in the Clerk Dashboard for the user to be able to update their attributes. For example, if you want to use the `update({ firstName })` method, you must enable the **First and last name** setting. It can be found on the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page in the Clerk Dashboard. ```ts function update(params: UpdateUserParams): Promise ``` #### `UpdateUserParams` All props below are optional. * `username` * `string` The user's [username](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#username). Only supported if username is enabled in the instance settings. *** * `firstName` * `string` The user's first name. *** * `lastName` * `string` The user's last name. *** * `primaryEmailAddressId` * `string` The ID for the [`EmailAddress`](/docs/reference/javascript/types/email-address) that the user has set as primary. *** * `primaryPhoneNumberId` * `string` The ID for the [`PhoneNumber`](/docs/reference/javascript/types/phone-number) that the user has set as primary. *** * `primaryWeb3WalletId` * `string` The ID for the [`Web3Wallet`](/docs/reference/javascript/types/web3-wallet) that the user signed up with. *** * `unsafeMetadata` * [`UserUnsafeMetadata`](/docs/reference/javascript/types/metadata#user-unsafe-metadata) Metadata that can be read and set from the Frontend API. One common use case for this attribute is to implement custom fields that will be attached to the `User` object. Updating this value overrides the previous value; it does not merge. To perform a merge, you can pass something like `{ …user.unsafeMetadata, …newData }` to this parameter. #### Example ```js await clerk.user.update({ firstName: 'Test' }) ``` ### `updatePassword()` Updates the user's password. Passwords must be at least 8 characters long. ```ts function updatePassword(params: UpdateUserPasswordParams): Promise ``` #### `UpdateUserPasswordParams` * `newPassword` * `string` The user's new password. *** * `currentPassword?` * `string` The user's current password. *** * `signOutOfOtherSessions?` * `boolean | undefined` If set to `true`, all sessions will be signed out. #### Example ```js await clerk.user.updatePassword({ currentPassword: 'current-password', newPassword: 'new-password', }) ``` ### `verifyTOTP()` Verifies a TOTP secret after a user has created it. The user must provide a code from their authenticator app that has been generated using the previously created secret. This way, correct set up and ownership of the authenticator app can be validated. Returns a [`TOTPResource`](/docs/reference/javascript/types/totp) object. > \[!WARNING] > The **Authenticator application** multi-factor strategy must be enabled in your app's settings in the Clerk Dashboard. See the [Multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) section to learn more. ```typescript function verifyTOTP(params: VerifyTOTPParams): Promise ``` #### `VerifyTOTPParams` * `code` * `string` A 6 digit TOTP generated from the user's authenticator app. #### Example ```js await clerk.user.verifyTOTP({ code: '123456' }) ``` [backupcode-ref]: /docs/reference/javascript/types/backup-code [email-ref]: /docs/reference/javascript/types/email-address [exacc-ref]: /docs/reference/javascript/types/external-account [phone-ref]: /docs/reference/javascript/types/phone-number [totp-ref]: /docs/reference/javascript/types/totp [web3-ref]: /docs/reference/javascript/types/web3-wallet --- title: "`BackupCodeResource`" description: An interface that represents a backup code. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/backup-code lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/backup-code.mdx --- An interface that represents a backup code. * `id` * `string` The unique identifier for the set of backup codes. *** * `codes` * `string[]` The generated set of backup codes. *** * `createdAt` * `Date` The date when the backup codes were created. *** * `updatedAt` * `Date` The date when the backup codes were last updated. --- title: "`BillingCheckoutResource`" description: The BillingCheckoutResource type represents information about a checkout session. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-checkout-resource lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-checkout-resource.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingCheckoutResource` type represents information about a checkout session. ## Properties | Property | Type | Description | | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | |
`confirm` | (params: [ConfirmCheckoutParams](/docs/reference/javascript/types/billing-checkout-resource#parameters)) => Promise\ | A function to confirm and finalize the checkout process, usually after payment information has been provided and validated. [Learn more.](#confirm) | | `externalClientSecret` | `string` | A client secret from an external payment provider (such as Stripe) used to complete the payment on the client-side. | | `externalGatewayId` | `string` | The identifier for the external payment gateway used for this checkout session. | | `freeTrialEndsAt?` | `Date` | Unix timestamp (milliseconds) of when the free trial ends. | | `id` | `string` | The unique identifier for the checkout session. | | `isImmediatePlanChange` | `boolean` | Whether the plan change will take effect immediately after checkout. | | `needsPaymentMethod` | `boolean` | Whether a payment method is required for this checkout. | | `pathRoot` | `string` | The root path of the resource. | | `payer` | [`BillingPayerResource`](/docs/reference/javascript/types/billing-payer-resource) | The payer associated with the checkout. | | `paymentMethod?` | [`BillingPaymentMethodResource`](/docs/reference/javascript/types/billing-payment-method-resource) | The payment method being used for the checkout, such as a credit card or bank account. | | `plan` | [`BillingPlanResource`](/docs/reference/javascript/types/billing-plan-resource) | The subscription plan details for the checkout. | | `planPeriod` | "month" \| "annual" | The billing period for the plan. | | `planPeriodStart?` | `number` | The start date of the plan period, represented as a Unix timestamp. | | `status` | "needs\_confirmation" \| "completed" | The current status of the checkout session. | | `totals` | [`BillingCheckoutTotals`](/docs/reference/javascript/types/billing-checkout-totals) | The total costs, taxes, and other pricing details for the checkout. | ### `confirm()` The `confirm()` function is used to confirm and finalize the checkout process, usually after payment information has been provided and validated. #### Parameters The `confirm()` method accepts the following parameters. **Only one of `paymentMethodId`, `paymentToken`, or `useTestCard` should be provided.** There are multiple variants of this type available which you can select by clicking on one of the tabs. | Name | Type | Description | | ------ | ------ | ------ | | `paymentMethodId?` | `string` | The ID of a saved payment method to use for this checkout. | | Name | Type | Description | | ------ | ------ | ------ | | `gateway?` | `"stripe"` | The payment gateway to use. **Required** if `paymentToken` or `useTestCard` is provided. | | `paymentToken?` | `string` | A token representing payment details, usually from a payment form. **Requires** `gateway` to be provided. | | Name | Type | Description | | ------ | ------ | ------ | | `gateway?` | `"stripe"` | The payment gateway to use. **Required** if `paymentToken` or `useTestCard` is provided. | | `useTestCard?` | `boolean` | If true, uses a test card for the checkout. **Requires** `gateway` to be provided. | --- title: "`BillingMoneyAmount`" description: The BillingMoneyAmount type represents a monetary value with currency information. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-money-amount lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-money-amount.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingMoneyAmount` type represents a monetary value with currency information. ## Properties | Property | Type | Description | | ---------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ | | `amount` | `number` | The raw amount as a number, usually in the smallest unit of the currency (like cents for USD). For example, `1000` for $10.00. | | `amountFormatted` | `string` | The amount as a formatted string. For example, `10.00` for $10.00. | | `currency` | `string` | The ISO currency code for this amount. For example, `USD`. | | `currencySymbol` | `string` | The symbol for the currency. For example, `$`. | --- title: "`BillingPaymentResource`" description: The BillingPaymentResource type represents a payment attempt for a user or Organization. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-payment-resource lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-payment-resource.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingPaymentResource` type represents a payment attempt for a user or organization. ## Properties | Property | Type | Description | | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | `amount` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The amount of the payment. | | `chargeType` | "checkout" \| "recurring" | The type of charge this payment represents. Can be `'checkout'` for one-time payments or `'recurring'` for subscription payments. | | `failedAt` | null \| Date | The date and time when the payment failed. | | `id` | `string` | The unique identifier for the payment. | | `paidAt` | null \| Date | The date and time when the payment was successfully completed. | | `pathRoot` | `string` | The root path of the resource. | | `paymentMethod` | null \| [BillingPaymentMethodResource](/docs/reference/javascript/types/billing-payment-method-resource) | The payment method being used for the payment, such as credit card or bank account. | | `status` | "pending" \| "paid" \| "failed" | The current status of the payment. | | `subscriptionItem` | [`BillingSubscriptionItemResource`](/docs/reference/javascript/types/billing-subscription-item-resource) | The subscription item being paid for. | | `updatedAt` | `Date` | The date and time when the payment was last updated. | --- title: "`BillingStatementGroup`" description: The BillingStatementGroup type represents a group of payment items within a statement. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-statement-group lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-statement-group.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingStatementGroup` type represents a group of payment items within a statement. ## Properties | Property | Type | Description | | ---------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | `items` | [BillingPaymentResource](/docs/reference/javascript/types/billing-payment-resource)\[] | An array of payment resources that belong to this group. | | `timestamp` | `Date` | The date and time when this group of payment items was created or last updated. | --- title: "`BillingPlanResource`" description: The BillingPlanResource type represents a Subscription Plan with its details. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-plan-resource lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-plan-resource.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingPlanResource` type represents a subscription plan with its details. ## Properties | Property | Type | Description | | ------------------------------------------------ | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `annualFee` | null \| [BillingMoneyAmount](/docs/reference/javascript/types/billing-money-amount) | The annual price of the plan or `null` if the plan is not annual. | | `annualMonthlyFee` | null \| [BillingMoneyAmount](/docs/reference/javascript/types/billing-money-amount) | The effective monthly price when billed annually or `null` if the plan is not annual. | | `avatarUrl` | null \| string | The URL of the plan's avatar image, or `null` if not set. | | `description` | null \| string | A short description of what the plan offers, or `null` if no description is provided. | | `features` | [FeatureResource](/docs/reference/javascript/types/feature-resource)\[] | The features the plan offers. | | `fee` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The monthly price of the plan. | | `forPayerType` | "org" \| "user" | Specifies the subscriber type this plan is designed for. Each plan is exclusively created for either individual users or organizations, and cannot be used interchangeably. | | `freeTrialDays` | null \| number | The number of days of the free trial for the plan. `null` if the plan does not have a free trial. | | `freeTrialEnabled` | `boolean` | Whether the plan has a free trial. | | `hasBaseFee` | `boolean` | Whether the plan has a base fee. | | `id` | `string` | The unique identifier for the plan. | | `isDefault` | `boolean` | Whether the plan is the default plan. | | `isRecurring` | `boolean` | Whether the plan is recurring. | | `name` | `string` | The name of the plan. | | `pathRoot` | `string` | The root path of the resource. | | `publiclyVisible` | `boolean` | Whether the plan is visible to the public. | | `slug` | `string` | The URL-friendly identifier of the plan. | --- title: "`BillingPaymentMethodResource`" description: The BillingPaymentMethodResource type represents a payment source for a checkout session. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-payment-method-resource lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-payment-method-resource.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingPaymentMethodResource` type represents a payment method for a checkout session. ## Properties | Property | Type | Description | | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `cardType` | null \| string | The brand or type of card. For example, `'visa'` or `'mastercard'`. | | `createdAt?` | null \| Date | The date the payment method was created, if available. | | `expiryMonth?` | null \| number | The card expiration month, if available. | | `expiryYear?` | null \| number | The card expiration year, if available. | | `id` | `string` | The unique identifier for the payment method. | | `isDefault?` | `boolean` | Whether the payment method is set as the default for the account. | | `isRemovable?` | `boolean` | Whether the payment method can be removed by the user. | | `last4` | null \| string | The last four digits of the payment method. | | `makeDefault` | (params?: \{ orgId?: string; \}) => Promise\ | A function that sets this payment method as the default for the account. Accepts the following parameters:
  • `orgId?` (`string`): The ID of the organization to set as the default.
| |
`pathRoot` | `string` | The root path of the resource. | | `paymentType?` | `"card"` | The type of payment method. For example, `'card'`. | | `remove` | (params?: \{ orgId?: string; \}) => Promise\<[DeletedObjectResource](/docs/reference/javascript/types/deleted-object-resource)\> | A function that removes this payment method from the account. Accepts the following parameters:
  • `orgId?` (`string`): The ID of the organization to remove the payment method from.
| |
`status` | "active" \| "expired" \| "disconnected" | The current status of the payment method. | | `updatedAt?` | null \| Date | The date the payment method was last updated, if available. | | `walletType?` | null \| string | The type of digital wallet, if applicable. For example, `'apple_pay'`, or `'google_pay'`. | --- title: "`BillingPayerResource`" description: The BillingPayerResource class represents a payer associated with a billing subscription. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-payer-resource lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-payer-resource.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingPayerResource` type represents a payer associated with a billing subscription. ## Properties | Property | Type | Description | | ------------------------------------------------- | --------------------------- | --------------------------------------------------------------------- | | `createdAt?` | `Date` | The date and time when the payer was created. | | `email?` | null \| string | The email address of the payer. | | `firstName?` | null \| string | The first name of the payer. | | `id` | `string` | The unique identifier for the payer. | | `imageUrl?` | `string` | The URL of the payer's avatar image. | | `lastName?` | null \| string | The last name of the payer. | | `organizationId` | null \| string | The unique identifier for the organization that the payer belongs to. | | `organizationName?` | null \| string | The name of the organization that the payer belongs to. | | `pathRoot` | `string` | The root path of the resource. | | `updatedAt?` | `Date` | The date and time when the payer was last updated. | | `userId` | null \| string | The unique identifier for the payer. | --- title: "`BillingCheckoutTotals`" description: The BillingCheckoutTotals type represents the total costs, taxes, and other pricing details for a checkout session. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-checkout-totals lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-checkout-totals.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingCheckoutTotals` type represents the total costs, taxes, and other pricing details for a checkout session. ## Properties | Property | Type | Description | | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | | `credit` | null \| [BillingMoneyAmount](/docs/reference/javascript/types/billing-money-amount) | Any credits (like account balance or promo credits) that are being applied to the checkout. | | `grandTotal` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The total amount for the checkout, including taxes and after credits/discounts are applied. This is the final amount due. | | `pastDue` | null \| [BillingMoneyAmount](/docs/reference/javascript/types/billing-money-amount) | Any outstanding amount from previous unpaid invoices that is being collected as part of the checkout. | | `subtotal` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The price of the items or plan before taxes, credits, or discounts are applied. | | `taxTotal` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The amount of tax included in the checkout. | | `totalDueAfterFreeTrial` | null \| [BillingMoneyAmount](/docs/reference/javascript/types/billing-money-amount) | The amount that becomes due after a free trial ends. | | `totalDueNow` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The amount that needs to be immediately paid to complete the checkout. | --- title: "`BillingStatementResource`" description: The BillingStatementResource type represents a billing statement for a user or Organization. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-statement-resource lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-statement-resource.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingStatementResource` type represents a billing statement for a user or organization. ## Properties | Property | Type | Description | | ---------------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | `groups` | [BillingStatementGroup](/docs/reference/javascript/types/billing-statement-group)\[] | An array of statement groups, where each group contains payment items organized by timestamp. | | `id` | `string` | The unique identifier for the statement. | | `pathRoot` | `string` | The root path of the resource. | | `status` | "open" \| "closed" | The current status of the statement. Statements can be either `'open'` (still accumulating charges) or `'closed'` (finalized). | | `timestamp` | `Date` | The date and time when the statement was created or last updated. | | `totals` | [`BillingStatementTotals`](/docs/reference/javascript/types/billing-statement-totals) | An object containing the financial totals for the statement, including subtotal, grand total, tax total, credit, and past due amounts. | --- title: "`BillingStatementTotals`" description: The BillingStatementTotals type represents the total costs, taxes, and other pricing details for a statement. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-statement-totals lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-statement-totals.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingStatementTotals` type represents the total costs, taxes, and other pricing details for a statement. ## Properties | Property | Type | Description | | ------------------------------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | `grandTotal` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The total amount for the checkout, including taxes and after credits/discounts are applied. This is the final amount due. | | `subtotal` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The price of the items or plan before taxes, credits, or discounts are applied. | | `taxTotal` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The amount of tax included in the checkout. | --- title: "`BillingSubscriptionItemResource`" description: The BillingSubscriptionItemResource type represents an item in a subscription. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-subscription-item-resource lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-subscription-item-resource.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingSubscriptionItemResource` type represents an item in a subscription. ## Properties | Property | Type | Description | | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `amount?` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The amount charged for the subscription item. | | `cancel` | (params: \{ orgId?: string; \}) => Promise\<[DeletedObjectResource](/docs/reference/javascript/types/deleted-object-resource)\> | A function to cancel the subscription item. Accepts the following parameters:
  • `orgId?` (`string`): The ID of the organization to cancel the subscription item from.
| |
`canceledAt` | null \| Date | The date and time when the subscription item was canceled. `null` if the subscription item is not canceled. | | `createdAt` | `Date` | The date and time when the subscription item was created. | | `credit?` | \{ amount: [BillingMoneyAmount](/docs/reference/javascript/types/billing-money-amount); \} | The credit from a previous purchase that is being applied to the subscription item. | | `credit.amount` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The amount of credit from a previous purchase that is being applied to the subscription item. | | `id` | `string` | The unique identifier for the subscription item. | | `isFreeTrial` | `boolean` | Whether the subscription item is for a free trial. | | `pastDueAt` | null \| Date | The date and time when the subscription item became past due. `null` if the subscription item is not past due. | | `pathRoot` | `string` | The root path of the resource. | | `periodEnd` | null \| Date | The date and time when the current billing period ends. `null` if not set. | | `periodStart` | `Date` | The date and time when the current billing period starts. | | `plan` | [`BillingPlanResource`](/docs/reference/javascript/types/billing-plan-resource) | The plan associated with the subscription item. | | `planPeriod` | "month" \| "annual" | The billing period for the subscription item. | | `status` | "active" \| "ended" \| "upcoming" \| "past\_due" | The status of the subscription item. | --- title: "`BillingSubscriptionResource`" description: The BillingSubscriptionResource type represents a Subscription to a Plan. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/billing-subscription-resource lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/billing-subscription-resource.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `BillingSubscriptionResource` type represents a subscription to a plan. ## Properties | Property | Type | Description | | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `activeAt` | `Date` | The date when the subscription became active. | | `createdAt` | `Date` | The date when the subscription was created. | | `eligibleForFreeTrial` | `boolean` | Whether the payer is eligible for a free trial. | | `id` | `string` | The unique identifier for the subscription. | | `nextPayment?` | \{ amount: [BillingMoneyAmount](/docs/reference/javascript/types/billing-money-amount); date: Date; \} | Information about the next payment, including the amount and the date it's due. Returns null if there is no upcoming payment. | | `nextPayment.amount` | [`BillingMoneyAmount`](/docs/reference/javascript/types/billing-money-amount) | The amount of the next payment. | | `nextPayment.date` | `Date` | The date when the next payment is due. | | `pastDueAt` | null \| Date | The date when the subscription became past due, or `null` if the subscription is not past due. | | `pathRoot` | `string` | The root path of the resource. | | `status` | "active" \| "past\_due" | The current status of the subscription. Due to the free plan subscription item, the top level subscription can either be `active` or `past_due`. | | `subscriptionItems` | [BillingSubscriptionItemResource](/docs/reference/javascript/types/billing-subscription-item-resource)\[] | The list of subscription items included in this subscription. | | `updatedAt` | null \| Date | The date when the subscription was last updated, or `null` if it hasn't been updated. | --- title: "`ClerkAPIError`" description: An interface that represents an error returned by the Clerk API. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/clerk-api-error lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/clerk-api-error.mdx --- An interface that represents an error returned by the Clerk API. * `code` * `string` A string code that represents the error, such as `username_exists_code`. *** * `message` * `string` A message that describes the error. *** * `longMessage?` * `string` A more detailed message that describes the error. *** * `meta?` * `object` Additional information about the error. *** * `meta.paramName?` * `string` The name of the parameter that caused the error. *** * `meta.sessionId?` * `string` The ID of the session that caused the error. *** * `meta.emailAddresses?` * `string[]` The email addresses that caused the error. *** * `meta.identifiers?` * `string[]` The identifiers that caused the error. *** * `meta.zxcvbn?` * `object` The [zxcvbn](https://github.com/dropbox/zxcvbn) score of the password that caused the error. *** * `meta.zxcvbn.suggestions?` * `{ code: string; message: string; }[]` Suggestions to improve the password. *** * `meta.permissions?` * `string[]` The permissions that caused the error. *** * `meta.plan?` * `object` The plan that caused the error. *** * `meta.plan.id?` * `string` The ID of the plan that caused the error. *** * `meta.plan.name?` * `string` The name of the plan. *** * `meta.plan.amount_formatted?` * `string` The formatted amount of the plan. *** * `meta.plan.annual_monthly_amount_formatted?` * `string` The formatted annual or monthly amount of the plan. *** * `meta.plan.currency_symbol?` * `string` The currency symbol of the plan. *** * `meta.isPlanUpgradePossible?` * `boolean` Whether the plan upgrade is possible. --- title: "`ClerkAPIResponseError`" description: An interface that represents an error returned by the Clerk API. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/clerk-api-response-error lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/clerk-api-response-error.mdx --- An interface that represents an error returned by the Clerk API. ## Properties * `clerkError` * `true` Always true, marks this as a Clerk API error. *** * `status` * `number` The HTTP status code returned by the API. *** * `message` * `string` The main error message. *** * `clerkTraceId?` * `string` Optional. A trace ID from Clerk for debugging or support. *** * `retryAfter?` * `number` Optional. If set, tells you how many seconds to wait before retrying (from `Retry-After` header). *** * `errors` * [ClerkAPIError](/docs/reference/javascript/types/clerk-api-error)\[] An array of error objects with more details about what went wrong. --- title: "`ClerkPaginatedResponse`" description: An interface that describes the response of a method that returns a paginated list of resources. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/clerk-paginated-response lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/clerk-paginated-response.mdx --- An interface that describes the response of a method that returns a paginated list of resources. ## Properties | Properties | Type | Description | | - | - | - | | `data` | `T[]` | An array that contains the fetched data. | | `totalCount` | `number` | The total count of data that exist remotely. | ## Error handling Clerk's SDKs always use `Promise>`. If the promise resolves, you will get back the [properties](#properties) listed above. If the promise is rejected, you will receive a `ClerkAPIResponseError` or network error. --- title: "`CustomPage`" description: An interface that provides the ability to add custom pages to the or components. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/custom-page lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/custom-page.mdx --- An interface that provides the ability to add custom pages to the \ or \ components. ## Attributes * `label` * `string` The label of the custom page. It is a required property. *** * `url` * `string | undefined` The path segment that will be used to navigate to the custom page. It should be relative when providing a custom page and absolute when providing a custom link. *** * `mountIcon` * `((el: HTMLDivElement) => void) | undefined` This function is called to mount the icon of the label. The `el` argument is the element where the icon should be mounted. *** * `unmountIcon` * `((el?: HTMLDivElement) => void) | undefined` This function is called to unmount the icon of the label. The `el` argument is the same element that was passed to the `mountIcon` function. *** * `mount` * `((el: HTMLDivElement) => void) | undefined` This function is called to mount the content of the custom page. The `el` argument is the element where the content should be mounted. *** * `unmount` * `((el?: HTMLDivElement) => void) | undefined` This function is called to unmount the content of the custom page. The `el` argument is the same element that was passed to the `mount` function. [userprofile-ref]: /docs/reference/components/user/user-profile [orgprofile-ref]: /docs/reference/components/organization/organization-profile --- title: "`CustomMenuItem`" description: An interface that provides the ability to add custom menu item to the component. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/custom-menu-item lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/custom-menu-item.mdx --- An interface that provides the ability to add custom menu item to the \ component. ## Attributes * `label` * `string` The label of the custom menu item. *** * `href?` * `string | undefined` The URL or path used to navigate to a route inside the app or an external website. It should be relative for internal routes and absolute for external links. *** * `onClick?` * `() => void | undefined` A function to be called when the menu item is clicked. *** * `open?` * `string | undefined` The path segment used to open a specific custom page in the user profile modal. *** * `mountIcon?` * `((el: HTMLDivElement) => void) | undefined` This function is called to mount the icon of the label. The `el` argument is the element where the icon should be mounted. *** * `unmountIcon?` * `((el?: HTMLDivElement) => void) | undefined` This function is called to unmount the icon of the label. The `el` argument is the same element that was passed to the `mountIcon` function. *** * `mount?` * `((el: HTMLDivElement) => void) | undefined` This function is called to mount the content of the custom page. The `el` argument is the element where the content should be mounted. *** * `unmount?` * `((el?: HTMLDivElement) => void) | undefined` This function is called to unmount the content of the custom page. The `el` argument is the same element that was passed to the `mount` function. [userbutton-ref]: /docs/reference/components/user/user-button --- title: "`DeletedObjectResource`" description: The DeletedObjectResource class represents an item that has been deleted from the database. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/deleted-object-resource lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/deleted-object-resource.mdx --- The `DeletedObjectResource` type represents an item that has been deleted from the database. ## Properties | Property | Type | Description | | ------------------------------ | --------- | --------------------------------------------------- | | `deleted` | `boolean` | Whether the object has been deleted. | | `id?` | `string` | The unique identifier for the deleted object. | | `object` | `string` | The type of object that has been deleted. | | `slug?` | `string` | The URL-friendly identifier for the deleted object. | --- title: "`EmailAddress`" description: The EmailAddress object is a model around an email address. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/email-address lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/email-address.mdx --- The `EmailAddress` object is a model around an email address. Email addresses are one of the identifiers used to provide identification for users. Email addresses must be **verified** to ensure that they are assigned to their rightful owners. The `EmailAddress` object holds all necessary state around the verification process. The following steps outline the verification process: 1. Initiate the verification process by collecting the user's email address. 2. Prepare the verification process by calling the [`prepareVerification()`](#prepare-verification) method, which will send a one-time verification code via an email link or code, depending on what parameters are passed to the method and the settings in the Clerk Dashboard. 3. Attempt to complete the verification by calling the [`attemptVerification()`](#attempt-verification) method, passing the one-time code as a parameter. For implementation examples for adding and verifying email addresses, see the [email link custom flow](/docs/guides/development/custom-flows/authentication/email-links) and [email code custom flow](/docs/guides/development/custom-flows/account-updates/add-email) guides. ## Properties * `id` * `string` The unique identifier for the email address. *** * `emailAddress` * `string` The value of the email address. *** * `verification` * [`Verification`](/docs/reference/javascript/types/verification) An object holding information on the verification of the email address. *** * `linkedTo` * `Array<{id: string, type: string}>` An array of objects containing information about any identifications that might be linked to the email address. ## Methods ### `create()` Creates a new email address for the current user. ```typescript function create(): Promise ``` ### `destroy()` Deletes the email address. ```typescript function destroy(): Promise ``` ### `toString()` Returns the value for the email address. Can also be accessed via the `EmailAddress.emailAddress` attribute. ```typescript function toString(): string ``` ### `prepareVerification()` Initiates the email address verification process. Based on the specified strategy, sends either a one-time verification code or a verification link to the email address. The verification status can be tracked through the `verification` property of the `EmailAddress` object. ```typescript function prepareVerification(params: PrepareEmailAddressVerificationParams): Promise ``` #### `PrepareEmailAddressVerificationParams` * `strategy` * `'email_link' | 'email_code'` The verification strategy. Supported strategies are: * `email_link`: User will receive an email link via email. * `email_code`: User will receive a one-time authentication code via email. *** * `redirectUrl` * `string | undefined` **Required** if `strategy` is set to `email_link`. The full URL that the user will be redirected to when they visit the email link. See the [custom flow](/docs/guides/development/custom-flows/authentication/email-links) for implementation details. ### `attemptVerification()` Attempts to verify an email address using a one-time code. The code must have been previously sent to the email address via the [EmailAddress.prepareVerification()](#prepare-verification) method with `strategy: 'email_code'`. Returns the updated `EmailAddress` object if verification is successful. ```typescript function attemptVerification(params: AttemptEmailAddressVerificationParams): Promise ``` #### `AttemptEmailAddressVerificationParams` * `code` * `string` The one-time code that was sent to the user's email address when [EmailAddress.prepareVerification()](#prepare-verification) was called with `strategy` set to `email_code`. ### `createEmailLinkFlow()` Sets up an email verification with email link flow. Calling `createEmailLinkFlow()` will return two functions. ```typescript function createEmailLinkFlow(): { startEmailLinkFlow: (params: StartEmailLinkFlowParams) => Promise cancelEmailLinkFlow: () => void } ``` `createEmailLinkFlow` returns an object with two functions: * `startEmailLinkFlow` * (params: [StartEmailLinkFlowParams](#start-email-link-flow-params)) => Promise\ Function to start the email link flow. It sends the email with the email link and polls for the verification result. *** * `cancelEmailLinkFlow` * `() => void` Function to stop polling for the verification result, allowing for full control of the flow and cleanup. #### `StartEmailLinkFlowParams` * `redirectUrl` * `string` The full URL that the user will be redirected to when they visit the email link. --- title: "`EmailLinkError`" description: Custom error for email links. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/email-link-error lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/email-link-error.mdx --- Custom error for email links. Raised when the email link verification doesn't succeed, either because the link has expired or a general failure. The error's `code` property will indicate the outcome, its values being: * `EmailLinkErrorCode.Expired` * `EmailLinkErrorCode.Failed` --- title: "`EnterpriseAccountConnection`" description: An interface that represents an enterprise account connection. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/enterprise-account-connection lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/enterprise-account-connection.mdx --- An interface that represents an enterprise account connection. * `active` * `boolean` A boolean that indicates whether the enterprise account connection is active. *** * `allow_idp_initiated` * `boolean` A boolean that indicates whether the enterprise account connection allows IDP-initiated authentication. *** * `allow_subdomains` * `boolean` A boolean that indicates whether the enterprise account connection allows subdomains. *** * `disable_additional_identifications` * `boolean` A boolean that indicates whether the enterprise account connection disables additional identifications. *** * `domain` * `string` The domain of the enterprise account connection. *** * `id` * `string` The unique identifier of the enterprise account connection. *** * `logo_public_url` * `string | null` The public URL of the enterprise account connection's logo. *** * `name` * `string` The name of the enterprise account connection. *** * `protocol` * `'saml' | 'oauth'` The authentication protocol of the enterprise account connection. *** * `provider` * "saml\_okta" | "saml\_google" | "saml\_microsoft" | "saml\_custom" | "oauth\_$\{[OAuthProvider](/docs/reference/javascript/types/sso#o-auth-provider)}" The provider of the enterprise account connection. *** * `sync_user_attributes` * `boolean` A boolean that indicates whether the enterprise account connection syncs user attributes. *** * `created_at` * `number` The timestamp of when the enterprise account connection was created. *** * `updated_at` * `number` The timestamp of when the enterprise account connection was updated. --- title: "`EnterpriseAccount`" description: An interface that represents an enterprise account. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/enterprise-account lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/enterprise-account.mdx --- An interface that represents an enterprise account. * `active` * `boolean` A boolean value that indicates whether the enterprise account is active. *** * `emailAddress` * `string` The email address of the enterprise account. *** * `enterpriseConnection` * [EnterpriseAccountConnection](/docs/reference/javascript/types/enterprise-account-connection) | null The enterprise connection associated with the enterprise account. *** * `firstName` * `string | null` The first name of the enterprise account. *** * `lastName` * `string | null` The last name of the enterprise account. *** * `protocol` * `'saml' | 'oauth'` The authentication protocol of the enterprise account connection. *** * `provider` * "saml\_okta" | "saml\_google" | "saml\_microsoft" | "saml\_custom" | "oauth\_$\{[OAuthProvider](/docs/reference/javascript/types/sso#o-auth-provider)}" The provider of the enterprise account. *** * `providerUserId` * `string | null` The user's ID as used in the provider. *** * `publicMetadata` * `Record | null` Metadata that can be read from both the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but can be set only from the Backend API. Once the user accepts the invitation and signs up, these metadata will end up in the user's public metadata. *** * `verification` * [Verification](/docs/reference/javascript/types/verification) | null The verification of the enterprise account. --- title: "`ExternalAccount`" description: The ExternalAccount object is a model around an identification obtained by an external provider (e.g. a social provider such as Google). sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/external-account lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/external-account.mdx --- The `ExternalAccount` object is a model around an identification obtained by an external provider (e.g. a social provider such as Google). External account must be verified, so that you can make sure they can be assigned to their rightful owners. The `ExternalAccount` object holds all necessary state around the verification process. ## Properties * `id` * `string` The unique identifier for this external account. *** * `identificationId` * `string` The identification with which this external account is associated. *** * `provider` * `string` The provider name (e.g., `google`). *** * `providerUserId` * `string` The unique ID of the user in the provider. *** * `emailAddress` * `string` The user's email address. *** * `approvedScopes` * `string[]` The scopes that the user has granted access to. *** * `firstName` * `string` The user's first name. *** * `lastName` * `string` The user's last name. *** * `imageUrl` * `string` The user's image URL. *** * `username` * `string | null` The user's [username](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#username). Only supported if username is enabled in the instance settings. *** * `phoneNumber` * `string | null` The phone number related to this specific external account. *** * `publicMetadata` * `Record` Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. *** * `label` * `string | null` A descriptive label to differentiate multiple external accounts of the same user for the same provider. *** * `verification` * [`Verification`](/docs/reference/javascript/types/verification) An object holding information on the verification of this external account. ## Methods ### `reauthorize()` Invokes a re-authorization flow for an existing external account. ```typescript function reauthorize(params: ReauthorizeExternalAccountParams): Promise ``` #### `ReauthorizeExternalAccountParams` * `additionalScopes` * `string[]` Additional scopes for your user to be prompted to approve. *** * `redirectUrl` * `string` The full URL or path that the OAuth provider should redirect to on successful authorization on their part. Typically, this will be a simple `/sso-callback` route that calls [`Clerk.handleRedirectCallback`](/docs/reference/javascript/clerk#handle-redirect-callback) or mounts the \ component. See the [custom flow](/docs/guides/development/custom-flows/authentication/oauth-connections) for implementation details. *** * `oidcPrompt?` * `string` The value to pass to the [OIDC `prompt` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=prompt,reauthentication%20and%20consent.) in the generated OAuth redirect URL. *** * `oidcLoginHint?` * `string` The value to pass to the [OIDC `login_hint` parameter](https://openid.net/specs/openid-connect-core-1_0.html#:~:text=login_hint,in%20\(if%20necessary\).) in the generated OAuth redirect URL. ### `destroy()` Deletes this external account. ```typescript function destroy(): Promise ``` ### `providerSlug()` A getter method for the `provider` attribute. ```typescript function providerSlug(): string ``` ### `providerTitle()` Returns the title of the provider with the word "Account" appended. EG: if `google` is passed as the parameter, `Google Account` will be returned. ```typescript function providerTitle(): string ``` ### `accountIdentifier()` Returns the identifier of the account, which can be one of the following: * `username` if present * `emailAddress` if present * `label` ```typescript function accountIdentifier(): string ``` --- title: "`FeatureResource`" description: The FeatureResource type represents a Feature of a Subscription Plan. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/feature-resource lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/feature-resource.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. The `FeatureResource` type represents a feature of a plan. ## Properties | Property | Type | Description | | -------------------------------------- | --------------------------- | ---------------------------------------------------------------------------- | | `avatarUrl` | null \| string | The URL of the feature's avatar image, or `null` if not set. | | `description` | null \| string | A short description of what the feature provides, or `null` if not provided. | | `id` | `string` | The unique identifier for the feature. | | `name` | `string` | The display name of the feature. | | `pathRoot` | `string` | The root path of the resource. | | `slug` | `string` | A unique, URL-friendly identifier for the feature. | --- title: "`LastAuthenticationStrategy`" description: The LastAuthenticationStrategy enum is used to indicate the last authentication strategy used by a client. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/last-authentication-strategy lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/last-authentication-strategy.mdx --- The `LastAuthenticationStrategy` enum is used to indicate the last authentication strategy used by a client. ```tsx type LastAuthenticationStrategy = | 'email_address' | 'email_code' | 'email_link' | 'phone_code' | 'password' | 'username' | 'oauth_' | 'web3_metamask_signature' | 'web3_base_signature' | 'web3_coinbase_wallet_signature' | 'web3_okx_wallet_signature' ``` --- title: "`OrganizationCustomPermissionKey`" description: A type that represents a user's Permission in an organization. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/organization-custom-permission-key lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/organization-custom-permission-key.mdx --- `OrganizationCustomPermissionKey` is a type that represents a user's Permission in an organization. It will be string unless the developer has provided their own types through [`ClerkAuthorization`](/docs/guides/development/override-clerk-types-interfaces#example-custom-roles-and-permissions). Clerk provides [default System Permissions](/docs/guides/organizations/roles-and-permissions#system-permissions). However, you can create [Custom Permissions](/docs/guides/organizations/roles-and-permissions#custom-permissions) as well. --- title: "`OrganizationCustomRoleKey`" description: A type that represents the user's Role in an Organization. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/organization-custom-role-key lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/organization-custom-role-key.mdx --- `OrganizationCustomRoleKey` is a type that represents the user's role in an organization. It will be string unless the developer has provided their own types through [`ClerkAuthorization`](/docs/guides/development/override-clerk-types-interfaces#example-custom-roles-and-permissions). Clerk provides the [default roles](/docs/guides/organizations/roles-and-permissions#default-roles) `org:admin` and `org:member`. However, you can create [custom roles](/docs/guides/organizations/roles-and-permissions#custom-roles) as well. --- title: Metadata description: Types related to metadata. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/metadata lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/metadata.mdx --- This reference contains types related to metadata. If you want to provide custom types for any of these types, you can redeclare them in the global namespace. See the [guide on custom types](/docs/guides/development/override-clerk-types-interfaces) for more information. ## `OrganizationPublicMetadata` A type that represents the public metadata for an Organization. ```ts interface OrganizationPublicMetadata { [k: string]: unknown } ``` ## `OrganizationPrivateMetadata` A type that represents the private metadata for an Organization. ```ts interface OrganizationPrivateMetadata { [k: string]: unknown } ``` ## `OrganizationInvitationPublicMetadata` A type that represents the public metadata for an Organization invitation. ```ts interface OrganizationInvitationPublicMetadata { [k: string]: unknown } ``` ## `OrganizationInvitationPrivateMetadata` A type that represents the private metadata for an Organization invitation. ```ts interface OrganizationInvitationPrivateMetadata { [k: string]: unknown } ``` ## `OrganizationMembershipPublicMetadata` A type that represents the public metadata for an Organization membership. ```ts interface OrganizationMembershipPublicMetadata { [k: string]: unknown } ``` ## `OrganizationMembershipPrivateMetadata` A type that represents the private metadata for an Organization membership. ```ts interface OrganizationMembershipPrivateMetadata { [k: string]: unknown } ``` ## `SignUpUnsafeMetadata` A type that represents the unsafe metadata for a sign-up. ```ts interface SignUpUnsafeMetadata { [k: string]: unknown } ``` ## `UserOrganizationInvitationPublicMetadata` A type that represents the public metadata for a user Organization invitation. ```ts interface UserOrganizationInvitationPublicMetadata { [k: string]: unknown } ``` ## `UserPublicMetadata` A type that represents the public metadata for a user. ```ts interface UserPublicMetadata { [k: string]: unknown } ``` ## `UserPrivateMetadata` A type that represents the private metadata for a user. ```ts interface UserPrivateMetadata { [k: string]: unknown } ``` ## `UserUnsafeMetadata` A type that represents the unsafe metadata for a user. ```ts interface UserUnsafeMetadata { [k: string]: unknown } ``` --- title: "`OrganizationDomain`" description: The OrganizationDomain object is the model around an Organization domain. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/organization-domain lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/organization-domain.mdx --- The `OrganizationDomain` object is the model around an Organization domain. ## Properties * `id` * `string` The unique identifier for this Organization domain. *** * `name` * `string` The name for this Organization domain (e.g. example.com). *** * `organizationId` * `string` The Organization ID of the Organization this domain is for. *** * `enrollmentMode` * `'manual_invitation' | 'automatic_invitation' | 'automatic_suggestion'` An [enrollment mode](/docs/guides/organizations/verified-domains#enrollment-mode) will change how new users join an Organization. *** * `verification` * [`OrganizationDomainVerification`](#organization-domain-verification) The object that describes the status of the verification process of the domain. *** * `affiliationEmailAddress` * `string | null` The email address that was used to verify this Organization domain. *** * `totalPendingInvitations` * `number` The number of total pending invitations sent to emails that match the domain name. *** * `totalPendingSuggestions` * `number` The number of total pending suggestions sent to emails that match the domain name. *** * `createdAt` * `Date` The date when the Organization domain was created. *** * `updatedAt` * `Date` The date when the Organization domain was last updated. ### `OrganizationDomainVerification` * `status` * `'unverified' | 'verified'` The status of the verification process. *** * `strategy` * `'email_code'` A string that indicates strategy of the verification. *** * `attempts` * `number` A number that indicates how many attempts have occurred in order to verify the domain. *** * `expiresAt` * `Date` The expiration date and time of the verification. ## Methods ## `delete()` Deletes the Organization domain and removes it from the Organization. ```ts {{ prettier: false }} function delete(): Promise ``` ## `prepareAffiliationVerification()` Begins the verification process of a created Organization domain. This is a required step in order to complete the registration of the domain under the Organization. ```typescript function prepareAffiliationVerification( params: PrepareAffiliationVerificationParams, ): Promise ``` ### `PrepareAffiliationVerificationParams` * `affiliationEmailAddress` * `string` An email address that is affiliated with the domain name (e.g. [user@example.com](mailto:user@example.com)). ## `attemptAffiliationVerification()` Attempts to complete the domain verification process. This is a required step in order to complete the registration of a domain under an Organization, as the administrator should be verified as a person who is affiliated with that domain. Make sure that an `OrganizationDomain` object already exists before you call this method, by first calling [`OrganizationDomain.prepareAffiliationVerification`](#prepare-affiliation-verification). ```typescript function attemptAffiliationVerification( params: AttemptAffiliationVerificationParams, ): Promise ``` ### `AttemptAffiliationVerificationParams` * `code` * `string` The one-time code that was sent to the user as part of this verification step. --- title: "`OrganizationInvitation`" description: The OrganizationInvitation object is the model around an Organization invitation. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/organization-invitation lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/organization-invitation.mdx --- The `OrganizationInvitation` object is the model around an Organization invitation. ## Properties * `id` * `string` The unique identifier for this Organization invitation. *** * `emailAddress` * `string` The email address the invitation has been sent to. *** * `organizationId` * `string` The Organization ID of the Organization this invitation is for. *** * `publicMetadata` * [`OrganizationInvitationPublicMetadata`](/docs/reference/javascript/types/metadata#organization-invitation-public-metadata) Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. *** * `role` * [`OrganizationCustomRoleKey`](/docs/reference/javascript/types/organization-custom-role-key) The [Role](/docs/guides/organizations/roles-and-permissions) of the current user in the Organization. *** * `status` * `'pending' | 'accepted' | 'revoked'` The status of the invitation. *** * `createdAt` * `Date` The date when the invitation was created. *** * `updatedAt` * `Date` The date when the invitation was last updated. ## Methods ### `revoke()` Revokes the invitation for the email it corresponds to. ```typescript function revoke(): Promise ``` ### Example The following example demonstrates how to revoke an Organization invitation. It first gets the list of Organization invitations using [`getInvitations()`](/docs/reference/javascript/organization#get-invitations) and then revokes the first invitation in the list. It assumes: * you have followed the [quickstart](/docs/js-frontend/getting-started/quickstart) in order to add Clerk to your JavaScript application * you have [enabled the Organizations feature in the Clerk Dashboard](/docs/guides/organizations/overview#enable-organizations-in-your-application) ```js {{ filename: 'main.js', mark: [22, 23] }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Check for an Active Organization if (clerk.organization) { // Get list of organization invitations const { totalCount, data } = await clerk.organization.getInvitations() const invitations = data console.log(`Invitations:`, invitations) if (invitations.length === 0) { console.log('No invitations to revoke.') } // Revoke the first invitation in the list invitations[0] .revoke() .then((res) => console.log(res)) .catch((error) => console.log(error.errors)) } else { // If there is no Active Organization, // mount Clerk's // to allow the user to set an organization as active document.getElementById('app').innerHTML = `

Select an organization to set it as active

` const orgSwitcherDiv = document.getElementById('org-switcher') clerk.mountOrganizationSwitcher(orgSwitcherDiv) } } else { document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ``` --- title: "`OrganizationMembershipRequest`" description: The OrganizationMembershipRequest object is the model that describes the request of a user to join an Organization. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/organization-membership-request lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/organization-membership-request.mdx --- The `OrganizationMembershipRequest` object is the model that describes the request of a user to join an Organization. ## Properties * `id` * `string` The unique identifier for this membership request. *** * `organizationId` * `string` The Organization ID of the Organization this request is for. *** * `status` * `'pending' | 'accepted' | 'revoked'` The status of the request. *** * `publicUserData` * [`PublicUserData`](/docs/reference/javascript/types/public-user-data) Public information about the user that this request belongs to. *** * `createdAt` * `Date` The date when the membership request was created. *** * `updatedAt` * `Date` The date when the membership request was last updated. ## Methods ## `accept()` Accepts the request of a user to join the Organization the request refers to. ```typescript function accept(): Promise ``` ## `reject()` Rejects the request of a user to join the Organization the request refers to. ```typescript function reject(): Promise ``` --- title: "`OrganizationMembership`" description: The OrganizationMembership object is the model around an Organization membership entity and describes the relationship between users and Organizations. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/organization-membership lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/organization-membership.mdx --- The `OrganizationMembership` object is the model around an Organization membership entity and describes the relationship between users and Organizations. ## Properties * `id` * `string` The unique identifier for this Organization membership. *** * `publicMetadata` * [`OrganizationMembershipPublicMetadata`](/docs/reference/javascript/types/metadata#organization-membership-public-metadata) Metadata that can be read from the Frontend API and [Backend API](/docs/reference/backend-api){{ target: '_blank' }} and can be set only from the Backend API. *** * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) of the current user in the Organization. *** * `publicUserData` * [`PublicUserData`](/docs/reference/javascript/types/public-user-data) Public information about the user that this membership belongs to. *** * `organization` * [`Organization`](/docs/reference/javascript/organization) The [`Organization`](/docs/reference/javascript/organization) object the membership belongs to. *** * `createdAt` * `Date` The date when the membership was created. *** * `updatedAt` * `Date` The date when the membership was last updated. ## Methods ### `destroy()` Deletes the membership from the Organization the membership belongs to. ```typescript function destroy(): Promise ``` ### `update()` Updates the member's Role. ```typescript function update(updateParams: UpdateOrganizationMembershipParams): Promise ``` #### `UpdateOrganizationMembershipParams` * `role` * `string` The [Role](/docs/guides/organizations/roles-and-permissions) of the new member. --- title: OrganizationSuggestion description: An interface representing an Organization suggestion. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/organization-suggestion lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/organization-suggestion.mdx --- An interface representing an Organization suggestion. * `id` * `string` The ID of the Organization suggestion. *** * `publicOrganizationData` * `{ hasImage: boolean; imageUrl: string; name: string; id: string; slug: string | null; }` The public data of the Organization. * `hasImage`: Whether the Organization has an image. * `imageUrl`: Holds the Organization logo. Compatible with Clerk's [Image Optimization](/docs/guides/development/image-optimization). * `name`: The name of the Organization. * `id`: The ID of the Organization. * `slug`: The slug of the Organization. *** * `status` * `'pending' | 'accepted'` The status of the Organization suggestion. *** * `createdAt` * `Date` The date and time when the Organization suggestion was created. *** * `updatedAt` * `Date` The date and time when the Organization suggestion was last updated. ## `accept()` Accepts the Organization suggestion. Returns the accepted `OrganizationSuggestion`. ```ts function accept(): Promise ``` --- title: Clerk types description: Explore the different types available for typing your application. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/overview.mdx --- Types are a powerful tool for adding type-safety to your application. They can help you catch bugs early, make your code easier to understand, and make your code easier to refactor. Clerk provides a number of types to help you add type-safety to your application. To get access to Clerk types, you need to add the `@clerk/types` package to your project. Run the following command to install it: ```npm npm install @clerk/types ``` --- title: "`PhoneNumber`" description: The PhoneNumber object describes a phone number. Phone numbers can be used as a proof of identification for users, or simply as a means of contacting users. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/phone-number lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/phone-number.mdx --- The `PhoneNumber` object describes a phone number. Phone numbers can be used as a proof of identification for users, or simply as a means of contacting users. Phone numbers must be **verified** to ensure that they can be assigned to their rightful owners. The `PhoneNumber` object holds all the necessary state around the verification process. * The verification process always starts with the [`prepareVerification()`](#prepare-verification) method, which will send a one-time verification code via an SMS message. * The second and final step involves an attempt to complete the verification by calling the [`attemptVerification()`](#attempt-verification) method, passing the one-time code as a parameter. Finally, phone numbers can be used as part of [multi-factor authentication](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication). During sign in, users can opt in to an extra verification step where they will receive an SMS message with a one-time code. This code must be entered to complete the sign in process. ## Properties * `id` * `string` The unique identifier for this phone number. *** * `phoneNumber` * `string` The value of this phone number, in [E.164 format](https://en.wikipedia.org/wiki/E.164). *** * `reservedForSecondFactor` * `boolean` Set to `true` if this phone number is reserved for multi-factor authentication (2FA). Set to `false` otherwise. *** * `defaultSecondFactor` * `boolean` Set to `true` if this phone number is the default second factor. Set to `false` otherwise. A user must have exactly one default second factor, if multi-factor authentication (2FA) is enabled. *** * `verification` * [`Verification`](/docs/reference/javascript/types/verification) An object holding information on the verification of this phone number. *** * `linkedTo` * `Array<{id: string, type: string}>` An object containing information about any other identification that might be linked to this phone number. *** * `backupCodes` * `string[] | undefined` A list of backup codes in case of lost phone number access. ## Methods ### `create()` Creates a new phone number for the current user. ```typescript function create(): Promise ``` ### `destroy()` Deletes this phone number. ```typescript function destroy(): Promise ``` ### `toString()` Returns the in [E.164 format](https://en.wikipedia.org/wiki/E.164) which includes the country code and the phone number.. Can also be accessed via the `PhoneNumber.phoneNumber` attribute. ```typescript function toString(): string ``` ### `prepareVerification()` Kick off the verification process for this phone number. An SMS message with a one-time code will be sent to the phone number value. ```typescript function prepareVerification(): Promise ``` ### `attemptVerification()` Attempts to verify this phone number, passing the one-time code that was sent as an SMS message. The code will be sent when calling the [`PhoneNumber.prepareVerification()`](#prepare-verification) method. ```typescript function attemptVerification(params: AttemptPhoneNumberVerificationParams): Promise ``` ### `AttemptPhoneNumberVerificationParams` * `code` * `string` The one-time code that was sent to the user's phone number when `prepareVerification` was called. ### `makeDefaultSecondFactor()` Marks this phone number as the default second factor for [multi-factor authentication](/docs/guides/development/custom-flows/authentication/email-password-mfa)(2FA). A user can have exactly one default second factor. ```typescript function makeDefaultSecondFactor(): Promise ``` ### `setReservedForSecondFactor()` Marks this phone number as reserved for [multi-factor authentication](/docs/guides/development/custom-flows/authentication/email-password-mfa) (2FA) or not. ```typescript function setReservedForSecondFactor(params: SetReservedForSecondFactorParams): Promise ``` #### `SetReservedForSecondFactorParams` * `reserved` * `boolean` Pass `true` to mark this phone number as reserved for 2FA, or `false` to disable 2FA for this phone number. --- title: "`PermissionResource`" description: An interface that represents a Permission in an Organization. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/permission lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/permission.mdx --- An interface that represents a Permission in an Organization. * `id` * `string` The unique identifier of the Permission. *** * `key` * `string` The unique key of the Permission. *** * `name` * `string` The name of the Permission. *** * `type` * `'system' | 'user'` The type of the Permission. *** * `createdAt` * `Date` The date when the Permission was created. *** * `updatedAt` * `Date` The date when the Permission was last updated. --- title: "`PasskeyResource`" description: An interface that describes a passkey associated with a user response. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/passkey-resource lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/passkey-resource.mdx --- An interface that describes a passkey associated with a user response. ## Properties * `id` * `string` The unique identifier of the passkey. *** * `name` * `string` The passkey's name. *** * `verification` * [`Verification`](/docs/reference/javascript/types/verification) The verification details for the passkey. *** * `createdAt` * `Date` The date when the passkey was created. *** * `updatedAt` * `Date` The date when the passkey was last updated. *** * `lastUsedAt` * `Date | null` The date when the passkey was last used. ## Methods ### `update()` Updates the name of the associated passkey for the signed-in user. ```ts function update(params: { name: string }): Promise ``` For an example of how to use these methods, see the [Passkeys custom flows documentation](/docs/guides/development/custom-flows/authentication/passkeys#rename-user-passkeys). ### `delete()` Deletes the associated passkey for the signed-in user. ```ts {{ prettier: false }} function delete(): Promise ``` Learn more: * [`DeletedObjectResource`](/docs/reference/javascript/types/deleted-object-resource) For an example of how to use these methods, see the [Passkeys custom flows documentation](/docs/guides/development/custom-flows/authentication/passkeys#delete-user-passkeys). --- title: "`PublicUserData`" description: Information about that user that's publicly available. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/public-user-data lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/public-user-data.mdx --- Information about the user that's publicly available. ## Properties * `firstName` * `string | null` The user's first name. *** * `lastName` * `string | null` The user's last name. *** * `imageUrl` * `string` Holds the default avatar or user's uploaded profile image. Compatible with Clerk's [Image Optimization](/docs/guides/development/image-optimization). *** * `hasImage` * `boolean` A getter boolean to check if the user has uploaded an image or one was copied from OAuth. Returns `false` if Clerk is displaying an avatar for the user. *** * `identifier` * `string` The user's identifier. *** * `userId?` * `string | null` The user's ID. --- title: "`RedirectOptions`" description: An interface that provides options for a range of redirect methods. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/redirect-options lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/redirect-options.mdx --- An interface that provides options for a range of redirect methods. ## Properties * `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. *** * `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. --- title: "`SamlAccount`" description: An interface that represents a SAML account. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/saml-account lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/saml-account.mdx --- An interface that represents a SAML account. * `active` * `boolean` A boolean that indicates whether the SAML account is active. *** * `email_address` * `string` The email address of the SAML account. *** * `first_name` * `string` The first name of the SAML account. *** * `last_name` * `string` The last name of the SAML account. *** * `saml_connection` * [SamlAccountConnection](/docs/reference/javascript/types/saml-account-connection) | null The SAML connection of the SAML account. *** * `provider` * `'saml_okta' | 'saml_google' | 'saml_microsoft' | 'saml_custom'` The provider of the SAML account. *** * `provider_user_id` * `string | null` The user's ID as used in the provider. *** * `verification` * [Verification](/docs/reference/javascript/types/verification) | null The verification of the SAML account. --- title: "`SessionStatus`" description: The SessionStatus enum is used to indicate the status of a session. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/session-status lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/session-status.mdx --- The `SessionStatus` enum is used to indicate the status of a session. ```tsx type SessionStatus = | 'abandoned' | 'active' | 'pending' | 'ended' | 'expired' | 'removed' | 'replaced' | 'revoked' ``` ## Properties | Value | Description | | - | - | | `abandoned` | The session was abandoned client-side. | | `active` | The session is valid and all activity is allowed. | | `pending` | The user has signed in but hasn't completed [session tasks](/docs/guides/configure/session-tasks). | | `ended` | The user signed out of the session, but the [`Session`](/docs/reference/javascript/session) remains in the [`Client`](/docs/reference/javascript/client) object. | | `expired` | The period of allowed activity for this session has passed. | | `removed` | The user signed out of the session and the [`Session`](/docs/reference/javascript/session) was removed from the [`Client`](/docs/reference/javascript/client) object. | | `replaced` | The session has been replaced by another one, but the [`Session`](/docs/reference/javascript/session) remains in the [`Client`](/docs/reference/javascript/client) object. | | `revoked` | The application ended the session and the [`Session`](/docs/reference/javascript/session) was removed from the [`Client`](/docs/reference/javascript/client) object. | [session-ref]: /docs/reference/javascript/session [client-ref]: /docs/reference/javascript/client --- title: "`SamlAccountConnection`" description: An interface that represents a SAML account connection. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/saml-account-connection lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/saml-account-connection.mdx --- An interface that represents a SAML account connection. * `active` * `boolean` A boolean that indicates whether the SAML account connection is active. *** * `allowIdpInitiated` * `boolean` A boolean that indicates whether the SAML account connection allows IDP-initiated authentication. *** * `allowSubdomains` * `boolean` A boolean that indicates whether the SAML account connection allows subdomains. *** * `createdAt` * `Date` The date and time when the SAML account connection was created. *** * `disableAdditionalIdentifications` * `boolean` A boolean that indicates whether the SAML account connection disables additional identifications. *** * `domain` * `string` The domain of the SAML account connection. *** * `id` * `string` The unique identifier of the SAML account connection. *** * `name` * `string` The name of the SAML account connection. *** * `provider` * `string` The provider of the SAML account connection. *** * `syncUserAttributes` * `boolean` A boolean that indicates whether the SAML account connection syncs user attributes. *** * `updatedAt` * `Date` The date and time when the SAML account connection was updated. --- title: "`RoleResource`" description: An interface that represents a Role in an Organization. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/role lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/role.mdx --- An interface that represents a Role in an Organization. * `id` * `string` The unique identifier of the Role. *** * `key` * `string` The unique key of the Role. *** * `name` * `string` The name of the Role. *** * `description` * `string` The description of the Role. *** * `permissions` * [PermissionResource](/docs/reference/javascript/types/permission)\[] The Permissions of the Role. *** * `createdAt` * `Date` The date when the Role was created. *** * `updatedAt` * `Date` The date when the Role was last updated. --- title: "`SessionTask`" description: The SessionTask interface represents the current pending task of a session. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/session-task lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/session-task.mdx --- An interface that represents the current [pending task](/docs/guides/configure/session-tasks) of a session. ## Properties * `key` * `'choose-organization'` A unique identifier for the task. Currently, the only supported value is `'choose-organization'`, which indicates that the user needs to choose an Organization before proceeding. --- title: SessionVerification description: The SessionVerification interface represents the state of a session reverification process. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/session-verification lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/session-verification.mdx --- An interface that represents the state of the session verification process. ## Properties * `status` * `'needs_first_factor' | 'needs_second_factor' | 'complete'` The current state of the session verification. *** * `level` * `'first_factor' | 'second_factor' | 'multi_factor'` The requested level of the session verification. *** * `session` * [`Session`](/docs/reference/javascript/session) The `Session` object that the session verification is attached to. *** * `firstFactorVerification` * [`Verification`](/docs/reference/javascript/types/verification) The state of the verification process for the selected first factor. Initially, this property contains an empty `Verification` object, since there is no first factor selected. You need to call the [`prepareFirstFactorVerification()`](/docs/reference/javascript/session#prepare-first-factor-verification) method in order to start the verification process. *** * `secondFactorVerification` * [`Verification`](/docs/reference/javascript/types/verification) The state of the verification process for the selected second factor. Initially, this property contains an empty `Verification` object, since there is no second factor selected. For the `phone_code` strategy, you need to call the [`prepareSecondFactorVerification()`](/docs/reference/javascript/session#prepare-second-factor-verification) method in order to start the verification process. For the `totp` or `backup_code` strategies, you can directly attempt the verification by calling the [`attemptSecondFactorVerification()`](/docs/reference/javascript/session#attempt-second-factor-verification) method. *** * `supportedFirstFactors` * [EmailCodeFactor](/docs/reference/javascript/types/sign-in-first-factor#email-code-factor)\[] | [PhoneCodeFactor](/docs/reference/javascript/types/sign-in-first-factor#phone-code-factor)\[] | [PasswordFactor](/docs/reference/javascript/types/sign-in-first-factor#password-factor)\[] Array of the first factors that are supported in the current session verification. Each factor contains information about the verification strategy that can be used. *** * `supportedSecondFactors` * [TOTPFactor](/docs/reference/javascript/types/sign-in-second-factor#totp-factor)\[] | [PhoneCodeFactor](/docs/reference/javascript/types/sign-in-first-factor#phone-code-factor)\[] | [BackupCodeFactor](/docs/reference/javascript/types/sign-in-second-factor#backup-code-factor)\[] Array of the second factors that are supported in the current session verification. Each factor contains information about the verification strategy that can be used. --- title: "`SessionWithActivities`" description: The SessionWithActivities object is a modified Session object. It contains most of the information that the Session object stores, adding extra information about the current session's latest activity. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/session-with-activities lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/session-with-activities.mdx --- The `SessionWithActivities` object is a modified [`Session`](/docs/reference/javascript/session) object. It includes most of the information stored in the `Session` object, with additional details about the latest activity in the current session. `SessionWithActivities` is returned by the [`User.getSessions()`](/docs/reference/javascript/user#get-sessions) method. The additional data included in the latest activity is useful for analytics purposes. A [`SessionActivity`](#session-activity) object provides information about the user's location, device and browser. While the `SessionWithActivities` object wraps the most important information around a `Session` object, the two objects have entirely different methods. ## Properties * `id` * `string` The unique identifier for the session. *** * `status` * [`SessionStatus`](/docs/reference/javascript/types/session-status) The current state of the session. *** * `lastActiveAt` * `Date` The time the session was last active on the [`Client`](/docs/reference/javascript/client). *** * `abandonAt` * `Date` The time when the session was abandoned by the user. *** * `expireAt` * `Date` The time the session expires and will seize to be active. *** * `latestActivity` * [`SessionActivity`](#session-activity) An object that provides additional information about this session, focused around user activity data. ## Methods ### `revoke()` Marks this session as revoked. If this is the active session, the attempt to revoke it will fail. Users can revoke only their own sessions. ```typescript function revoke(): Promise ``` ## Types ### `SessionActivity` * `id` * `string` The unique identifier for the session activity record. *** * `browserName` * `string | undefined` The name of the browser from which this session activity occurred. *** * `browserVersion` * `string | undefined` The version of the browser from which this session activity occurred. *** * `deviceType` * `string | undefined` The type of the device which was used in this session activity. *** * `ipAddress` * `string | undefined` The IP address from which this session activity originated. *** * `city` * `string | undefined` The city from which this session activity occurred. Resolved by IP address geo-location. *** * `country` * `string | undefined` The country from which this session activity occurred. Resolved by IP address geo-location. *** * `isMobile` * `boolean | undefined` Will be set to `true` if the session activity came from a mobile device. Set to `false` otherwise. --- title: "`SignInFirstFactor`" description: The SignInFirstFactor type represents the first factor verification strategy that can be used in the sign-in process. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/sign-in-first-factor lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/sign-in-first-factor.mdx --- The `SignInFirstFactor` type represents the first factor verification strategy that can be used in the sign-in process. ```ts type SignInFirstFactor = | EmailCodeFactor | EmailLinkFactor | PhoneCodeFactor | PasswordFactor | ResetPasswordPhoneCodeFactor | ResetPasswordEmailCodeFactor | Web3SignatureFactor | OauthFactor | SamlFactor ``` * `strategy` * `'email_code'` | `'email_link'` | `'phone_code'` | `'password'` | `'passkey'` | `'reset_password_phone_code'` | `'reset_password_email_code'` | `'web3_base_signature'` | `'web3_metamask_signature'` | `'web3_coinbase_wallet_signature'` | `'web3_okx_wallet_signature'` | [`OAuthStrategy`](/docs/reference/javascript/types/sso) | `'saml'` | `'enterprise_sso'` The strategy of the factor. *** * `emailAddressId` * `string` The ID of the email address that a code or link will be sent to. Populated when the `strategy` is `'email_code'`, `'email_link'`, or `'reset_password_email_code'`. *** * `phoneNumberId` * `string` The ID of the phone number that a code will be sent to. Populated when the `strategy` is `'phone_code'` or `'reset_password_phone_code'`. *** * `web3WalletId` * `string` The ID of the Web3 wallet that will be used to sign a message. Populated when the `strategy` is `'web3_base_signature'`, `'web3_metamask_signature'`, `'web3_coinbase_wallet_signature'`, or `'web3_okx_wallet_signature'`. *** * `safeIdentifier` * `'emailAddress'` | `'phoneNumber'` The safe identifier of the factor. Populated when the strategy is `'email_code'`, `'email_link'`, `'phone_code'`, `'reset_password_email_code'`, or `'reset_password_phone_code'`. *** * `primary` * `boolean` Whether the factor is the primary factor. Populated when the strategy is `'email_code'`, `'email_link'`, `'phone_code'`, `'web3_base_signature'`, `'web3_metamask_signature'`, `'web3_coinbase_wallet_signature'`, `'web3_okx_wallet_signature'`, `'reset_password_email_code'`, or `'reset_password_phone_code'`. ## `EmailCodeFactor` ```ts type EmailCodeFactor = { strategy: EmailCodeStrategy emailAddressId: string safeIdentifier: string primary?: boolean } ``` ## `EmailLinkFactor` ```ts type EmailLinkFactor = { strategy: EmailLinkStrategy emailAddressId: string safeIdentifier: string primary?: boolean } ``` ## `PhoneCodeFactor` ```ts type PhoneCodeFactor = { strategy: PhoneCodeStrategy phoneNumberId: string safeIdentifier: string primary?: boolean default?: boolean } ``` ## `PasswordFactor` ```ts type PasswordFactor = { strategy: PasswordStrategy } ``` ## `ResetPasswordPhoneCodeFactor` ```ts type ResetPasswordPhoneCodeFactor = { strategy: ResetPasswordPhoneCodeStrategy phoneNumberId: string safeIdentifier: string primary?: boolean } ``` ## `ResetPasswordEmailCodeFactor` ```ts type ResetPasswordEmailCodeFactor = { strategy: ResetPasswordEmailCodeStrategy emailAddressId: string safeIdentifier: string primary?: boolean } ``` ## `Web3SignatureFactor` ```ts type Web3SignatureFactor = { strategy: Web3Strategy web3WalletId: string primary?: boolean } ``` ## `OauthFactor` ```ts type OauthFactor = { strategy: OAuthStrategy } ``` ## `SamlFactor` ```ts type SamlFactor = { strategy: SamlStrategy } ``` --- title: "`SetActiveParams`" description: The parameters for the `setActive()` method. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/set-active-params lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/set-active-params.mdx --- The parameters for the `setActive()` method. * `session` * [Session](/docs/reference/javascript/session) | string | null The session resource or session ID (string version) to be set as active. If `null`, the current session is deleted. *** * `organization` * [Organization](/docs/reference/javascript/organization) | string | null The Organization resource or Organization ID/slug (string version) to be set as active in the current session. If `null`, the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. is removed as active. *** * `beforeEmit?` (deprecated) * `(session?: Session | null) => void | Promise` Deprecated in favor of `redirectUrl`. Callback run just before the active session and/or Organization is set to the passed object. Can be used to set up for pre-navigation actions. *** * `redirectUrl?` * `string` The full URL or path to redirect to just before the active session and/or Organization is set. *** * `navigate?` * `(opts: { session: SessionResource; }) => Promise` A custom navigation function to be called just before the session and/or Organization is set. When provided, it takes precedence over the `redirectUrl` parameter for navigation. --- title: "`SignInInitialValues`" description: The type for the `initialValues` prop that is used to pre-populate the sign-in form. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/sign-in-initial-values lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/sign-in-initial-values.mdx --- The type for the `initialValues` prop that is used to pre-populate the sign-in form. ## Properties * `emailAddress?` * `string | undefined` The email address of the user. *** * `username?` * `string | undefined` The username of the user. *** * `phoneNumber?` * `string | undefined` The user's phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164). --- title: "`SignInSecondFactor`" description: The SignInSecondFactor type represents the second factor verification strategy that can be used in the sign-in process. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/sign-in-second-factor lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/sign-in-second-factor.mdx --- The `SignInSecondFactor` type represents the second factor verification strategy that can be used in the sign-in process. ```ts type SignInSecondFactor = PhoneCodeFactor | TOTPFactor | BackupCodeFactor ``` * `strategy` * `'phone_code' | 'totp' | 'backup_code'` The strategy of the factor. *** * `phoneNumberId` * `string` The ID of the phone number that a code will be sent to. Populated when the `strategy` is `'phone_code'`. *** * `safeIdentifier` * `string` The safe identifier of the factor. Supports the following values: * `'phoneNumber'` Populated when the strategy is `'phone_code'`. *** * `primary` * `boolean` Whether the factor is the primary factor. Populated when the strategy is `'phone_code'`. ## `TOTPFactor` ```ts type TOTPFactor = { strategy: TOTPStrategy } ``` ## `BackupCodeFactor` ```ts type BackupCodeFactor = { strategy: BackupCodeStrategy } ``` --- title: "`SignUpRedirectOptions`" description: An interface that provides options for sign-up redirect methods. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/sign-up-redirect-options lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/sign-up-redirect-options.mdx --- An interface that provides options for sign-up redirect methods. ## Properties * `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. *** * `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. --- title: "`SignUpInitialValues`" description: The type for the `initialValues` prop that is used to pre-populate the sign-up form. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/sign-up-initial-values lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/sign-up-initial-values.mdx --- The type for the `initialValues` prop that is used to pre-populate the sign-up form. ## Properties * `emailAddress?` * `string | undefined` The user's email address. *** * `username?` * `string | undefined` The user's username. *** * `phoneNumber?` * `string | undefined` The user's phone number in [E.164 format](https://en.wikipedia.org/wiki/E.164). *** * `firstName?` * `string | undefined` The user's first name. *** * `lastName?` * `string | undefined` The user's last name. --- title: "`SignInRedirectOptions`" description: An interface that provides options for sign-in redirect methods. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/sign-in-redirect-options lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/sign-in-redirect-options.mdx --- An interface that provides options for sign-in redirect methods. ## Properties * `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. *** * `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. --- title: SSO Types description: Types related to SSO providers and strategies. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/sso lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/sso.mdx --- ## `OAuthStrategy` A type that represents the OAuth strategy for a given provider. For example, when creating a [`SignIn`](/docs/reference/javascript/sign-in#sign-in-create-params) or [`SignUp`](/docs/reference/javascript/sign-up#sign-up-create-params), you can pass the `strategy` option to specify the OAuth strategy to use. ```ts type OAuthStrategy = `oauth_${OAuthProvider}` | CustomOAuthStrategy ``` ## `OAuthProvider` A type that represents the OAuth provider. ```ts type OAuthProvider = | 'facebook' | 'google' | 'hubspot' | 'github' | 'tiktok' | 'gitlab' | 'discord' | 'twitter' | 'twitch' | 'linkedin' | 'linkedin_oidc' | 'dropbox' | 'atlassian' | 'bitbucket' | 'microsoft' | 'notion' | 'apple' | 'line' | 'instagram' | 'coinbase' | 'spotify' | 'xero' | 'box' | 'slack' | 'linear' | 'x' | 'huggingface' | `custom_${string}` ``` ## `CustomOAuthStrategy` A type that represents a [custom OAuth strategy](/docs/guides/configure/auth-strategies/social-connections/custom-provider). ```ts type CustomOAuthStrategy = `oauth_custom_${string}` ``` ## `EnterpriseSSOStrategy` A type that represents an [Enterprise SSO](/docs/guides/configure/auth-strategies/enterprise-connections/authentication-flows) strategy. ```ts type EnterpriseSSOStrategy = `enterprise_sso` ``` --- title: "`TOTPResource`" description: An interface that represents a TOTP secret. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/totp lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/totp.mdx --- An interface that represents a TOTP secret. * `id` * `string` The unique identifier for this TOTP secret. *** * `secret?` * `string` The generated TOTP secret. This is only returned to the client upon creation and cannot be retrieved afterwards. *** * `uri?` * `string` A complete TOTP configuration URI including the Issuer, Account, etc that can be pasted to an authenticator app or encoded to a QR code and scanned for convenience. This is only returned to the client upon creation and cannot be retrieved afterwards. *** * `verified` * `boolean` A boolean indicating whether this TOTP secret has been verified by the user by providing one code generated with it. TOTP is not enabled on the user unless they have a verified secret. *** * `backupCodes?` * `string[]` A set of fresh generated Backup codes. This will be populated if the feature is enabled in your instance and the user doesn't already have backup codes generated. *** * `createdAt` * `Date` The date when the TOTP secret was created. *** * `updatedAt` * `Date` The date when the TOTP secret was last updated. --- title: "`Verification`" description: An interface that represents the state of the verification process of a sign-in or sign-up attempt. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/verification lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/verification.mdx --- An interface that represents the state of the verification process of a sign-in or sign-up attempt. * `attempts` * `number | null` The number of attempts related to the verification. *** * `error` * `ClerkAPIError | null` The last error the verification attempt ran into. *** * `expireAt` * `Date | null` The time the verification will expire at. *** * `externalVerificationRedirectURL` * `URL | null` The redirect URL for an external verification. *** * `nonce` * `string | null` The [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) pertaining to the verification. *** * `message` * `string | null` The message that will be presented to the user's Web3 wallet for signing during authentication. This follows the [Sign-In with Ethereum (SIWE) protocol format](https://docs.login.xyz/general-information/siwe-overview/eip-4361#example-message-to-be-signed), which typically includes details like the requesting service, wallet address, terms acceptance, nonce, timestamp, and any additional resources. *** * `status` * `'unverified' | 'verified' | 'transferable' | 'failed' | 'expired' | null` The state of the verification. * `unverified`: The verification has not been verified yet. * `verified`: The verification has been verified. * `transferable`: The verification is transferable to between sign-in and sign-up flows. * `failed`: The verification has failed. * `expired`: The verification has expired. *** * `strategy` * `string | null` The strategy pertaining to the parent sign-up or sign-in attempt. *** * `verifiedAtClient` * `string | null` The client ID where the verification was completed. ## Methods ### `verifiedFromTheSameClient()` A check to see if the verification was verified from the same client as the parent sign-in or sign-up attempt. For example, checking if the verification was verified from the same browser as the parent sign-in or sign-up attempt. ```typescript function verifiedFromTheSameClient(): boolean ``` --- title: UserOrganizationInvitation description: The UserOrganizationInvitation object is the model around a user's invitation to an Organization. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/user-organization-invitation lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/user-organization-invitation.mdx --- The `UserOrganizationInvitation` object is the model around a user's invitation to an Organization. ## Properties * `id` * `string` The unique identifier for this Organization invitation. *** * `emailAddress` * `string` The email address the invitation has been sent to. *** * `publicOrganizationData` * `{ hasImage: boolean; imageUrl: string; name: string; id: string; slug: string | null; }` The public data of the Organization. * `hasImage`: Whether the Organization has an image. * `imageUrl`: Holds the Organization logo. Compatible with Clerk's [Image Optimization](/docs/guides/development/image-optimization). * `name`: The name of the Organization. * `id`: The ID of the Organization. * `slug`: The slug of the Organization. *** * `publicMetadata` * [`UserOrganizationInvitationPublicMetadata`](/docs/reference/javascript/types/metadata#user-organization-invitation-public-metadata) The public metadata of the Organization invitation. *** * `role` * [`OrganizationCustomRoleKey`](/docs/reference/javascript/types/organization-custom-role-key) The [Role](/docs/guides/organizations/roles-and-permissions) of the current user in the Organization. *** * `status` * `'pending' | 'accepted' | 'revoked'` The status of the invitation. *** * `createdAt` * `Date` The date when the invitation was created. *** * `updatedAt` * `Date` The date when the invitation was last updated. ## Methods ### `accept()` Accepts the invitation to the Organization. ```typescript function accept(): Promise ``` ### Example To see an example of how to use the `accept()` method, see the [custom flow guide for managing invitations](/docs/guides/development/custom-flows/organizations/manage-user-org-invitations). --- title: Web3Wallet description: The Web3Wallet object describes a Web3 wallet address. The address can be used as a proof of identification for users. sdk: js-frontend sdkScoped: "true" canonical: /docs/reference/javascript/types/web3-wallet lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: js-frontend notAvailableSdks: nextjs,react,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: js-frontend sourceFile: /docs/reference/javascript/types/web3-wallet.mdx --- The `Web3Wallet` object describes a Web3 wallet address. The address can be used as a proof of identification for users. Web3 addresses must be verified to ensure that they can be assigned to their rightful owners. The verification is completed via Web3 wallet browser extensions, such as [Metamask](https://metamask.io/), [Coinbase Wallet](https://www.coinbase.com/wallet), and [OKX Wallet](https://www.okx.com/help/section/faq-web3-wallet). The `Web3Wallet` object holds all the necessary state around the verification process. The verification process always starts with the [`Web3Wallet.prepareVerification()`](/docs/reference/javascript/types/web3-wallet#prepare-verification) or [`signIn.prepareFirstFactor()`](/docs/reference/javascript/sign-in#prepare-first-factor) method, which will send the wallet address to Clerk's [Frontend API](/docs/reference/frontend-api){{ target: '_blank' }} and will receive a nonce that needs to be signed by the Web3 wallet browser extension. A signature is generated from the nonce and is returned in the `Verification.message` property of the returned `Web3Wallet` object. The second and final step involves an attempt to complete the verification by calling [`Web3Wallet.attemptVerification()`](/docs/reference/javascript/types/web3-wallet#attempt-verification) method, passing the signature that was generated from the `prepareVerification()`method as a parameter. ## Properties * `id` * `string` The unique ID for the Web3 wallet. *** * `web3Wallet` * `string` The Web3 wallet address, made up of 0x + 40 hexadecimal characters. *** * `verification` * [`Verification`](/docs/reference/javascript/types/verification) An object holding information on the verification of this Web3 wallet. ## Methods ### `create()` Creates a new Web3 wallet. ```typescript function create(): Promise ``` ### `destroy()` Deletes this Web3 wallet. ```typescript function destroy(): Promise ``` ### `toString()` Returns the `web3Wallet` hexadecimal string. ```typescript function toString(): string ``` ## `prepareVerification()` Starts the verification process for the Web3 wallet. The user will be prompted to sign a generated nonce by the browser extension. Returns a `Web3Wallet` object **with the signature in the `Verification.message` property.** The signature should then be passed to the [`attemptVerification()`](#attempt-verification) method. ```typescript function prepareVerification(params: PrepareWeb3WalletVerificationParams): Promise ``` ### `PrepareWeb3WalletVerificationParams` * `strategy` * `'web3_base_signature'` | `'web3_metamask_signature'` | `'web3_coinbase_wallet_signature'` | `'web3_okx_wallet_signature'` The verification strategy to validate the user's sign-up request. The following strategies are supported: * `'web3_base_signature'`: User will need to sign a message and generate a signature using Base. * `'web3_metamask_signature'`: User will need to sign a message and generate a signature using MetaMask browser extension. * `'web3_coinbase_wallet_signature'`: User will need to sign a message and generate a signature using Coinbase Wallet. * `'web3_okx_wallet_signature'`: User will need to sign a message and generate a signature using OKX Wallet. ## `attemptVerification()` Attempts to verify the Web3 wallet by passing the signature generated from the [`prepareVerification()`](#prepare-verification) method. Returns a `Web3Wallet` object. ```typescript function attemptVerification(params: AttemptWeb3WalletVerificationParams): Promise ``` ### `AttemptWeb3WalletVerificationParams` * `signature` * `string` The signature generated from calling the [`prepareVerification()`](#prepare-verification) method. --- title: Clerk React SDK description: The Clerk React SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. sdk: react sdkScoped: "true" canonical: /docs/reference/react/overview lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: react notAvailableSdks: nextjs,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: react sourceFile: /docs/reference/react/overview.mdx --- The Clerk React SDK is built on top of the JavaScript SDK and gives you access to prebuilt components, hooks, and helpers to make user authentication easier. Refer to the [quickstart guide](/docs/react/getting-started/quickstart) to get started. ## Custom hooks The React SDK provides hooks that include access to the Clerk object, User object, Organization object, and a set of useful helper methods for signing in and signing up. * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() ## Framework-specific SDKs > \[!IMPORTANT] > Clerk provides optimized SDKs for specific React frameworks. If you're using one of the supported frameworks below, you should use its dedicated SDK instead of `@clerk/clerk-react`. Clerk offers framework-specific SDKs that are customized to provide the better developer experience and integration with each framework's features. Choose the appropriate SDK based on your framework: | Framework | Package | Docs | | - | - | - | | Next.js | `@clerk/nextjs` | Next.js SDK | | React Router | `@clerk/react-router` | React Router SDK | | Remix | `@clerk/remix` | Remix SDK | | Astro | `@clerk/astro` | Astro SDK | | Tanstack React Start | `@clerk/tanstack-react-start` | Tanstack React Start SDK | ## Set up Clerk React Before you can add Clerk to your React application, you must create a Clerk app in the Clerk Dashboard. To get started, follow the [setup guide](/docs/getting-started/quickstart/setup-clerk). Then, follow the [quickstart guide](/docs/react/getting-started/quickstart) to set up the React SDK in your app. --- title: API Reference description: Access Clerk's frontend and backend API reference documentation. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/reference/api/overview sourceFile: /docs/reference/api/overview.mdx --- While accessing Clerk functionality via SDK is the easiest path, Clerk offers two different HTTP APIs for you to interact with directly. [The Clerk Frontend API](/docs/reference/frontend-api){{ target: '_blank' }} is meant to be accessed from a browser or native clients. This is what the Clerk SDK's utilize. Use this API if you are building client-side functionality. [The Clerk Backend API](/docs/reference/backend-api){{ target: '_blank' }} is meant to be accessed by backend servers. Use this API if you need to update data inside of Clerk's systems outside the concept of a session, like coordinating data sync operations with third-parties or fetching and updating configuration settings. For more information about how Clerk works, see the [dedicated guide](/docs/guides/how-clerk-works/overview). --- title: Use Clerk with Next.js 12 and older description: Learn how to use Clerk with older versions of Next.js. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/reference/nextjs/usage-with-older-versions sourceFile: /docs/reference/nextjs/usage-with-older-versions.mdx --- Clerk's prebuilt components are exported from the `@clerk/nextjs` package and leverage APIs from Next.js itself. These APIs often change between major Next.js releases. While Clerk tries to offer the highest compatibility for any supported Next.js version, for Next.js 12 and older, you need to modify your setup. > \[!WARNING] > Clerk highly recommends updating your Next.js version as older versions won't receive any updates in the future. Read [their upgrade guides](https://nextjs.org/docs/pages/building-your-application/upgrading) to learn more. ## Install `@clerk/nextjs` v4 Install `^4.0.0` of `@clerk/nextjs`. Newer major versions of `@clerk/nextjs` only support Next.js 13+. ```npm npm install @clerk/nextjs@^4.0.0 ``` ## Change your `next.config.js` As mentioned previously, the `@clerk/nextjs` components contain code for multiple Next.js versions, but depending on your version, only certain components will be used. Update your `next.config.js` to instruct webpack to ignore modules on code paths that won't be used. ```js {{ filename: 'next.config.js', mark: [1, [5, 12]] }} const webpack = require('webpack') /** @type {import('next').NextConfig} */ const nextConfig = { webpack(config) { config.plugins.push( new webpack.IgnorePlugin({ resourceRegExp: /^next\/(navigation|headers|compat\/router)$/, }), ) return config }, } module.exports = nextConfig ``` --- title: clerkMiddleware() | Next.js description: The clerkMiddleware() function allows you to protect your Next.js application using Middleware. sdk: nextjs sdkScoped: "true" canonical: /docs/reference/nextjs/clerk-middleware lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/nextjs/clerk-middleware.mdx --- The `clerkMiddleware()` helper integrates Clerk authentication into your Next.js application through Middleware. `clerkMiddleware()` is compatible with both the App and Pages routers. ## Configure `clerkMiddleware()` > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. Create a `proxy.ts` file at the root of your project, or in your `src/` directory if you have one. > \[!NOTE] > For more information about Middleware in Next.js, see the [Next.js documentation](https://nextjs.org/docs/app/api-reference/file-conventions/proxy). ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware } from '@clerk/nextjs/server' export default clerkMiddleware() export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` By default, `clerkMiddleware` will not protect any routes. All routes are public and you must opt-in to protection for routes. ## `createRouteMatcher()` `createRouteMatcher()` is a Clerk helper function that allows you to protect multiple routes. `createRouteMatcher()` accepts an array of routes and checks if the route the user is trying to visit matches one of the routes passed to it. The paths provided to this helper can be in the same format as the paths provided to the Next Middleware matcher. The `createRouteMatcher()` helper returns a function that, if called with the `req` object from the Middleware, will return `true` if the user is trying to access a route that matches one of the routes passed to `createRouteMatcher()`. In the following example, `createRouteMatcher()` sets all `/dashboard` and `/forum` routes as protected routes. ```tsx const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)']) ``` ## Protect routes You can protect routes using either or both of the following: * [Authentication-based protection](#protect-routes-based-on-authentication-status): Verify if the user is signed in. * [Authorization-based protection](#protect-routes-based-on-authorization-status): Verify if the user has the required Organization Roles or Custom Permissions. > \[!TIP] > If you have a `` tag on a public page that points to a protected page that returns a `400`-level error, like a `401`, the data prefetch will fail because it will be redirected to the sign-in page and throw a confusing error in the console. To prevent this behavior, disable prefetching by adding `prefetch={false}` to the `` component. ### Protect routes based on authentication status You can protect routes based on a user's authentication status by checking if the user is signed in. There are two methods that you can use: * Use [`auth.protect()`](/docs/reference/nextjs/app-router/auth#auth-protect) if you want to redirect unauthenticated users to the sign-in route automatically. * Use [`auth().isAuthenticated`](/docs/reference/nextjs/app-router/auth#protect-pages-and-routes) if you want more control over what your app does based on user authentication status. ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)']) export default clerkMiddleware(async (auth, req) => { if (isProtectedRoute(req)) await auth.protect() }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)']) export default clerkMiddleware(async (auth, req) => { const { isAuthenticated, redirectToSignIn } = await auth() if (!isAuthenticated && isProtectedRoute(req)) { // Add custom logic to run before redirecting return redirectToSignIn() } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ### Protect routes based on authorization status You can protect routes based on a user's authorization status by checking if the user has the required Roles or Permissions. There are two methods that you can use: * Use [`auth.protect()`](/docs/reference/nextjs/app-router/auth#auth-protect) if you want Clerk to return a `404` if the user does not have the Role or Permission. * Use auth().has() if you want more control over what your app does based on the authorization status. ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isProtectedRoute = createRouteMatcher(['/admin(.*)']) export default clerkMiddleware(async (auth, req) => { // Restrict admin routes to users with specific Permissions if (isProtectedRoute(req)) { await auth.protect((has) => { return has({ permission: 'org:admin:example1' }) || has({ permission: 'org:admin:example2' }) }) } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` > \[!WARNING] > Using `has()` **on the server-side** to check Permissions works only with **Custom Permissions**, as [System Permissions](/docs/guides/organizations/roles-and-permissions#system-permissions) aren't included in the session token claims. To check System Permissions, verify the user's Role instead. ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isProtectedRoute = createRouteMatcher(['/admin(.*)']) export default clerkMiddleware(async (auth, req) => { const { has, redirectToSignIn } = await auth() // Restrict admin routes to users with specific Permissions if ( (isProtectedRoute(req) && !has({ permission: 'org:admin:example1' })) || !has({ permission: 'org:admin:example2' }) ) { // Add logic to run if the user does not have the required Permissions return redirectToSignIn() } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ## Protect multiple groups of routes You can use more than one `createRouteMatcher()` in your application if you have two or more groups of routes. The following example uses the has() method from the `auth()` helper. > \[!TIP] > If you have a `` tag on a public page that points to a protected page that returns a `400`-level error, like a `401`, the data prefetch will fail because it will be redirected to the sign-in page and throw a confusing error in the console. To prevent this behavior, disable prefetching by adding `prefetch={false}` to the `` component. ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isTenantRoute = createRouteMatcher(['/organization-selector(.*)', '/orgid/(.*)']) const isTenantAdminRoute = createRouteMatcher(['/orgId/(.*)/memberships', '/orgId/(.*)/domain']) export default clerkMiddleware(async (auth, req) => { // Restrict admin routes to users with specific Permissions if (isTenantAdminRoute(req)) { await auth.protect((has) => { return has({ permission: 'org:admin:example1' }) || has({ permission: 'org:admin:example2' }) }) } // Restrict Organization routes to signed in users if (isTenantRoute(req)) await auth.protect() }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ## Protect all routes To protect all routes in your application and define specific routes as public, you can use any of the above methods and simply invert the `if` condition. > \[!TIP] > If you have a `` tag on a public page that points to a protected page that returns a `400`-level error, like a `401`, the data prefetch will fail because it will be redirected to the sign-in page and throw a confusing error in the console. To prevent this behavior, disable prefetching by adding `prefetch={false}` to the `` component. ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)']) export default clerkMiddleware(async (auth, req) => { if (!isPublicRoute(req)) { await auth.protect() } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ## Protect routes based on token types You can protect routes based on token types by checking if the request includes the required token (e.g. OAuth token, API key, machine token or session token). This ensures that only requests with the appropriate token type can access the route. The following example uses the [`protect()`](/docs/reference/nextjs/app-router/auth#auth-protect) method from the `auth()` helper. Requests without the required token will return an appropriate error: * A `404` error for unauthenticated requests with a session token type. * A `401` error for unauthenticated requests with machine token types. ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' // Create route matchers to identify which token type each route should require const isOAuthAccessible = createRouteMatcher(['/oauth(.*)']) const isApiKeyAccessible = createRouteMatcher(['/api(.*)']) const isMachineTokenAccessible = createRouteMatcher(['/m2m(.*)']) const isUserAccessible = createRouteMatcher(['/user(.*)']) const isAccessibleToAnyValidToken = createRouteMatcher(['/any(.*)']) export default clerkMiddleware(async (auth, req) => { // Check if the request matches each route and enforce the corresponding token type if (isOAuthAccessible(req)) await auth.protect({ token: 'oauth_token' }) if (isApiKeyAccessible(req)) await auth.protect({ token: 'api_key' }) if (isMachineTokenAccessible(req)) await auth.protect({ token: 'm2m_token' }) if (isUserAccessible(req)) await auth.protect({ token: 'session_token' }) if (isAccessibleToAnyValidToken(req)) await auth.protect({ token: 'any' }) }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ## Debug your Middleware If you are having issues getting your Middleware dialed in, or are trying to narrow down auth-related issues, you can use the debugging feature in `clerkMiddleware()`. Add `{ debug: true }` to `clerkMiddleware()` and you will get debug logs in your terminal. ```tsx {{ filename: 'proxy.ts', mark: [[4, 7]] }} import { clerkMiddleware } from '@clerk/nextjs/server' export default clerkMiddleware( (auth, req) => { // Add your middleware checks }, { debug: true }, ) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` If you would like to set up debugging for your development environment only, you can use the `process.env.NODE_ENV` variable to conditionally enable debugging. For example, `{ debug: process.env.NODE_ENV === 'development' }`. ## Combine Middleware You can combine other Middleware with Clerk's Middleware by returning the second Middleware from `clerkMiddleware()`. ```js {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' import createMiddleware from 'next-intl/middleware' import { AppConfig } from './utils/AppConfig' const intlMiddleware = createMiddleware({ locales: AppConfig.locales, localePrefix: AppConfig.localePrefix, defaultLocale: AppConfig.defaultLocale, }) const isProtectedRoute = createRouteMatcher(['dashboard/(.*)']) export default clerkMiddleware(async (auth, req) => { if (isProtectedRoute(req)) await auth.protect() return intlMiddleware(req) }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ## `clerkMiddleware()` options The `clerkMiddleware()` 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']` *** * `clockSkewInMs?` * `number` Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to 5000 ms (5 seconds). *** * `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/~/api-keys) page in the Clerk Dashboard. **It's recommended to use [the environment variable](/docs/guides/development/clerk-environment-variables) instead.** For more information, refer to [Manual JWT verification](/docs/guides/sessions/manual-jwt-verification). *** * `organizationSyncOptions?` * [OrganizationSyncOptions](#organization-sync-options) | undefined Used to activate a specific [Organization](/docs/guides/organizations/overview) or [Personal Account](/docs/guides/dashboard/overview) based on URL path parameters. If there's a mismatch between the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. in the session (e.g., as reported by [`auth()`](/docs/reference/nextjs/app-router/auth)) and the Organization indicated by the URL, the middleware will attempt to activate the Organization specified in the URL. *** * `proxyUrl?` * `string` Specify the URL of the proxy, if using a proxy. *** * `signInUrl` * `string` The full URL or path to your sign-in page. Needs to point to your primary application on the client-side. **Required 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` The full URL or path to your sign-up page. Needs to point to your primary application on the client-side. **Required 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. *** * `publishableKey` * `string` The Clerk Publishable Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. *** * `secretKey?` * `string` The Clerk Secret Key for your instance. This can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. The `CLERK_ENCRYPTION_KEY` environment variable must be set when providing `secretKey` as an option, refer to [Dynamic keys](#dynamic-keys). It's also possible to dynamically set options based on the incoming request: ```ts {{ filename: 'proxy.ts' }} import { clerkMiddleware } from '@clerk/nextjs/server' export default clerkMiddleware( (auth, req) => { // Add your middleware checks }, (req) => ({ // Provide `domain` based on the request host domain: req.nextUrl.host, }), ) ``` ### Dynamic keys > \[!NOTE] > Dynamic keys are not accessible on the client-side. The following options, known as "Dynamic Keys," are shared to the Next.js application server through `clerkMiddleware`, enabling access by server-side helpers like [`auth()`](/docs/reference/nextjs/app-router/auth): * `signUpUrl` * `signInUrl` * `secretKey` * `publishableKey` Dynamic keys are encrypted and shared during request time using a [AES encryption algorithm](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard). When providing a `secretKey`, the `CLERK_ENCRYPTION_KEY` environment variable is mandatory and used as the encryption key. If no `secretKey` is provided to `clerkMiddleware`, the encryption key defaults to `CLERK_SECRET_KEY`. When providing `CLERK_ENCRYPTION_KEY`, it is recommended to use a 32-byte (256-bit), pseudorandom value. You can use `openssl` to generate a key: ```sh {{ filename: 'terminal' }} openssl rand --hex 32 ``` For multi-tenant applications, you can dynamically define Clerk keys depending on the incoming request. Here's an example: ```ts {{ filename: 'proxy.ts' }} import { clerkMiddleware } from '@clerk/nextjs/server' // You would typically fetch these keys from a external store or environment variables. const tenantKeys = { tenant1: { publishableKey: 'pk_tenant1...', secretKey: 'sk_tenant1...' }, tenant2: { publishableKey: 'pk_tenant2...', secretKey: 'sk_tenant2...' }, } export default clerkMiddleware( (auth, req) => { // Add your middleware checks }, (req) => { // Resolve tenant based on the request const tenant = getTenant(req) return tenantKeys[tenant] }, ) ``` ### `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 Organization 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 OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the 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 \. 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` | ❌ | --- title: Clerk Next.js SDK description: The Clerk Next.js SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. sdk: nextjs sdkScoped: "true" canonical: /docs/reference/nextjs/overview lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/nextjs/overview.mdx --- The Clerk Next.js SDK gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Refer to the quickstart guide to get started. ## `clerkMiddleware()` The `clerkMiddleware()` helper integrates Clerk authentication into your Next.js application through middleware. It allows you to integrate authorization into both the client and server of your application. You can learn more [here](/docs/reference/nextjs/clerk-middleware). ## Client-side helpers Because the Next.js SDK is built on top of the Clerk React SDK, you can use the hooks that the React SDK provides. These hooks include access to the Clerk object, User object, Organization object, and a set of useful helper methods for signing in and signing up. * useUser() * useClerk() * useAuth() * useSignIn() * useSignUp() * useSession() * useSessionList() * useOrganization() * useOrganizationList() * useReverification() * useCheckout() * usePaymentElement() * usePaymentMethods() * usePlans() * useSubscription() * useStatements() * usePaymentAttempts() ## Server-side helpers ### App router Clerk provides first-class support for the [Next.js App Router](https://nextjs.org/docs/app). The following references show how to integrate Clerk features into apps using the latest App Router and React Server Components features. * [`auth()`](/docs/reference/nextjs/app-router/auth) * [`currentUser()`](/docs/reference/nextjs/app-router/current-user) * [Route Handlers](/docs/reference/nextjs/app-router/route-handlers) * [Server Actions](/docs/reference/nextjs/app-router/server-actions) ### Pages router Clerk continues to provide drop-in support for the Next.js Pages Router. In addition to the main Clerk integration, the following references are available for apps using Pages Router. * [`getAuth()`](/docs/reference/nextjs/pages-router/get-auth) * [`buildClerkProps()`](/docs/reference/nextjs/pages-router/build-clerk-props) ## `clerkClient` Clerk's JS Backend SDK provides access to Backend API resources and low-level authentication utilities for JavaScript environments. For example, to retrieve a list of all users in your application, you can use the `users.getUserList()` method from the JS Backend SDK instead of manually making a fetch request to the [https://api.clerk.com/v1/users](https://clerk.com/docs/reference/backend-api/tag/users/get/users) endpoint. All resource operations are mounted as sub-APIs on the `clerkClient` object. See the reference documentation for more information. ## `Auth` object Both `auth()` (App Router) and `getAuth()` (Pages Router) return an `Auth` object. This JavaScript object contains important information like the current user's session ID, user ID, and Organization ID. Learn more about the Auth object{{ target: '_blank' }}. ## Demo repositories For examples of Clerk's features, such as user and Organization management, integrated into a single application, see the Next.js demo repositories: * [Clerk + Next.js App Router Demo](https://github.com/clerk/clerk-nextjs-demo-app-router) * [Clerk + Next.js Pages Router Demo](https://github.com/clerk/clerk-nextjs-demo-pages-router) --- title: "`buildClerkProps`" description: Clerk uses buildClerkProps to inform the client-side helpers of the authentication state of the user. This function is used SSR in the getServerSideProps function of your Next.js application. sdk: nextjs sdkScoped: "true" canonical: /docs/reference/nextjs/pages-router/build-clerk-props lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/nextjs/pages-router/build-clerk-props.mdx --- The `buildClerkProps()` function is used in your Next.js application's `getServerSideProps` to pass authentication state from the server to the client. It returns props that get spread into the `` component. This enables Clerk's client-side helpers, such as `useAuth()`, to correctly determine the user's authentication status during server-side rendering. ```tsx {{ filename: 'pages/example.tsx' }} import { getAuth, buildClerkProps } from '@clerk/nextjs/server' import { GetServerSideProps } from 'next' export const getServerSideProps: GetServerSideProps = async (ctx) => { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(ctx.req) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return { redirect: { destination: '/sign-in', permanent: false, }, } } // Initialize the JS Backend SDK const client = await clerkClient() // Get the user's full `Backend User` object const user = await client.users.getUser(userId) // Pass the `user` object to buildClerkProps() return { props: { ...buildClerkProps(ctx.req, { user }) } } } ``` --- title: "`getAuth()`" description: The getAuth() helper retrieves authentication state from the request object. sdk: nextjs sdkScoped: "true" canonical: /docs/reference/nextjs/pages-router/get-auth lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/nextjs/pages-router/get-auth.mdx --- The `getAuth()` helper retrieves authentication state from the request object. > \[!NOTE] > If you are using App Router, use the [`auth()` helper](/docs/reference/nextjs/app-router/auth) instead. ## Parameters * `req` The Next.js request object. *** * `opts?` An optional object that can be used to configure the behavior of the `getAuth()` function. It accepts the following properties: * `secretKey?`: A string that represents the Secret Key used to sign the session token. If not provided, the Secret Key is retrieved from the environment variable `CLERK_SECRET_KEY`. ## Returns `getAuth()` returns the `Auth` object. See the Auth reference for more information. ## Usage The following example uses `getAuth()` to protect a route and load the user's data. If the user is authenticated, their `userId` is passed to clerkClient.users.getUser(){{ target: '_blank' }} to get the current user's User{{ target: '_blank' }} object. If not authenticated, the request is rejected with a `401` status code. See more detailed examples in the dedicated guide. ```tsx {{ filename: 'pages/api/auth.ts' }} import { getAuth, clerkClient } from '@clerk/nextjs/server' import type { NextApiRequest, NextApiResponse } from 'next' export default async function handler(req: NextApiRequest, res: NextApiResponse) { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(req) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return res.status(401).json({ error: 'Unauthorized' }) } // Initialize the JS Backend SDK const client = await clerkClient() // Get the user's full Backend User object const user = await client.users.getUser(userId) return res.status(200).json({ user }) } ``` --- title: "`auth()`" description: Access minimal authentication data for managing sessions and data fetching. sdk: nextjs sdkScoped: "true" canonical: /docs/reference/nextjs/app-router/auth lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/nextjs/app-router/auth.mdx --- The `auth()` helper returns the Auth{{ target: '_blank' }} object of the currently active user, as well as the [`redirectToSignIn()`](#redirect-to-sign-in) method. It includes a single method, `protect()`, which you can use to check if a user is authenticated or authorized to access certain parts of your application or even entire routes. * Only available for App Router. * Only works on the server-side, such as in Server Components, Route Handlers, and Server Actions. * Requires [`clerkMiddleware()`](/docs/reference/nextjs/clerk-middleware) to be configured. ## Parameters * `opts?` * `{acceptsToken: TokenType, treatPendingAsSignedOut: boolean }` An optional object that can be used to configure the behavior of the `auth()` function. It accepts the following properties: * `acceptsToken?`: The type of authentication token(s) to accept. Valid values are: * `'session_token'` - authenticates a user session. * `'oauth_token'` - authenticates a machine request using OAuth. * `'m2m_token'` - authenticates a machine to machine request. * `'api_key'` - authenticates a machine request using API keys. Can be set to: * A single token type. * An array of token types. * `'any'` to accept all available token types. Defaults to `'session_token'`. * `treatPendingAsSignedOut?`: A boolean that indicates whether to treat pending session status as signed out. Defaults to `true`. ## `auth.protect()` `auth` includes a single property, the `protect()` method, which you can use in three ways: * to check if a user is authenticated (signed in) * to check if a user is authorized (has the correct Role, Permission, Feature, or Plan) to access something, such as a component or a route handler * to check if a request includes a valid machine token (e.g. API key or OAuth token) and enforce access rules accordingly The following table describes how `auth.protect()` behaves based on user authentication or authorization status: | Authenticated | Authorized | `auth.protect()` will | | - | - | - | | Yes | Yes | Return the Auth{{ target: '_blank' }} object. | | Yes | No | Return a `404` error. | | No | No | Redirect the user to the sign-in page\*\*. | > \[!IMPORTANT] > For non-document requests, such as API requests, `auth.protect()` returns: > > * A `404` error for unauthenticated requests with session token type. > * A `401` error for unauthenticated requests with machine token types. `auth.protect()` accepts the following parameters: * `role?` * `string` The Role to check for. *** * `permission?` * `string` The Permission to check for. *** * `has?` * `(isAuthorizedParams: CheckAuthorizationParamsWithCustomPermissions) => boolean` A function that checks if the user has an Organization Role or Custom Permission. See the reference for more information. *** * `unauthorizedUrl?` * `string` The URL to redirect the user to if they are not authorized. *** * `unauthenticatedUrl?` * `string` The URL to redirect the user to if they are not authenticated. *** * `token?` * `TokenType` The type of authentication token(s) to accept. Valid values are: * `'session_token'` - authenticates a user session. * `'oauth_token'` - authenticates a machine request using OAuth. * `'machine_token'` - authenticates a machine to machine request. * `'api_key'` - authenticates a machine request using API keys. Can be set to: * A single token type. * An array of token types. * `'any'` to accept all available token types. Defaults to `'session_token'`. ### Example `auth.protect()` can be used to check if a user is authenticated or authorized to access certain parts of your application or even entire routes. See detailed examples in the [guide on verifying if a user is authorized](/docs/guides/secure/authorization-checks). ## Returns The `auth()` helper returns the following: * The Auth{{ target: '_blank' }} object. * The [`redirectToSignIn()`](#redirect-to-sign-in) method. ### `redirectToSignIn()` The `auth()` helper returns the `redirectToSignIn()` method, which you can use to redirect the user to the sign-in page. `redirectToSignIn()` accepts the following parameters: * `returnBackUrl?` * `string | URL` The URL to redirect the user back to after they sign in. > \[!NOTE] > `auth()` on the server-side can only access redirect URLs defined via [environment variables](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects) or [`clerkMiddleware` dynamic keys](/docs/reference/nextjs/clerk-middleware#dynamic-keys). #### Example The following example shows how to use `redirectToSignIn()` to redirect the user to the sign-in page if they are not authenticated. It's also common to use `redirectToSignIn()` in `clerkMiddleware()` to protect entire routes; see [the `clerkMiddleware()` docs](/docs/reference/nextjs/clerk-middleware) for more information. ```tsx {{ filename: 'app/page.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function Page() { const { isAuthenticated, redirectToSignIn, userId } = await auth() if (!isAuthenticated) return redirectToSignIn() return

Hello, {userId}

} ``` ## `auth()` usage ### Protect pages and routes You can use `auth()` to check if `isAuthenticated` is true. If it's false, then there is not an authenticated (signed in) user. See detailed examples in the dedicated guide. ### Check if a user is authorized You can use `auth()` to check if a user is authorized to access certain parts of your application or even entire routes by checking their type of access control. See detailed examples in the [guide on verifying if a user is authorized](/docs/guides/secure/authorization-checks). ### Verify machine requests You can use `auth()` to verify OAuth access tokens by passing in the `acceptsToken` parameter. See detailed examples in the guide on verifying OAuth access tokens. ### Data fetching with `getToken()` If you need to send a JWT along to a server, `getToken()` retrieves the current user's [session token](/docs/guides/sessions/session-tokens) or a [custom JWT template](/docs/guides/sessions/jwt-templates). See detailed examples in the Auth object reference{{ target: '_blank' }}. --- title: Route Handlers description: Learn how to use Clerk with your Route Handlers. sdk: nextjs sdkScoped: "true" canonical: /docs/reference/nextjs/app-router/route-handlers lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/nextjs/app-router/route-handlers.mdx --- Clerk provides helpers that allow you to protect your Route Handlers, fetch the current user, and interact with the Clerk Backend API. > \[!TIP] > If you have a `` tag on a public page that points to a protected page that returns a `400`-level error, like a `401`, the data prefetch will fail because it will be redirected to the sign-in page and throw a confusing error in the console. To prevent this behavior, disable prefetching by adding `prefetch={false}` to the `` component. ## Protect your Route Handlers If you aren't protecting your Route Handler using [`clerkMiddleware()`](/docs/reference/nextjs/clerk-middleware), you can protect your Route Handler in two ways: * Use [`auth.protect()`](/docs/reference/nextjs/app-router/auth#auth-protect) if you want Clerk to return a `404` error when there is no signed in user. * Use [`auth().userId`](/docs/reference/nextjs/app-router/auth#protect-pages-and-routes) if you want to customize the behavior or error message. ```tsx {{ filename: 'app/api/route.ts' }} import { auth } from '@clerk/nextjs/server' export async function GET() { // If there is no signed in user, this will return a 404 error await auth.protect() // Add your Route Handler logic here return Response.json({ message: 'Hello world!' }) } ``` ```tsx {{ filename: 'app/api/route.ts' }} import { auth } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function GET() { const { isAuthenticated, userId } = await auth() if (!isAuthenticated) { return NextResponse.json({ error: 'Error: No signed in user' }, { status: 401 }) } // Add your Route Handler logic here return NextResponse.json({ userId }) } ``` ## Retrieve data from external sources Clerk provides integrations with a number of popular databases. The following example demonstrates how to use auth().getToken() to retrieve a token from a JWT template and use it to fetch data from the external source. ```ts {{ filename: 'app/api/route.ts' }} import { NextResponse } from 'next/server' import { auth } from '@clerk/nextjs/server' export async function GET() { const { isAuthenticated, getToken } = await auth() if (!isAuthenticated) { return new Response('Unauthorized', { status: 401 }) } const token = await getToken({ template: 'supabase' }) // Fetch data from Supabase and return it. const data = { supabaseData: 'Hello World' } return NextResponse.json({ data }) } ``` ## Retrieve the current user To retrieve information about the current user in your Route Handler, you can use the [`currentUser()`](/docs/reference/nextjs/app-router/current-user) helper, which returns the Backend User object of the currently active user. **It does count towards the [Backend API request rate limit](/docs/guides/how-clerk-works/system-limits)** so it's recommended to use the useUser() hook on the client side when possible and only use `currentUser()` when you specifically need user data in a server context. For more information on this helper, see the [`currentUser()`](/docs/reference/nextjs/app-router/current-user) reference. > \[!WARNING] > The Backend User object includes a `privateMetadata` field that should not be exposed to the frontend. Avoid passing the full user object returned by `currentUser()` to the frontend. Instead, pass only the specified fields you need. ```ts {{ filename: 'app/api/route.ts' }} import { NextResponse } from 'next/server' import { currentUser } from '@clerk/nextjs/server' export async function GET() { const { isAuthenticated } = await auth() const user = await currentUser() if (!isAuthenticated) { return new Response('Unauthorized', { status: 401 }) } return NextResponse.json({ userId: user.id, email: user.emailAddresses[0].emailAddress }) } ``` ## Interact with Clerk's Backend API The JS Backend SDK exposes the [Backend API](/docs/reference/backend-api){{ target: '_blank' }} resources and low-level authentication utilities for JavaScript environments. `clerkClient` exposes an instance of the JS Backend SDK for use in server environments. ```ts {{ filename: 'app/api/route.ts' }} import { NextResponse, NextRequest } from 'next/server' import { auth, clerkClient } from '@clerk/nextjs/server' export async function POST(req: NextRequest) { const { isAuthenticated, userId } = await auth() if (!isAuthenticated) return NextResponse.redirect(new URL('/sign-in', req.url)) const params = { firstName: 'John', lastName: 'Wick' } const client = await clerkClient() const user = await client.users.updateUser(userId, params) return NextResponse.json({ user }) } ``` --- title: "`currentUser()`" description: Use the currentUser() helper to access information about your user inside of your Server Components, Route Handlers, and Server Actions. sdk: nextjs sdkScoped: "true" canonical: /docs/reference/nextjs/app-router/current-user lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/nextjs/app-router/current-user.mdx --- > \[!WARNING] > For optimal performance and to avoid rate limiting, it's recommended to use the useUser() hook on the client-side when possible. Only use `currentUser()` when you specifically need user data in a server context. The `currentUser()` helper returns the Backend User object of the currently active user. It can be used in Server Components, Route Handlers, and Server Actions. Under the hood, this helper: * calls `fetch()`, so it is automatically deduped per request. * uses the [`GET /v1/users/{user_id}`](/docs/reference/backend-api/tag/users/get/users/\{user_id}){{ target: '_blank' }} endpoint. * counts towards the [Backend API request rate limit](/docs/guides/how-clerk-works/system-limits). > \[!WARNING] > The Backend User object includes a `privateMetadata` field that should not be exposed to the frontend. Avoid passing the full user object returned by `currentUser()` to the frontend. Instead, pass only the specified fields you need. ```tsx {{ filename: 'app/page.tsx' }} import { currentUser } from '@clerk/nextjs/server' export default async function Page() { const user = await currentUser() if (!user) return
Not signed in
return
Hello {user?.firstName}
} ``` --- title: Server Actions description: Learn how to use Clerk with Server Actions. sdk: nextjs sdkScoped: "true" canonical: /docs/reference/nextjs/app-router/server-actions lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/reference/nextjs/app-router/server-actions.mdx --- Clerk provides helpers that are specific for server-side usage. The following guide provides examples for using these helpers with Server Actions in Server Components and in Client Components. ## With Server Components ### Protect your Server Actions You can use the `isAuthenticated` property from the [`auth()`](/docs/reference/nextjs/app-router/auth) helper to protect your Server Actions. If `isAuthenticated` is `false`, then the user is not signed in. ```tsx {{ filename: 'actions.ts' }} import { auth } from '@clerk/nextjs/server' export default function AddToCart() { async function addItem(formData: FormData) { 'use server' const { isAuthenticated } = await auth() if (!isAuthenticated) { throw new Error('You must be signed in to add an item to your cart') } console.log('add item server action', formData) } return (
) } ``` When performing Organization-related operations, you can use `auth().orgId` to check a user's Organization ID before performing an action. ```tsx {{ filename: 'actions.ts' }} import { auth } from '@clerk/nextjs/server' export default function AddVerifiedDomain() { async function addVerifiedDomain(formData: FormData) { 'use server' const { isAuthenticated, orgId } = await auth() if (!isAuthenticated) { throw new Error('You must be signed in to add a verified domain') } if (!orgId) { throw new Error('No Active Organization found. Set one as active or create/join one') } const domain = formData.get('domain')?.toString() if (!domain) { throw new Error('Domain is required') } await clerkClient().organizations.createOrganizationDomain({ organizationId: orgId, name: domain, enrollmentMode: 'automatic_invitation', }) console.log(`Added domain ${domain} to Organization ${orgId}`) } return (
) } ``` For more examples on how to use the `auth()` helper, see the [`auth()`](/docs/reference/nextjs/app-router/auth) reference. ### Read user data To retrieve information about the current user in your Server Actions, you can use the [`currentUser()`](/docs/reference/nextjs/app-router/current-user) helper, which returns the Backend User object of the currently active user. **It does count towards the [Backend API request rate limit](/docs/guides/how-clerk-works/system-limits)** so it's recommended to use the useUser() hook on the client-side when possible and only use `currentUser()` when you specifically need user data in a server context. For more information on this helper, see the [`currentUser()`](/docs/reference/nextjs/app-router/current-user) reference. ```tsx {{ filename: 'app/page.tsx' }} import { auth, currentUser } from '@clerk/nextjs/server' export default function AddHobby() { async function addHobby(formData: FormData) { 'use server' const { isAuthenticated } = await auth() const user = await currentUser() if (!isAuthenticated) { throw new Error('You must be signed in to use this feature') } const serverData = { usersHobby: formData.get('hobby'), userId: user.id, profileImage: user.imageUrl, } console.log('add item server action completed with user details ', serverData) } return (
) } ``` ## With Client Components When you define a Server Action inside a Client Component, the request headers are not available by default because Client Components run in the browser and headers are only available in a server-side context. This is an issue for Clerk's server-side helpers, like `auth()` and `currentUser()`, as they require the request headers to be available in order to work. So if you are using these helpers in a Server Action that's being called inside a Client Component, you need to **pass the Server Action as a prop** to the Client Component. The following example demonstrates the flow of data from the Server Action being passed to the Client Component, and the Client Component being used on a page. Use the tabs to view the example code for each file. ```tsx {{ filename: 'app/actions.ts' }} 'use server' import { auth, currentUser } from '@clerk/nextjs/server' export async function addHobby(formData: FormData) { const { isAuthenticated } = await auth() const user = await currentUser() if (!isAuthenticated) { throw new Error('You must be signed in to use this feature') } const serverData = { usersHobby: formData.get('hobby'), userId: user.id, profileImage: user.imageUrl, } console.log('add Hobby completed with user details ', serverData) } ``` ```tsx {{ filename: 'app/components/AddHobby.tsx' }} 'use client' export default function UI({ addHobby }) { return (
) } ``` ```tsx {{ filename: 'app/page.tsx' }} import AddHobby from './components/AddHobby' import { addHobby } from './actions' export default function Hobby() { return } ```
--- title: "Clerk: auth() was called but Clerk can't detect usage of clerkMiddleware()" description: Learn how to handle auth() was called but Clerk can't detect usage of clerkMiddleware() when getting 404 errors in Next.js. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/reference/nextjs/errors/auth-was-called sourceFile: /docs/reference/nextjs/errors/auth-was-called.mdx --- This error occurs when a request that is not covered by `clerkMiddleware()` gets a 404 return in a Clerk + Next.js App Router setup. ## Why this error occurs This error commonly appears when using Clerk with Next.js and the clerkMiddleware() helper is configured *not* to run on static asset routes, which is part of the default setup. It can happen for the following reasons: * [Missing ``](#missing-clerk-provider): The `` is not wrapped around the component tree where Clerk components are used. * [Incorrect path](#incorrect-path): A typo or incorrect path is used in a static asset request. ### Missing `` The most common cause of this error is when auth() is called **without** a \ wrapping the component tree where Clerk components are used. The \ component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with `` to make authentication globally accessible. See the reference docs for other configuration options. #### Solution Ensure that `` is set up at a higher level in your component hierarchy than any Clerk components like \, \, or others. [The Next.js quickstart](https://clerk.com/docs/quickstarts/nextjs) shows how you can do this in your root layout. ```tsx {{ filename: 'app/layout.tsx' }} import { ClerkProvider } from '@clerk/nextjs' import './globals.css' export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { return ( {children} ) } ``` ### Incorrect path If `` is correctly configured, it's possible this error is happening because when `auth()` was called, `clerkMiddleware()` didn't run on the request. This can occur if a request is made to a **non-existent static asset.** Static asset requests are excluded by the matcher Clerk provides and often from other `proxy.ts` matchers, so `clerkMiddleware()` doesn't run for them. A typo or incorrect path is usually the problem in these cases. For example, 1. A user accesses `/dashboard`, which is a **valid page and matched route**. 2. That page includes an `` tag with a `src` pointing to an invalid path. 3. A 404 error is triggered because of the invalid static asset request. 4. Next.js serves the 404 response. 5. The 404 page is rendered **within the root layout** — that's where Next.js injects their 404 page/component. 6. Since `` is usually placed in the root layout, it runs, but because the request didn't match the middleware matcher, `clerkMiddleware()` never executed. As a result, `` attempts to call `auth()` **without context**, leading to one of these outcomes: * A `500` or `404` error in your browser's network tab. * `GET /{non-existing-path}.{static-asset-extension} 500 | 404` in your terminal or logs. * The following Clerk error in the console: ```text x [Error: Clerk: auth() was called but Clerk can't detect usage of clerkMiddleware(). Please ensure the following: Your Middleware exists at ./src/middleware.(ts|js) clerkMiddleware() is used in your Next.js Middleware. Your Middleware matcher is configured to match this route or page. If you are using the src directory, make sure the Middleware file is inside of it. For more details, see https://clerk.com/docs/quickstarts/nextjs ] { digest: '3346914516' } ``` #### Solution Select the appropriate solution based on your use case: to a sub-layout"]}> The ideal solution is to fix any incorrect asset paths, as this is the **root cause** of the error and the cleanest fix. Ensure that all images, icons, or files are requested using valid URLs. When these requests succeed, no 404 is triggered, and the Clerk provider context works as expected. This fix will prevent *the Clerk error*, as it moves `` from the root layout. However, it does not resolve the underlying issue, which is a reference to a missing static asset. Your app will still have a 404 network request for the missing asset. If you want to protect your app against similar issues in the future or want to ensure that system-level errors (like 404s) don't rely on Clerk, you can refactor your layout structure. By moving `` into a subfolder layout, you allow 404 pages and other global error routes to render without needing Clerk's context. **Before** ```bash app/ layout.ts // includes ``` **After** ```bash app/ layout.ts // base layout without Clerk (in-app) // virtual folder - doesn't impact routing layout.ts // includes page.tsx ``` Here's an example of what the new Clerk layout would look like in this case: ```tsx {{ filename: 'app/(in-app)/layout.tsx' }} import { ClerkProvider } from '@clerk/nextjs' export default function AppLayout({ children }: { children: React.ReactNode }) { return {children} } ``` Or loading Clerk built-in components: ```tsx {{ filename: 'app/(in-app)/layout.tsx' }} import { ClerkProvider, SignedIn, SignedOut, SignInButton, SignUpButton, UserButton, } from '@clerk/nextjs' export default function AppLayout({ children }: { children: React.ReactNode }) { return (
{children}
) } ``` This ensures the root layout (which handles top-level errors like 404s) does not rely on Clerk, avoiding the middleware mismatch error entirely.
--- title: Clerk guides description: Guides covering how to build or work with parts of Clerk lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/overview sourceFile: /docs/guides/overview.mdx --- Clerk offers a variety of guides to help you build and work with Clerk. These guides cover a broad range of topics, from authentication flows and user management to security, billing and deployment. This overview will help you quickly find the right guide for your needs, whether you're just getting started or looking to implement advanced features. * [Authentication flows](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) * Implement and customize authentication for your application. From basic sign-up/sign-in to social providers, enterprise connections, and Web3 wallets. * {} *** * [User management](/docs/guides/users/managing) * Manage users securely, including invitations, profile updates, data extensions, and impersonation. * {} *** * [Session management](/docs/guides/sessions/session-tokens) * Manage session tokens, including creating, verifying, customizing, and revoking sessions. Includes JWT templates, manual verification, and token refresh best practices. * {} *** * [Customizing Clerk](/docs/guides/customizing-clerk/appearance-prop/overview) * Customize Clerk's UI components, email templates, and other aspects of the user experience to match your application's branding and user interface. * {} ## Beyond the basics * [Securing your application](/docs/guides/secure/authorization-checks) * Enhance the security of your application with access control, authorization checks, session options, MFA, password policies, bot protection, and compliance tools. * {} *** * [Organizations (B2B)](/docs/guides/organizations/overview) * Manage Organizations with Verified Domains, Roles and Permissions, invitations, Enterprise SSO, and Organization metadata for scalable B2B workflows. * {} *** * [Billing](/docs/guides/billing/overview) * Set up and manage Billing for B2C and B2B applications, including free trials, Subscription Plans, payments, and webhook events. * {} *** * [Development](/docs/guides/development/clerk-environment-variables) * Build and maintain your app with environment management, custom auth flows, third-party integrations, testing, deployment, and API requests. * {} *** * [Clerk Dashboard](/docs/guides/dashboard/overview) * Configure your instance, manage settings, and monitor usage from the Clerk Dashboard. * {} *** * [How Clerk works](/docs/guides/how-clerk-works/overview) * Understand the underlying concepts and technologies that power Clerk, including authentication protocols, token management, and security practices. * {} --- title: User metadata description: Learn how to store information about a user that Clerk doesn't collect and extend the User object. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/users/extending sourceFile: /docs/guides/users/extending.mdx --- To store information about a user that Clerk doesn't collect, you can use metadata, which will get stored on the user's User object. ## Types of metadata There are three types of metadata: "public", "private", and "unsafe". | Metadata | Frontend API | Backend API | | - | - | - | | Public | Read access | Read & write access | | Private | No read or write access | Read & write access | | Unsafe | Read & write access | Read & write access | > \[!WARNING] > Metadata is limited to **8KB** maximum. If you're storing metadata as a custom claim in the session token, it's highly recommended to keep it under **1.2KB**. [Learn more about the session token size limitations](/docs/guides/sessions/session-tokens#size-limitations). > > If you use Clerk metadata and modify it server-side, the changes won't appear in the session token until the next refresh. To avoid race conditions, either [force a JWT refresh](/docs/guides/sessions/force-token-refresh) after metadata changes or handle the delay in your application logic. ### Public metadata Public metadata can be read by both the frontend and the backend, but can only be set on the backend. This is useful for storing data that you want to expose to the frontend, but don't want the user to be able to modify. For example, you could store a user's birthday. #### Access public metadata To access public metadata on the frontend, it's available on the User object, which can be accessed using the useUser() hook. To access public metadata on the backend, it's available on the Backend `User` object which can be accessed using the getUser() method. This method will return the `User` object which contains the public metadata. However, this method is subject to [rate limits](/docs/guides/how-clerk-works/system-limits#backend-api-requests), so *if you are accessing the metadata frequently*, it's recommended to [attach it to the user's session token](#metadata-in-the-session-token). #### Set public metadata To set public metadata, see the updateUserMetadata() reference. ### Private metadata Private metadata can only be read and set by the backend and webhook handlers, which makes this useful for storing sensitive data that you don't want to expose to the frontend. For example, you could store a user's Stripe customer ID. #### Access private metadata To access private metadata on the backend, it's available on the Backend `User` object which can be accessed using the getUser() method. This method will return the `User` object which contains the private metadata. However, this method is subject to [rate limits](/docs/guides/how-clerk-works/system-limits#backend-api-requests), so *if you are accessing the metadata frequently*, it's recommended to [attach it to the user's session token](#metadata-in-the-session-token). #### Set private metadata To set private metadata, see the updateUserMetadata() reference. ### Unsafe metadata Unsafe metadata can be both read and set from the frontend and the backend. It's called "unsafe" metadata because it can be modified directly from the frontend, which means malicious users could potentially tamper with these values. Unsafe metadata is the only metadata property that can be set during sign-up, so a common use case is to use it in custom onboarding flows. Custom data collected during the onboarding (sign-up) flow can be stored in the SignUp object. After a successful sign-up, `SignUp.unsafeMetadata` is copied to the `User` object as `User.unsafeMetadata`. From that point on, the unsafe metadata is accessible as a direct attribute of the `User` object. #### Access unsafe metadata To access unsafe metadata on the frontend, it's available on the User object, which can be accessed using the useUser() hook. To access unsafe metadata on the backend, it's available on the Backend `User` object which can be accessed using the getUser() method. This method will return the `User` object which contains the unsafe metadata. However, this method is subject to [rate limits](/docs/guides/how-clerk-works/system-limits#backend-api-requests), so *if you are accessing the metadata frequently*, it's recommended to [attach it to the user's session token](#metadata-in-the-session-token). #### Set unsafe metadata See the following examples to see how to set unsafe metadata on the frontend (client-side) and backend (server-side). For React-based SDKs, such as Next.js, use the useUser() hook to update unsafe metadata. ```tsx {{ filename: 'page.tsx' }} export default function Page() { const { user } = useUser() const [birthday, setBirthday] = useState('') return (
setBirthday(e.target.value)} />
) } ```
When using the JavaScript SDK, use the User.update() method to update unsafe metadata. ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { await clerk.user .update({ unsafeMetadata: { birthday: '01-01-2000', }, }) .then((res) => console.log(res)) .catch((error) => console.log('An error occurred:', error.errors)) } else { document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ```
To update unsafe metadata on the server-side, see the updateUserMetadata() reference.
## Metadata in the session token Retrieving metadata from the `User` object on the server-side requires making an API request to Clerk's Backend API, which is slower and is subject to [rate limits](/docs/guides/how-clerk-works/system-limits#backend-api-requests). You can store it in the user's session token, which doesn't require making an API request as it's available on the user's authentication context. **However, there is a size limitation to keep in mind.** Clerk stores the session token in a cookie, and most browsers cap cookie size at [**4KB**](https://datatracker.ietf.org/doc/html/rfc2109#section-6.3). After accounting for the size of Clerk's default claims, the cookie can support **up to 1.2KB** of custom claims. **Exceeding this limit will cause the cookie to not be set, which will break your app as Clerk depends on cookies to work properly.** If you need to store more than 1.2KB of metadata, you should [store the extra data in your own database](/docs/guides/development/webhooks/syncing#storing-extra-user-data) instead. If this isn't an option, you can [move particularly large claims out of the token](/docs/guides/sessions/session-tokens#example) and fetch them using a separate API call from your backend, but this approach brings back the issue of making an API request to Clerk's Backend API, which is slower and is subject to rate limits. Another limitation of storing metadata in the session token is that when you modify metadata server-side, the changes won't appear in the session token until the next refresh. To avoid race conditions, either [force a JWT refresh](/docs/guides/sessions/force-token-refresh) after metadata changes or handle the delay in your application logic. If you've considered the limitations, and you still want to store metadata in the session token: 1. In the Clerk Dashboard, navigate to the [**Sessions**](https://dashboard.clerk.com/~/sessions) page. 2. Under **Customize session token**, in the **Claims** editor, you can add any claim to your session token that you need and select **Save**. To avoid exceeding the session token's 1.2KB limit, it's not recommended to add the entire `user.public_metadata` object. Instead, add individual fields as claims, like `user.public_metadata.birthday`. When doing this, it's recommended to leave particularly large claims out of the token to avoid exceeding the session token's size limit. See the [example](/docs/guides/sessions/session-tokens#example) for more information. --- title: User impersonation description: Clerk's user impersonation feature allows you to sign in as different users to offer customer support or debug issues. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/users/impersonation sourceFile: /docs/guides/users/impersonation.mdx --- > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. Clerk's user impersonation feature allows you to sign in to your application as one of your users, enabling you to directly reproduce and remedy any issues they're experiencing. It's a helpful feature for customer support and debugging. ## Impersonate a user The easiest way to impersonate a user is from the [**Users**](https://dashboard.clerk.com/~/users) page in the Clerk Dashboard. To impersonate a user, on the right side of a user's row, select on the menu icon (three stacked dots). A dropdown menu will appear. When you select the **Impersonate user** option, your application instance should open in a new tab with the impersonated user signed in. To add user impersonation functionality to your application, see the [custom flow for user impersonation](/docs/guides/development/custom-flows/account-updates/user-impersonation). ## How user impersonation works Clerk allows developers or admins of an application to sign in as different users. The feature involves two parts: 1. Get an actor token that can be used to sign in as a different user. 2. Detect an impersonated session as soon as you're signed in. ## Actor tokens Actor tokens are similar to [sign-in tokens](/docs/reference/backend-api/tag/sign-in-tokens/post/sign_in_tokens){{ target: '_blank' }}. They can be used for one-time sign-ins, but they result in impersonated sessions. ### Create an actor token To create an actor token, you can use the [Backend API](/docs/reference/backend-api/tag/actor-tokens/post/actor_tokens){{ target: '_blank' }}. The following example demonstrates how to create an actor token by making a request directly to Clerk's Backend API using cURL. Using the generated token will result in user with ID `user_21Ufcy98STcA11s3QckIwtwHIES` (the actor/impersonator) signing in as user with ID `user_1o4qfak5AdI2qlXSXENGL05iei6` (the subject/impersonated). ```bash curl -X POST https://api.clerk.com/v1/actor_tokens -d '{ \ "user_id": "user_1o4qfak5AdI2qlXSXENGL05iei6", \ "expires_in_seconds": 600 \ "actor": { \ "sub": "user_21Ufcy98STcA11s3QckIwtwHIES", \ } \ }' ``` When creating actor tokens, the object that you pass as the `actor` parameter will end up in the authentication token's `act` claim. You can read more details in the [guide on session tokens](/docs/guides/sessions/session-tokens#default-claims). ### Revoke an actor token To revoke an actor token, you can use the [Backend API](/docs/reference/backend-api/tag/actor-tokens/post/actor_tokens/\{actor_token_id}/revoke){{ target: '_blank' }}. Despite it's expiration date, you can revoke a token at any time. Revoked actor tokens can no longer be used for signing in. The following example demonstrates how to revoke an actor token by making a request directly to Clerk's Backend API using cURL, even if it's not expired yet. ```bash curl -X POST https://api.clerk.com/v1/actor_tokens/act_2EL6mQKzeUtoRwGuLZsznyfkIsH/revoke ``` ### Sign in with an actor token Actor tokens are consumed the same way as sign in tokens. Once you've successfully created an actor token, you can use the `url` attribute of the response to consume the token and impersonate a user. The `url` attribute is a Clerk Frontend API URL that will use the token to sign out existing users and prepare the SignIn object for impersonation. You can directly visit the `url` provided in the response to consume the actor token. The [Frontend API](/docs/reference/frontend-api/){{ target: '_blank' }} will redirect you to the `/sign-in` page of your application, where the flow will continue by consuming the `__clerk_ticket` parameter. ## How to detect impersonated sessions Once a user is signed in as a different user, Clerk provides APIs and helper methods to distinguish an impersonated session from a regular session. Clerk also adds an `act` claim on the [Clerk session token](/docs/guides/sessions/session-tokens), which contains information like the impersonated session ID and the actor/impersonator's user ID. > \[!NOTE] > When using a custom JWT template, the `{{session.actor}}` will need to be added as a claim in order to expose it. ### Detect impersonated sessions in the frontend To detect impersonated sessions in the frontend, the `actor` object contains the `sub` claim of the impersonator. You can use this information to detect impersonated sessions. You can use the useAuth() hook to get access to the authentication context, which includes the `actor` object. ```jsx const { userId, actor } = useAuth() return (
Server-side info:

{actor && ( User {actor.sub} has signed in as user {userId} )}

) ```
You can use the Clerk object to get access to the `session` object, which includes the `actor` object. ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() const { session } = clerk if (session.actor) { const { actor, user } = session console.log(`User ${actor.sub} is signed in as user ${user.id}.`) } ```
### Detect impersonated sessions in the backend The Auth object is a server-side object that contains the `actor` object, as well as important information like the current user's session ID and user ID. **Accessing the `Auth` object differs depending on the SDK you're using.** Here are some examples: The Next.js SDK provides the auth() helper to App Router apps to access the `Auth` object. ```jsx import { auth } from '@clerk/nextjs/server' export default async function Page() { // Use `auth()` to access the `Auth` object const { actor, userId } = await auth() return (
{actor && ( user {actor.sub} has signed in as user {userId} )}
) } ```
The Astro SDK provides the `locals.auth()` function to access the `Auth` object. Learn more about using `locals.auth()`. ```astro {{ filename: 'src/pages/example.astro' }} --- // Use `locals.auth()` to access the `Auth` object const { actor, userId } = Astro.locals.auth() ---
{ actor && ( user {actor.sub} has signed in as user {userId || ''} ) }
```
The Express SDK provides a middleware that attaches the Auth object to the `request` object. ```js import express from 'express' import { clerkMiddleware } from '@clerk/express' const app = express() // Apply the Express SDK middleware app.use(clerkMiddleware()) app.get('/protected-endpoint', (req, res) => { // Clerk's authentication context can be accessed from the request object const { userId, actor } = req.auth res.json({ userId, actor }) }) app.listen(3000, () => { console.log('Booted.') }) ``` The React Router SDK provides the getAuth() function to access the `Auth` object. ```tsx {{ filename: 'app/routes/example.tsx' }} import { redirect } from 'react-router' import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/example' export async function loader(args: Route.LoaderArgs) { // Use `getAuth()` to access the `Auth` object const { isAuthenticated, actor, userId } = await getAuth(args) return { actor: actor, userId: userId || '', } } export default function Example({ loaderData }: Route.ComponentProps) { return (
{loaderData.actor && ( user {loaderData.actor.sub} has signed in as user {loaderData.userId} )}
) } ```
The Tanstack React Start SDK provides the `auth()` function to access the `Auth` object. Learn more about using `auth()`. ```tsx {{ filename: 'src/routes/api/example.tsx' }} import { auth } from '@clerk/tanstack-react-start/server' import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { GET: async () => { // Use `auth()` to access the `Auth` object const { actor, userId } = await auth() return json({ actor, userId }) }, }, }, }) ```
--- title: Invite users to your application description: Learn how to invite users to your Clerk application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/users/inviting sourceFile: /docs/guides/users/inviting.mdx --- Inviting users to your Clerk application allows you to onboard new users seamlessly by sending them a unique invitation link. Once you create an invitation, Clerk sends an email to the invited user with a unique invitation link. When the user visits the invitation link, they will be redirected to the [Account Portal sign-up page](/docs/guides/customizing-clerk/account-portal#sign-up) and **their email address will be automatically verified.** If you want to redirect the user to a specific page in your application, you can [specify a redirect URL when creating the invitation](#with-a-redirect-url). Invitations expire after a month. If the user clicks on an expired invitation, they will get redirected to the application's sign-up page and will have to go through the normal sign-up flow. Their email address will not be auto-verified. > \[!TIP] > Invitations are only used to invite users to your application. The application will still be available to everyone even without an invitation. If you're looking to restrict access to invited users only, refer to the [**Restricted** sign-up mode](/docs/guides/secure/restricting-access#sign-up-modes). ## Create an invitation You can create an invitation either in the [Clerk Dashboard](#in-the-clerk-dashboard) or [programmatically](#programmatically). When making this decision, keep in mind that if you create an invitation through the Clerk Dashboard, you can only set an invitation expiration date. If you create an invitation programatically, you are able to set more options, such as the URL you want the user to be redirected to after they accept the invitation, metadata to add to the invitation, or whether an invitation should be created if there is already an existing invitation for the given email address. ### In the Clerk Dashboard To create an invitation in the Clerk Dashboard, navigate to the [**Invitations**](https://dashboard.clerk.com/~/users/invitations) page. ### Programmatically To create an invitation programmatically, you can either make a request directly to Clerk's Backend API or use the createInvitation() method as shown in the following example. ```ts {{ filename: 'app/api/example/route.ts' }} import { clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function POST() { const client = await clerkClient() const invitation = await client.invitations.createInvitation({ emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, }) return NextResponse.json({ message: 'Invitation created', invitation }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' import { clerkClient } from '@clerk/astro/server' export const POST: APIRoute = async (context) => { await clerkClient(context).invitations.createInvitation({ emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, }) return new Response(JSON.stringify({ success: true }), { status: 200 }) } ``` ```ts {{ filename: 'public.ts' }} import { getAuth, clerkClient } from '@clerk/express' app.post('/createUser', async (req, res) => { await clerkClient.invitations.createInvitation({ emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, password: 'password', }) res.status(200).json({ success: true }) }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' import { json } from 'react-router-dom' export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() const emailAddress = formData.get('emailAddress') const redirectUrl = formData.get('redirectUrl') const publicMetadata = formData.get('publicMetadata') await clerkClient.invitations.createInvitation({ emailAddress: emailAddress, redirectUrl: redirectUrl, publicMetadata: publicMetadata, }) return json({ success: true }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { POST: async () => { await clerkClient().invitations.createInvitation({ emailAddress: 'invite@example.com', redirectUrl: 'https://www.example.com/my-sign-up', publicMetadata: { example: 'metadata', example_nested: { nested: 'metadata', }, }, }) return json({ success: true }) }, }, }, }) ``` See the [Backend API reference](/docs/reference/backend-api/tag/invitations/post/invitations){{ target: '_blank' }} for an example of the response. ### With a redirect URL > \[!WARNING] > You currently cannot specify a redirect URL when creating an invitation in the Clerk Dashboard; if you need to specify a redirect URL, you need to create the invitation programmatically. When you create an invitation programmatically, you can specify a `redirectUrl` parameter. This parameter tells Clerk where to redirect the user when they visit the invitation link. Once the user visits the invitation link, they will be redirected to the page you specified, which means **you must handle the sign-up flow in your code for that page**. You can either embed the \ component on that page, or if the prebuilt component doesn't meet your specific needs or if you require more control over the logic, you can build a [custom flow](/docs/guides/development/custom-flows/authentication/application-invitations). > \[!TIP] > > * To test redirect URLs in your development environment, pass your port (e.g. `http://localhost:3000`). > * To use the Account Portal, pass the URL provided by Clerk on the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page in the Clerk Dashboard. For example, `https://prepared-phoenix-98.accounts.dev/sign-up` redirects the user to the Account Portal sign-up page. ### With invitation metadata When you create an invitation programmatically, you can specify a `publicMetadata` parameter to add metadata to an invitation. Once the invited user signs up using the invitation link, the invitation metadata will end up in the user's public metadata. [Learn more about user metadata](/docs/guides/users/extending). ## Revoke an invitation You can revoke an invitation at any time. Revoking an invitation prevents the user from using the invitation link that was sent to them. You can revoke an invitation in the [Clerk Dashboard](#in-the-clerk-dashboard-2) or [programmatically](#programmatically-2). > \[!WARNING] > Revoking an invitation does **not** prevent the user from signing up on their own. If you're looking to restrict access to invited users only, refer to the [**Restricted** sign-up mode](/docs/guides/secure/restricting-access#sign-up-modes). ### In the Clerk Dashboard To revoke an invitation in the Clerk Dashboard, navigate to the [**Invitations**](https://dashboard.clerk.com/~/users/invitations) page. ### Programmatically To revoke an invitation programmatically, you can either make a request directly to Clerk's Backend API or use the revokeInvitation() method as shown in the following example. ```ts {{ filename: 'app/api/example/route.ts' }} import { clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function POST() { const client = await clerkClient() const invitation = await client.invitations.revokeInvitation({ invitationId: 'invitation_123', }) return NextResponse.json({ message: 'Invitation revoked' }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' import { clerkClient } from '@clerk/astro/server' export const POST: APIRoute = async (context) => { await clerkClient(context).invitations.revokeInvitation({ invitationId: 'invitation_123', }) return new Response(JSON.stringify({ success: true }), { status: 200 }) } ``` ```ts {{ filename: 'public.ts' }} import { getAuth, clerkClient } from '@clerk/express' app.post('/revokeInvitation', async (req, res) => { await clerkClient.invitations.revokeInvitation({ invitationId: 'invitation_123', }) res.status(200).json({ success: true }) }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' import { json, redirect } from 'react-router-dom' export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() const invitationId = formData.get('invitationId') await clerkClient.invitations.revokeInvitation({ invitationId: invitationId, }) return json({ success: true }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { POST: async () => { await clerkClient().invitations.revokeInvitation({ invitationId: 'invitation_123', }) return json({ success: true }) }, }, }, }) ``` See the [Backend API reference](/docs/reference/backend-api/tag/invitations/post/invitations/\{invitation_id}/revoke){{ target: '_blank' }} for an example of the response. ## Custom flow Clerk's prebuilt components and [Account Portal pages](/docs/guides/customizing-clerk/account-portal) handle the sign-up flow for you, including the invitation flow. If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow for application invitations](/docs/guides/development/custom-flows/authentication/application-invitations). --- title: Users description: Learn how to manage your users in your Clerk application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/users/managing sourceFile: /docs/guides/users/managing.mdx --- To get started, it's important to first understand Clerk's User object. The `User` object holds all of the information for a single user of your application and provides a set of methods to manage their account. Each `User` has at least one authentication identifier, which might be their email address, phone number, or a username. A user can be contacted at their primary email address or primary phone number. They can have more than one registered email address, but only one of them will be their primary email address (`User.primaryEmailAddress`). This goes for phone numbers as well; a user can have more than one, but only one phone number will be their primary (`User.primaryPhoneNumber`). At the same time, a user can also have one or more external accounts by connecting to [social providers](/docs/guides/configure/auth-strategies/social-connections/all-providers) such as Google, Apple, Facebook, and many more (`User.externalAccounts`). Finally, a `User` object holds profile data like the user's name, profile picture, and a set of [metadata](/docs/guides/users/extending) that can be used internally to store arbitrary information. The metadata are split into `publicMetadata` and `privateMetadata`. Both types are set from the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}, but public metadata can also be accessed from the [Frontend API](/docs/reference/frontend-api){{ target: '_blank' }}. For more information on the `User` object, such as helper methods for retrieving and updating user information and authentication status, see the reference docs. The `User` object is also available in the backend, but it looks slightly different. For more information, see the Backend `User` object reference docs. ## Manage users You can manage your users [in the Clerk Dashboard](#in-the-clerk-dashboard), or [programmatically](#programmatically). ### In the Clerk Dashboard To manage users in the Clerk Dashboard, navigate to the [**Users**](https://dashboard.clerk.com/~/users) page. ### Programmatically You can manage users programmatically through the [frontend](#in-the-frontend) or [backend](#in-the-backend). #### In the frontend Depending on the level of abstraction you need, you can manage users in the frontend using Clerk's prebuilt components, React hooks, or lower-level JavaScript methods. * Prebuilt components: Clerk provides the prebuilt components \ and \ to help your users manage their profile data. * Hooks: Because Clerk's React-based SDKs are built on top of the Clerk React SDK, you can use the hooks that the React SDK provides. These hooks include access to the `User` object and helpful methods for managing user authentication and profile data. * JavaScript methods: If Clerk's prebuilt components don't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. For more information, see the [custom flow guides](/docs/guides/development/custom-flows/overview). #### In the backend The JS Backend SDK is a wrapper around the [Backend API](/docs/reference/backend-api){{ target: '_blank' }} that makes it easier to interact with the API. It includes many methods for managing users, such as `getUser()`, `createUser()`, and `deleteUser()`. For more information, see the JS Backend SDK reference docs. ## Create users You can create users either [in the Clerk Dashboard](#in-the-clerk-dashboard-2) or [programmatically](#programmatically-2). ### In the Clerk Dashboard To create a user in the Clerk Dashboard, navigate to the [**Users**](https://dashboard.clerk.com/~/users) page and select **Create user**. ### Programmatically To create a user programmatically, you can either make a request directly to Clerk's Backend API or use the createUser() method as shown in the following example. ```ts {{ filename: 'app/api/example/route.ts' }} import { auth, clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function POST() { const client = await clerkClient() const user = await client.users.createUser({ emailAddress: ['test@example.com'], password: 'password', }) return NextResponse.json({ message: 'User created', user }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' import { clerkClient } from '@clerk/astro/server' export const POST: APIRoute = async (context) => { await clerkClient(context).users.createUser({ emailAddress: ['test@example.com'], password: 'password', }) return new Response(JSON.stringify({ success: true }), { status: 200 }) } ``` ```ts {{ filename: 'public.ts' }} import { getAuth, clerkClient } from '@clerk/express' app.post('/createUser', async (req, res) => { await clerkClient.users.createUser({ emailAddress: ['test@example.com'], password: 'password', }) res.status(200).json({ success: true }) }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' import { json } from 'react-router-dom' export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() const emailAddress = formData.get('emailAddress') const password = formData.get('password') await clerkClient.users.createUser({ emailAddress: [emailAddress], password: password, }) return json({ success: true }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { POST: async () => { await clerkClient().users.createUser({ emailAddress: ['test@example.com'], password: 'my-secure-password', }) return json({ success: true }) }, }, }, }) ``` ## Delete users You can delete users either [in the Clerk Dashboard](#in-the-clerk-dashboard-3) or [programmatically](#programmatically-3). ### In the Clerk Dashboard To delete a user in the Clerk Dashboard, navigate to the [**Users**](https://dashboard.clerk.com/~/users) page. You can either select the user and then in the side navigation menu, select **Delete user**, or select the menu icon on the right side of the user's row and select **Delete user**. ### Programmatically To delete a user programmatically, you can either make a request directly to Clerk's Backend API or use the deleteUser() method as shown in the following example. ```ts {{ filename: 'app/api/example/route.ts' }} import { clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function POST() { await clerkClient.users.deleteUser('user_123') return NextResponse.json({ success: true }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' import { clerkClient } from '@clerk/astro/server' export const POST: APIRoute = async (context) => { await clerkClient(context).users.deleteUser('user_123') return new Response(JSON.stringify({ success: true }), { status: 200 }) } ``` ```ts {{ filename: 'public.ts' }} import { clerkClient } from '@clerk/express' app.post('/deleteUser', async (req, res) => { await clerkClient.users.deleteUser('user_123') res.status(200).json({ success: true }) }) ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' import { json, redirect } from 'react-router-dom' export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() const userId = formData.get('userId') await clerkClient.users.deleteUser(userId) return json({ success: true }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { auth, clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { POST: async () => { await clerkClient().users.deleteUser('user_123') return json({ success: true }) }, }, }, }) ``` --- title: Free trials description: Let users try paid Features before subscribing lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/billing/free-trials sourceFile: /docs/guides/billing/free-trials.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Free trials let your users explore paid [Features](/docs/guides/secure/features) for a limited time for free, helping them build confidence in a purchase decision. With Clerk Billing, you can turn on free trials for any Plan, or set the same trial period across all your Plans. ## Enable free trials To enable free trials for your Plans: 1. Navigate to the [**Plans**](https://dashboard.clerk.com/~/billing/plans) page in the Clerk Dashboard. 2. Select the Plan you want to enable free trials on. 3. Enable **Free trial** and set the number of trial days (minimum is 1 day). ## What your users experience ### Starting a trial Only users who have never paid for a subscription and have never used a free trial can start a free trial. A credit card is required to start a free trial. This helps prevent abuse and ensures a smooth transition to paid service when the trial ends. ### During a trial Users get access to the Plan's paid Features for the configured number of days. If they cancel during their trial, they keep access until the original trial end date. ### When the trial ends If the user didn't cancel their subscription during the trial, they are charged using their default payment method on file. This may be a different payment method than the one used during checkout when the trial started. If the user cancels their subscription during the trial, they lose access at the end of the trial and are moved back to the free plan. They are not charged. Both you and your users will receive notifications when a trial is about to expire: * You'll receive a `subscriptionItem.freeTrialEnding` webhook event 3 days before the trial expires. * Users receive an email notification 3 days before their trial expires. If the trial period is shorter than 3 days, these notifications are sent immediately when the trial begins. ## Manage trials You can manually change the duration of a user's trial: * **Cancel at the end of the trial**: Cancel the trial while allowing the user to keep access to the paid Features until the trial period ends. This prevents their default payment method from being charged when the trial period ends. * **End immediately**: Immediately move the user back to the free Plan and terminate their access to the paid Features they were trialing. * **Extend a trial**: Make a user's trial last longer. You must extend a trial by at least 1 day and no more than 365 days. You can only manage the trial of a user while the trial is active. Once a trial ends, you can no longer extend or cancel it. To manage a trial for a subscription: 1. Navigate to the [**Subscriptions**](https://dashboard.clerk.com/~/billing/subscriptions) page in the Clerk Dashboard. 2. Select the subscription with the trial you want to manage. 3. Under **Subscriptions**, select the **...** menu to see the available actions for managing the trial. --- title: Clerk Billing description: Clerk Billing is a feature that allows you to create and manage Plans and Features for your application. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/billing/overview sourceFile: /docs/guides/billing/overview.mdx --- > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. Clerk Billing allows your customers to purchase recurring subscriptions to your application. To get started, **choose one or combine both of the following** business models depending on your application's needs. * [Billing for B2C SaaS](/docs/guides/billing/for-b2c) * To charge individual users *** * [Billing for B2B SaaS](/docs/guides/billing/for-b2b) * To charge companies or organizations *** * [Webhooks](/docs/guides/development/webhooks/billing) * To track subscription lifecycles and monitor payment attempts *** * [Build a simple checkout page](/docs/guides/development/custom-flows/billing/checkout-new-payment-method) * To charge users with a new payment method ## Frequently asked questions (FAQ) ### Can I use an existing Stripe account with Clerk Billing? Yes, you can. However, it must not already be linked to another platform. ### Can I see subscriptions in my Stripe account? Clerk Billing only uses Stripe for payment processing. You can see payment and customer information in Stripe. However, Clerk Billing is a separate product from Stripe Billing; plans and subscriptions made in Clerk are not synced to Stripe. ### Can I use the same Stripe account for both dev and prod environments? No. Stripe accounts created for development instances are sandbox/test accounts and cannot be used for production. For a production environment, you must create a separate Stripe account. ### Is Clerk a Merchant of Record (MoR) for transactions? No, Clerk does not provide this service. ### Does Clerk Billing support non-USD currencies? Clerk Billing currently supports only USD as the billing currency. While you can connect both US and non-US Stripe accounts, all payments will be processed in USD regardless of your Stripe account's local currency. For information about Stripe's supported countries and currencies, see [Stripe Global](https://stripe.com/global){{ rel: 'noopener noreferrer' }}. Support for additional currencies is on our roadmap. ### What third-party tools does Clerk Billing integrate with? None directly, but since payments are processed through Stripe, you can use any third-party tool that integrates with Stripe for analytics, reporting, invoicing, or tax compliance. ### Can I offer custom pricing plans to specific customers? Clerk Billing does not currently support custom pricing plans, though we plan to roll out support for this in the future. ### Can I let users upgrade or downgrade their plans mid-cycle? Yes. Plan upgrades will take effect immediately, while downgrades take effect at the end of the current billing cycle. ### Does Clerk Billing support annual subscriptions? Yes, you can offer subscribers the option to pay annually, at a discounted monthly price. Set up annual pricing for your plans in the Clerk dashboard, and customers can choose between monthly or annual billing when subscribing. ### How does Clerk handle taxes and VAT for international billing? Clerk Billing does not currently support tax or VAT, but these are planned for future releases. ### How can I test failure scenarios like expired cards or canceled subscriptions? You can simulate failures in Stripe test mode using test cards that trigger specific behaviors. See [Stripe Testing](https://docs.stripe.com/testing){{ rel: 'noopener noreferrer' }} for a list of test cards and behaviors. ### Which countries is Clerk Billing not supported in? Clerk Billing is not supported in Brazil, India, Malaysia, Mexico, Singapore, and Thailand due to [payment processing restrictions](https://stripe.com/legal/restricted-businesses). Support may be added in the future. For all other regions, availability depends on Stripe - see [Stripe Global](https://stripe.com/global){{ rel: 'noopener noreferrer' }} for the full list. --- title: Tasks after sign-up/sign-in description: Learn how to configure your application to require users to complete specific tasks after signing up or signing in. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/configure/session-tasks sourceFile: /docs/guides/configure/session-tasks.mdx --- **Session tasks** are pending requirements that users must complete after authentication, such as choosing an Organization. When enabled in the Clerk Dashboard, these tasks are handled automatically within the `` and `` components. ## Available tasks Each task is identified by a unique SessionTask\['key']. You can use these task keys to conditionally handle different requirements in your application logic. The following table lists the available tasks and their corresponding keys. | Setting | Key | Description | | - | - | - | | [Allow Personal Accounts](https://dashboard.clerk.com/~/organizations-settings) | `choose-organization` | Disabled by default when enabling Organizations. When disabled, users are required to choose an Organization after authenticating. When enabled, users can choose a Personal Account instead of an Organization. | ## Session states After authentication, users enter one of three states: * **Signed-in**: Authentication complete. Can access protected content or routes. * **Pending**: Authentication complete, but session tasks incomplete. Can't access protected content or routes. * **Signed-out**: Authentication failed or not attempted. Can't access protected content or routes. When authenticating, sessions remain `pending` until users complete the required tasks. By default, `pending` sessions are treated as signed-out across Clerk's authentication context. ## Displaying tasks Once enabled in the Clerk Dashboard, tasks are **embedded by default** within the `` and `` components. For more customization, you can opt out of using the `` and `` components and [create custom pages for tasks](/docs/guides/development/custom-flows/overview#session-tasks). The following table lists the available tasks and their corresponding components. See the linked reference guide for usage instructions. | Name | Component | | - | - | | [Personal accounts disabled (default)](/docs/guides/organizations/overview#allow-personal-accounts) | \ | > \[!IMPORTANT] > Personal accounts being disabled by default was released on 08-22-2025. Applications created before this date will not be able to see the **Allow Personal Accounts** setting, because Personal Accounts were enabled by default. If the prebuilt components don't meet your specific needs or if you require more control over the logic, you can also build your own UI using the `Session.currentTask` property to check if the user has pending session tasks. To access the `Session.currentTask` property, you can use either the `useSession()` hook for React-based applications or `window.Clerk` for other frameworks. ```jsx const { session } = useSession() if (session?.currentTask) { // Check for pending tasks and display custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) } ``` ```js if (window.Clerk.session.currentTask) { // Check for pending tasks and display custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(window.Clerk.session.currentTask) } ``` ## Redirecting to tasks When users have pending session tasks, you can redirect them to specific pages or components to complete these requirements. This is useful when you want to handle session tasks outside of the default `` and `` components. ### Using the `taskUrls` option The `taskUrls` option allows you to specify custom URL paths where users are redirected after sign-up or sign-in when specific session tasks need to be completed. This allows you to still use `` and `` but have tasks with custom pages. The `taskUrls` option is available wherever you initialize the Clerk integration. For most SDKs, it's ``. ```tsx {children} ``` Then, create a page at that URL path that imports the \ component to handle the task. ```tsx {{ filename: 'app/onboarding/choose-organization/page.tsx' }} export default function Page() { return } ``` ### Using the `` control component The `` control component redirects users to the appropriate task page when they have pending session tasks. ```tsx <> {/* Until the user completes their session tasks, Clerk considers them as signed out, by default */} ``` ### Middleware-based redirects There are many ways to protect routes using middleware. If you'd like to simply redirect users to the sign-in page if they are signed-out, you can [use `auth.protect()`](#using-auth-protect). If you'd like to have more control over what your app does based on user authentication status, you can [use the `isAuthenticated` property](#using-is-authenticated). ### Using `auth.protect()` When using `auth.protect()` in middleware to protect routes, it will redirect users to the sign-in page if they are signed-out. In the following example, `pending` users will be redirected to the sign-in page, where the `` component will prompt them to fulfill the session tasks. Once finished, their session will move from `pending` to an `active` (signed-in) state. > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. ```tsx {{ filename: 'proxy.ts', mark: [[6, 8]] }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)']) export default clerkMiddleware(async (auth, req) => { // pending users won't be able to access protected routes // and will be redirected to the sign-in page if (isProtectedRoute(req)) await auth.protect() }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ### Using `isAuthenticated` When using the `isAuthenticated` property in middleware to protect routes, it will return `false` if the user has a `pending` session. Then, you can handle how to respond to pending users, such as redirecting them to a custom page to fulfill the session tasks. ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' import { NextRequest, NextResponse } from 'next/server' const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)']) export default clerkMiddleware(async (auth, req: NextRequest) => { const { isAuthenticated, redirectToSignIn, sessionStatus } = await auth() // Send users with pending sessions to the /session-tasks page if (!isAuthenticated && sessionStatus === 'pending' && isProtectedRoute(req)) { // Add logic to handle pending users // This example redirects pending users to the /session-tasks page // so they can fulfill the session tasks const url = req.nextUrl.clone() url.pathname = '/session-tasks' return NextResponse.redirect(url) } // Send users who are not authenticated // and don't have pending tasks to the sign-in page if (!isAuthenticated && isProtectedRoute(req)) { return redirectToSignIn() } }) ``` ## Session handling By default, `pending` sessions are treated as signed-out across Clerk's authentication context. Some control components and authentication utilities accept a `treatPendingAsSignedOut` prop to control how `pending` sessions are handled: * `true` (default): Treats `pending` sessions as signed-out. Users can't access protected content or routes. * `false`: Treats `pending` sessions as signed-in. Users can access protected content or routes. ### Control components ', '', '']}> The \ component protects content or even entire routes based on a user's authentication state. It will render its children if the user's state is signed-in. It accepts a `fallback` prop that will be rendered if the user's state is signed-out. If the user's state is `pending`, they will see the `fallback` content because, by default, `pending` sessions are treated as signed-out. ```tsx export default function Page() { return ( Signed-out and pending users can see this.

}>

Only signed-in users can see this.

) } ``` If the user's state is `pending`, they will see the protected content because `treatPendingAsSignedOut` is set to `false`. ```tsx export default function Page() { return ( Users that are signed-out can see this.

} >

Users that are signed-in or pending can see this.

) } ```
The \ component renders its children if the user's authentication state is signed-out. If the user's state is `pending`, they **will** see the content of the component because, by default, `pending` sessions are treated as signed-out. ```tsx export default function Page() { return (

Users that are signed-out or pending will see this.

) } ``` If the user's state is `pending`, they **won't** see the content of the component because `treatPendingAsSignedOut` is set to `false`. ```tsx export default function Page() { return (

Users that are signed-out will see this.

) } ```
The \ component renders its children if the user's authentication state is signed-in. If the user's state is `pending`, they **won't** see the content of the component because, by default, `pending` sessions are treated as signed-out. ```tsx export default function Page() { return (

Users that are signed-in will see this.

) } ``` If the user's state is `pending`, they **will** see the content of the component because `treatPendingAsSignedOut` is set to `false`. ```tsx export default function Page() { return (

Users that are signed-in or pending will see this.

) } ```
### Authentication utilities The `useAuth()` hook and helpers that access the Auth object, such as `getAuth()` or `request.auth`, will return `null` if the user has a `pending` session. Most utilities accept a `treatPendingAsSignedOut` option that defaults to `true`. You can pass `false` to treat `pending` sessions as signed-in. #### Example: Personal accounts disabled When Organizations are enabled, [Personal Accounts are disabled by default](/docs/guides/organizations/overview#allow-personal-accounts) and your users will be required to select or create an Organization after authenticating. Until completed, their session remains `pending`. Pages that are protected using Clerk's protection utilities will treat the user's session as signed-out. For `useAuth()`, `isSignedIn` will be `false` and `userId` and `orgId` will be `null` if the user has a `pending` session. ```tsx export default function Dashboard() { const { isSignedIn, userId, orgId } = useAuth() if (!isSignedIn) { return (

User has no session, or has a pending session. They either need to sign in, or they need to complete tasks by selecting or creating an Organization.

) } return (

User {userId} has a valid session and {orgId} is defined

) } ``` For helpers that access the Auth object, `isAuthenticated` would return `false` and `userId` and `orgId` would return `null` if the user has a `pending` session. This example uses the Next.js-specific auth() helper, but you can use the comments in the example to help you adapt it to your SDK. ```tsx {{ filename: 'app/page.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function Page() { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId, orgId } = await auth() if (!isAuthenticated) { return (

User has no session, or has a pending session. They either need to sign in, or they need to complete pending session tasks by selecting or creating an Organization.

) } return (

User {userId} has a valid session and {orgId} is defined

) } ``` #### Example: Accessing the `userId` for pending sessions By default, users with a `pending` session are treated as signed-out, and their `userId` will not be available. However, in some cases, you may want to access the user's ID even if their session is still `pending`. In these cases, you can set `treatPendingAsSignedOut` to `false`, which will treat `pending` sessions as signed-in and allow you to access the `userId`. This example uses the Next.js-specific auth() helper, but you can use the comments in the example to help you adapt it to your SDK. ```tsx {{ filename: 'app/api/get-teams/route.tsx' }} import { auth } from '@clerk/nextjs/server' export const POST = async () => { // `treatPendingAsSignedOut` is set to `false` to allow access to the `userId` for pending sessions // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId, has } = await auth({ treatPendingAsSignedOut: false }) // Check if the user is signed-out if (!isAuthenticated) { return Response.json({ error: 'User is signed-out' }, { status: 401 }) } // Now the pending user's `userId` can be used for your use case // This is a basic example of creating a resource using the `userId` try { const newResource = await resources.create({ userId, }) return Response.json({ data: newResource }, { status: 201 }) } catch (error) { return Response.json({ error: 'Failed to create resource' }, { status: 500 }) } } ``` --- title: Sign-up and sign-in options description: Clerk provides various options for configuring a sign-up and sign-in flow. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/sign-up-sign-in-options sourceFile: /docs/guides/configure/auth-strategies/sign-up-sign-in-options.mdx --- Clerk provides multiple options for configuring a sign-up and sign-in flow for your application. This guide will walk you through each option. You can modify your authentication options after your application has been created by navigating to the [Clerk Dashboard](https://dashboard.clerk.com/) and selecting any of the options under **User & Authentication** in the left sidenav. ## User & authentication To configure the options available to users for authentication, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page in the Clerk Dashboard. The easiest way to allow your users to create and manage their authentication options is to use the prebuilt \ component. If you're building a custom user interface using the Clerk API, refer to the [custom flow guides](/docs/guides/development/custom-flows/overview). ### Email Users can authenticate with their email address using the following options: * **Email verification code**: Users receive a one-time code to their email address to sign in. * **Email verification link**: Users receive an email with a link to sign in. As a security measure, email links expire after 10 minutes to prevent the use of compromised or stale links. > \[!WARNING] > Expo does not support email links. You can request this feature on [Clerk's roadmap](https://feedback.clerk.com/). * **Require the same device and browser**: Email links are required to be verified from the same device and browser on which the sign-up or sign-in was initiated. For example: * A user tries to sign in from their desktop browser. * They open the email link on their mobile phone to verify their email address. * The user's sign-in on the desktop browser **gets an error**, because the link was verified on a different device and browser. ### Phone > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. Users can authenticate with their phone number and verify it with a one-time code. SMS functionality is restricted to phone numbers from countries enabled on your [SMS allowlist](#sms-allowlist). ### SMS allowlist SMS functionality, including SMS OTPs, is restricted to phone numbers from countries that are enabled on your SMS allowlist. This can be useful for avoiding extraneous SMS fees from countries from which your app is not expected to attract traffic. Every instance starts off with a default set of enabled SMS country tiers. To tailor it to your needs: 1. In the Clerk Dashboard, navigate to the [**SMS**](https://dashboard.clerk.com/~/customization/sms) page. 2. Select the **Settings** tab. 3. Enable or disable countries as needed. If a country is disabled, then phone numbers starting with the corresponding country calling code: * Cannot receive OTPs and a request to receive an OTP will be rejected with an error * Cannot receive notifications for password or passkey modifications * Cannot be used upon sign-up * Cannot be added to an existing user profile ### Username In this section, you can allow users to set their username. Usernames must be between 4 and 64 characters long and do not allow special characters (^$!.`#+~`), but this can be customized. > \[!IMPORTANT] > Usernames only support Latin-based characters. This restriction helps protect against Unicode spoofing and homograph attacks, where characters from non-Latin scripts can be used to impersonate users. ### Password When **Password** is enabled, users provide a password to sign in. Disabling **Password** will only affect new users. Existing users will still be able to sign in with their existing password. ### Passkeys > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. A passkey is a type of sign-in credential that requires one user action, but uses two authentication factors: 1. A pin number or biometric data 2. A physical device **Users can only create passkeys after signing up**, so you'll need to enable another authentication strategy for the sign-up process. After signing in, users can create a passkey. When setting up passkeys with Android, there are a few additional steps to follow. Learn more about passkeys for Android. When setting up passkeys with Expo, there are a few additional steps to follow. Learn more about passkeys for Expo. #### Passkey limitations * Passkeys are not currently available as an [MFA](#multi-factor-authentication) option. * Not all devices and browsers are compatible with passkeys. Passkeys are built on WebAuthn technology and you should check [the Browser Compatibility docs](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API#browser_compatibility) for an up-to-date list. * Passkey related APIs will not work with Expo. * Your users can have a max of 10 passkeys per account. #### Domain restrictions for passkeys Passkeys are tied to the domain they are created on and **cannot be used across different domains**. However, passkeys **do work on subdomains** if they are registered on the root domain. For example: * Passkeys created on `your-domain.com` **cannot be used** on `your-domain-admin.com` (different domains). * Passkeys created on `your-domain.com` **can be used** on `accounts.your-domain.com` (subdomain of the same root domain). * Passkeys created on `staging1.your-domain.com` **cannot be used** on `staging2.your-domain.com` (sibling subdomains) unless the passkey was scoped to `your-domain.com` (i.e. the shared root domain). **If you're using [satellite domains](/docs/guides/dashboard/dns-domains/satellite-domains)**, in both development and production, passkeys won't be portable between your primary domain and your satellite domains so you should avoid using them. If you're **not** using satellite domains: * **In development**, you can either: * **The recommended approach**. Use Clerk's components, [Elements](/docs/guides/customizing-clerk/elements/overview), or custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview)., instead of the [Account Portal](/docs/guides/customizing-clerk/account-portal). This ensures the passkey is created and used entirely on your development domain, so passkeys created on `localhost` will only work on `localhost`. * Create a passkey directly through the Account Portal instead of your local application to keep it tied to the Account Portal's domain. Passkeys created on your Account Portal (e.g., `your-app.accounts.dev`) will only work on that domain, which can cause issues if you switch between `localhost` and the Account Portal during development. If you choose this approach, ensure all testing happens on the same domain where the passkey was created. * **In production,** your Account Portal is usually hosted on a subdomain of your main domain (e.g. `accounts.your-domain.com`), enabling passkeys to work seamlessly across your app. However, as stated above, if you use **satellite domains**, passkeys will not work as intended. ### User model In this section, you can: * Allow users to set their first and last name. * Allow users to delete their accounts. ## SSO connections SSO connections are a way to allow users to authenticate with their existing accounts from other services. For example, if a user already has an account with Google, they can sign in with their Google account instead of creating a new account with your application. Clerk offers two different types of SSO connections: * For all users, which are also known as OAuth connections, or social connections. Read more about [OAuth connections](/docs/guides/configure/auth-strategies/social-connections/overview). * For specific domains and Organizations, which are also known as Enterprise SSO connections. Read more about [Enterprise SSO connections](/docs/guides/configure/auth-strategies/enterprise-connections/overview). To enable SSO connections, navigate to the [**Enterprise SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. ## Web3 authentication Clerk provides Web3 authentication with either [Base](/docs/guides/configure/auth-strategies/web3/base), [MetaMask](/docs/guides/configure/auth-strategies/web3/metamask), [Coinbase Wallet](/docs/guides/configure/auth-strategies/web3/coinbase-wallet), or [OKX Wallet](/docs/guides/configure/auth-strategies/web3/okx-wallet). As part of validating the accuracy of the returned Web3 account address, Clerk handles the signing of a message and verifying the signature. Because sign-in with Web3 uses the same abstraction as our other authentication factors, like passwords or email links, other Clerk features like multi-factor authentication and profile enrichment work for Web3 users out-of-the-box. To enable Web3 authentication, navigate to the [**Web3**](https://dashboard.clerk.com/~/user-authentication/web3) page in the Clerk Dashboard. ## Multi-factor authentication Clerk supports multi-factor authentication (MFA), also known as two-factor authentication (2FA). If a user enables MFA for their account, they are required to complete a second verification step during sign-in. This enhances security by enforcing two different types of verification. Many websites offer this as an optional step, giving users control over their own security. MFA is not available on the new application screen, but it can be enabled in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**Multi-factor**](https://dashboard.clerk.com/~/user-authentication/multi-factor) page. 2. Toggle on the MFA strategies you would like to enable. The following MFA strategies are currently available: * **SMS verification code** * **Authenticator application (also known as TOTP - Time-based One-time Password)** * **Backup codes** Enabling MFA allows users of your app to turn it on for their own accounts through their [User Profile](/docs/guides/customizing-clerk/account-portal#user-profile) page. Enabling MFA does not automatically turn on MFA for all users. > \[!WARNING] > If you're using Duo as an authenticator app, please note that Duo generates TOTP codes differently than other authenticator apps. Duo allows a code to be valid for 30 seconds from *the moment it is first displayed*, which may cause frequent `invalid_code` errors if the code is not entered promptly. More information can be found in [Duo's Help Center](https://help.duo.com/s/article/2107). If you're building a custom user interface instead of using the [Account Portal](/docs/guides/customizing-clerk/account-portal) or prebuilt components, you can use [elements](/docs/guides/customizing-clerk/elements/examples/sign-in#multi-factor-authentication-mfa) or [the Clerk API](/docs/guides/development/custom-flows/authentication/email-password-mfa) to build a custom sign-in flow that allows users to sign in with MFA. ### Reset a user's MFA You can reset a user's MFA by deleting their MFA enrollments. This will remove all of their MFA methods and they will have to enroll in MFA again. To reset a user's MFA: 1. At the top of the [Clerk Dashboard](https://dashboard.clerk.com/), select **Users**. 2. Select the user from the list. 3. Select the **Reset MFA enrollments** button. ## Restrictions Clerk provides a set of restriction options designed to provide you with enhanced control over who can gain access to your application. Restrictions can limit sign-ups or prevent accounts with specific identifiers, such as email addresses, phone numbers, and even entire domains, from accessing your application. [Learn more about restrictions](/docs/guides/secure/restricting-access). --- title: Sign in with Google description: Learn how to configure Sign in with Google for your Clerk-powered Android app. sdk: android sdkScoped: "true" canonical: /docs/guides/configure/auth-strategies/sign-in-with-google lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: android notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: android sourceFile: /docs/guides/configure/auth-strategies/sign-in-with-google.mdx --- [Sign in with Google](https://support.google.com/accounts/answer/12849458?hl=en) helps you easily and securely sign in to third-party apps or services with your Google Account, without having to enter a username and password repeatedly across different services. This guide will teach you how to add native Sign in with Google to your Clerk apps on Android platforms. This is different from Google OAuth - if you want to use Google OAuth, see the [dedicated guide](/docs/guides/configure/auth-strategies/social-connections/google). To make the setup process easier, it's recommended to keep two browser tabs open - one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Google Cloud Console](https://console.cloud.google.com/). ## Enable Google as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Google**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Authorized Redirect URI** somewhere secure. Keep this modal and page open. ## Create the Google Developer Android client 1. Navigate to the [Google Cloud Console](https://console.cloud.google.com/). 2. Select an existing project or [create a new one](https://console.cloud.google.com/projectcreate). You'll be redirected to your project's **Dashboard** page. 3. In the top-left, select the menu icon (**≡**) and select **APIs & Services**. Then, select **Credentials**. 4. Next to **Credentials**, select **Create Credentials**. Then, select **OAuth client ID.** You might need to [configure your OAuth consent screen](https://support.google.com/cloud/answer/6158849#userconsent). Otherwise, you'll be redirected to the **Create OAuth client ID** page. 5. For the **Application type**, select **Android**. 6. Complete the required fields. * **Package name**: Your package name is in your `build.gradle` file, formatted as `com.example.myclerkapp`. * **SHA-1 certificate fingerprint**: To get your SHA-1, run the following command in your terminal: ```sh {{ filename: 'terminal' }} $ keytool -keystore path-to-debug-or-production-keystore -list -v ``` > \[!NOTE] > Replace `path-to-debug-or-production-keystore` with the path to your debug or production keystore. By default, the debug keystore is located in `~/.android/debug.keystore`. It may ask for a keystore password, which is `android`. **Please note that Java is required to run the `keytool` command.** 7. Select **Create**. ## Create the Google Developer Web client 1. In the same project, create another client. Next to **Credentials**, select **Create Credentials**. Then, select **OAuth client ID.** 2. For the **Application type**, select **Web Application**. 3. Complete the required fields. In the **Authorized Redirect URIs** setting, paste the **Authorized Redirect URI** value you saved from the Clerk Dashboard. 4. Select **Create**. A modal will open with your **Client ID** and **Client Secret**. Save these values somewhere secure. ## Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ## Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. > \[!WARNING] > Google sign-in [**does not** allow users to sign in via in-app browsers](https://developers.googleblog.com/en/modernizing-oauth-interactions-in-native-apps-for-better-usability-and-security). ## Usage To learn how to build a sign-up and sign-in flow that supports OAuth connections in your Android application, see the [custom flow guide](/docs/guides/development/custom-flows/authentication/oauth-connections). --- title: Base description: Learn how to set up Web3 authentication with Base. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/web3/base sourceFile: /docs/guides/configure/auth-strategies/web3/base.mdx --- Enabling [Base](https://docs.base.org/base-account/guides/authenticate-users) as a Web3 provider allows your users to sign in and up to your Clerk application with their Base account using SIWE-compatible wallet signatures. SIWE, or [Sign-In With Ethereum](https://docs.base.org/base-account/reference/core/capabilities/signInWithEthereum), is a standard that ensures secure, wallet-based authentication. ## Enable Base as a Web3 provider 1. In the Clerk Dashboard, navigate to the [**Web3**](https://dashboard.clerk.com/~/user-authentication/web3) page. 2. From the list of web3 providers, enable **Base**. ## Test authentication The simplest way to test authentication is to visit your Clerk application's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk applications out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to the **Sign-in** URL, select **Visit**. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. On the sign-in page, you should see **Base** as an option. Use it to sign in. ## Collect additional user information during sign-up (optional) Web3 applications typically use a hexadecimal wallet address to identify users, which offers a high level of privacy. However, when bridging the gap between Web3 and Web2, it's often necessary to gather human-readable information about the user, such as their email address, phone number, or a username. To collect additional information about your user during sign-up: 1. In the Clerk Dashboard, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page. 2. On this page, enable the attributes you want to collect from your user during sign-up. ## Connect Base to existing account Users can connect their Base account to their account at any time through their user profile page. You can configure your application to use the [Account Portal user profile page](/docs/guides/customizing-clerk/account-portal#user-profile) or the prebuilt \ component. --- title: Coinbase Wallet description: Learn how to set up Web3 authentication with Coinbase Wallet. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/web3/coinbase-wallet sourceFile: /docs/guides/configure/auth-strategies/web3/coinbase-wallet.mdx --- Enabling [Coinbase Wallet](https://www.coinbase.com/wallet) as a Web3 provider allows your users to sign in and up to your Clerk application with their Coinbase Wallet. Both [Smart Wallet](https://www.coinbase.com/wallet/smart-wallet) and the [Coinbase Wallet browser extension](https://www.coinbase.com/wallet/downloads) are supported. > \[!WARNING] > This guide is for using Coinbase Wallet for authentication. If you're looking to connect users using [Coinbase.com](https://www.coinbase.com/) as a social provider, see the [dedicated guide](/docs/guides/configure/auth-strategies/social-connections/coinbase). ## Enable Coinbase Wallet as a Web3 provider 1. In the Clerk Dashboard, navigate to the [**Web3**](https://dashboard.clerk.com/~/user-authentication/web3) page. 2. From the list of web3 providers, enable **Coinbase Wallet**. ## Test authentication The simplest way to test authentication is to visit your Clerk application's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk applications out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to the **Sign-in** URL, select **Visit**. The URL should resemble: * **For development** – `https://your-domain.accounts.dev/sign-in` * **For production** – `https://accounts.your-domain.com/sign-in` 3. On the sign-in page, you should see **Coinbase Wallet** as an option. Use it to sign in. ## Collect additional user information during sign-up (optional) Web3 applications typically use a hexadecimal wallet address to identify users, which offers a high level of privacy. However, when bridging the gap between Web3 and Web2, it's often necessary to gather human-readable information about the user, such as their email address, phone number, or a username. To collect additional information about your user during sign-up: 1. In the Clerk Dashboard, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page. 2. On this page, enable the attributes you want to collect from your user during sign-up. ## Connect Coinbase Wallet to existing account Users can connect their Coinbase Wallet to their account at any time through their user profile page. You can configure your application to use the [Account Portal user profile page](/docs/guides/customizing-clerk/account-portal#user-profile) or the prebuilt \ component. --- title: MetaMask description: Learn how to set up Web3 authentication with MetaMask. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/web3/metamask sourceFile: /docs/guides/configure/auth-strategies/web3/metamask.mdx --- Enabling [MetaMask](https://metamask.io/) as a Web3 provider allows your users to sign in and up to your Clerk application with their MetaMask wallet. > \[!IMPORTANT] > MetaMask authentication is not supported when using the **Clerk Chrome Extension SDK**, as it cannot load third-party code per Chrome Web Store policies. ## Enable MetaMask as a Web3 provider 1. In the Clerk Dashboard, navigate to the [**Web3**](https://dashboard.clerk.com/~/user-authentication/web3) page. 2. From the list of web3 providers, enable **MetaMask**. 3. Download the [Metamask plugin](https://metamask.io/download/) and install it on your browser to ensure a seamless login flow. ## Test authentication The simplest way to test authentication is to visit your Clerk application's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk applications out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to the **Sign-in** URL, select **Visit**. The URL should resemble: * **For development** – `https://your-domain.accounts.dev/sign-in` * **For production** – `https://accounts.your-domain.com/sign-in` 3. On the sign-in page, you should see **MetaMask** as an option. Use it to sign in. ## Collect additional user information during sign-up (optional) Web3 applications typically use a hexadecimal wallet address to identify users, which offers a high level of privacy. However, when bridging the gap between Web3 and Web2, it's often necessary to gather human-readable information about the user, such as their email address, phone number, or a username. To collect additional information about your user during sign-up: 1. In the Clerk Dashboard, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page. 2. On this page, enable the attributes you want to collect from your user during sign-up. ## Connect MetaMask to existing account Users can connect their MetaMask Wallet to their account at any time through their user profile page. You can configure your application to use the [Account Portal user profile page](/docs/guides/customizing-clerk/account-portal#user-profile) or the prebuilt \ component. --- title: OKX Wallet description: Learn how to set up Web3 authentication with OKX Wallet. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/web3/okx-wallet sourceFile: /docs/guides/configure/auth-strategies/web3/okx-wallet.mdx --- Enabling [OKX Wallet](https://www.okx.com/web3/rewritethesystem) as a Web3 provider allows your users to sign in and up to your Clerk application with their OKX Wallet. ## Enable OKX Wallet as a Web3 provider 1. In the Clerk Dashboard, navigate to the [**Web3**](https://dashboard.clerk.com/~/user-authentication/web3) page. 2. From the list of web3 providers, enable **OKX Wallet**. ## Test authentication The simplest way to test authentication is to visit your Clerk application's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk applications out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to the **Sign-in** URL, select **Visit**. The URL should resemble: * **For development** – `https://your-domain.accounts.dev/sign-in` * **For production** – `https://accounts.your-domain.com/sign-in` 3. On the sign-in page, you should see **OKX Wallet** as an option. Use it to sign in. ## Collect additional user information during sign-up (optional) Web3 applications typically use a hexadecimal wallet address to identify users, which offers a high level of privacy. However, when bridging the gap between Web3 and Web2, it's often necessary to gather human-readable information about the user, such as their email address, phone number, or a username. To collect additional information about your user during sign-up: 1. In the Clerk Dashboard, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page. 2. On this page, enable the attributes you want to collect from your user during sign-up. ## Connect OKX Wallet to existing account Users can connect their OKX Wallet to their account at any time through their user profile page. You can configure your application to use the [Account Portal user profile page](/docs/guides/customizing-clerk/account-portal#user-profile) or the prebuilt \ component. --- title: How Clerk implements OAuth description: Learn how to configure and secure OAuth flows with Clerk, including dynamic client registration, consent screens, PKCE, public clients, and scopes. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth sourceFile: /docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth.mdx --- Clerk supports secure, standards-compliant OAuth flows for your applications. You can create OAuth apps, enable dynamic client registration, manage consent screens, and configure public clients. This guide covers all key OAuth features and configurations in Clerk and helps you set up the right OAuth flow for your needs. ## Build an OAuth app with Clerk To create or edit an OAuth app, navigate to the [**OAuth applications**](https://dashboard.clerk.com/~/oauth-applications) page in the Clerk Dashboard. The following sections explain the available settings for configuring your OAuth app. ### Dynamic client registration In addition to configuring OAuth apps manually through the [Clerk Dashboard](https://dashboard.clerk.com/~/oauth-applications), Clerk supports [dynamic client registration](https://datatracker.ietf.org/doc/html/rfc7591), allowing OAuth clients to be created programmatically via a public API endpoint. To enable this feature, navigate to the [**OAuth applications**](https://dashboard.clerk.com/~/oauth-applications) page in the Clerk Dashboard and enable **Dynamic client registration**. > \[!CAUTION] > Dynamic client registration creates a public, unauthenticated endpoint that anyone can use to register OAuth clients with your authorization service. While this can enable use cases like multi-tenant SaaS platforms, developer marketplaces, and some MCP integrations, it also introduces significant security risks: > > * Attackers can create clients anonymously without audit trails. > * Malicious clients can use legitimate-sounding names to trick users. > * Administrative overhead increases substantially for monitoring and cleanup. > > In some use cases, dynamic client registration can be a requirement. However, it should only be enabled after carefully evaluating and accepting the associated security risks. > > Additionally, when dynamic client registration is enabled, the OAuth consent screen is automatically enforced and cannot be disabled - this prevents dangerous combinations that could lead to CSRF vulnerabilities. ### Scopes Scopes define the level of access and specific user data that will be shared with the client app during authentication. The following scopes are currently available: | Scope | Access | | - | - | | `profile` | Grant access to the user's personal information, such as first and last name, avatar, and username | | `email` | Grant access to the user's email address | | `public_metadata` | Grant access to the user's public and unsafe metadata | | `private_metadata` | Grant access to the user's private metadata | | `openid` | Enables the OpenID Connect flow | > \[!NOTE] > Support for adding custom OAuth scopes is **not yet available**, but development is underway. The goal is to allow custom scopes to be added, accepted, and checked through Clerk SDKs. An update will be provided when this feature is available. > > For early access to custom OAuth scopes, please vote or provide feedback on the [roadmap here](https://feedback.clerk.com/roadmap?id=d2d88be9-4d4f-45e6-997e-61d0b2a34bc9). ### Public clients and PKCE In OAuth flows where a private server environment is available, the server can store and use a `client_secret` to securely exchange an authorization code for an access token. However, in mobile apps or single-page apps (SPAs), there is often no private server-side environment available to store the `client_secret` and run this exchange. These are called **public clients** because they cannot securely store secrets. Any secret you embed in a mobile app can be extracted by someone with the right tools, and anything in a browser-based app is visible to anyone who opens the developer tools, as well as browser extensions, etc. To support these use cases, Clerk's OAuth implementation allows public clients to exchange an authorization code **without requiring a `client_secret`**. This makes it easier for mobile and browser-based apps to complete the token exchange and retrieve access and refresh tokens, without the risk of exposing long-lived secrets. However, this process means **public clients** often need an additional layer of security to protect against interception attacks. This is where **[PKCE (Proof Key for Code Exchange)](https://datatracker.ietf.org/doc/html/rfc7636)** comes in - PKCE helps secure public clients by replacing the `client_secret` with a dynamically generated proof that **only the client who started the OAuth flow can provide**. Here's how it works: instead of relying on a pre-shared secret, the client generates a random value called a **code verifier** at the start of each OAuth flow, along with a **code challenge**, which is a hashed version of the code verifier. The client sends the code challenge when starting the authorization flow, and later, during the token exchange, sends the original code verifier to prove it initiated the flow. The authorization service can then hash the code verifier to ensure it matches the code challenge. This ensures that even if an attacker intercepts the authorization code, they can't complete the token exchange without the original code verifier. Only the client that started the flow has that value. > \[!QUIZ] > Couldn't an attacker just steal the `code_verifier` from the browser (like from sessionStorage)? > > *** > > The key difference is *timing* and *access*. > > The `code_verifier` only exists for the brief duration of the OAuth flow and is only accessible to the specific app that created it. A `client_secret`, on the other hand, would be permanently embedded in the app code where it could be extracted by anyone. > > Additionally, each PKCE flow uses a unique `code_verifier`, so even if one was somehow compromised, it couldn't be reused for other users or future flows. To enable PKCE for a public client, you can enable the **Public** option for each OAuth app [in the Clerk Dashboard](https://dashboard.clerk.com/~/oauth-applications). ### Consent screen management The OAuth consent screen shows users a confirmation dialog before they authorize OAuth applications. It ensures users understand *exactly* what permissions they're granting before completing the OAuth flow. **The consent screen displays:** * The requesting app's name and logo. * The name and logo of the app receiving the request. * The specific access scopes that are being requested, in user-friendly language. * Clear accept/deny options. ![OAuth Consent Screen](/docs/images/oauth/consent-screen.png){{ style: { maxWidth: '460px' } }} The consent screen is enabled by default for all OAuth apps. You can enable or disable the consent screen for each OAuth app [in the Clerk Dashboard](https://dashboard.clerk.com/~/oauth-applications). > \[!IMPORTANT] > Enabling the consent screen for all OAuth apps is **strongly recommended**. Without a consent screen, any logged-in user who visits an OAuth authorization URL automatically grants access to any requested scopes. The consent screen acts as a critical security checkpoint, preventing malicious apps from silently gaining access to user accounts. ## Token expiration and management * OAuth access tokens expire **after 1 day**. * Refresh tokens **never expire**. * Authorization codes expire **after 10 minutes**. * OIDC `id_token`s expire **after 1 day**. ## Authorization server metadata An important feature of modern OAuth 2.0 and OpenID Connect (OIDC) implementations is **authorization server metadata**. This is a standardized JSON document published by the authorization server that describes its configuration, supported features and endpoints. This metadata makes it easier for clients to automatically discover important endpoints and features without needing manual configuration. You can easily retrieve this metadata by loading your Clerk **Frontend API URL** with `/.well-known/oauth-authorization-server` appended to it. For example: * `https://verb-noun-00.clerk.accounts.dev/.well-known/oauth-authorization-server` for a development environment. * `https://clerk..com/.well-known/oauth-authorization-server` for a production environment. Your **Frontend API URL** can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. This endpoint exposes all relevant details in a standardized JSON format. A sample metadata document might look like this: ```json { "issuer": "https://well-hagfish-71.clerk.accounts.dev", "authorization_endpoint": "https://well-hagfish-71.clerk.accounts.dev/oauth/authorize", "token_endpoint": "https://well-hagfish-71.clerk.accounts.dev/oauth/token", "jwks_uri": "https://well-hagfish-71.clerk.accounts.dev/.well-known/jwks.json", "response_types_supported": ["code"], "grant_types_supported": ["authorization_code", "refresh_token"], "token_endpoint_auth_methods_supported": ["client_secret_basic", "none"], "scopes_supported": ["openid", "profile", "email", "public_metadata", "private_metadata"], "subject_types_supported": ["public"], "id_token_signing_alg_values_supported": ["RS256"], "claims_supported": ["sub", "iss", "aud", "exp", "iat", "email", "name"], "service_documentation": "https://clerk.com/docs", "ui_locales_supported": ["en"], "op_tos_uri": "https://clerk.com/legal/standard-terms", "code_challenge_methods_supported": ["S256"] } ``` --- title: OAuth and OIDC overview description: Learn what OAuth and OpenID Connect (OIDC) are, why they're used, and how the different OAuth flows work. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/oauth/overview sourceFile: /docs/guides/configure/auth-strategies/oauth/overview.mdx --- **[OAuth (Open Authorization)](https://oauth.net/2/)** is a widely adopted standard designed by the **[IETF](https://www.ietf.org/)** to provide a secure way for users to grant third-party applications limited access to their data and resources without providing their login credentials directly. This guide explains the fundamentals of OAuth using practical examples and outlines its different use cases, helping developers navigate the complexities of implementing OAuth in modern apps. > \[!NOTE] > For a more in-depth version of this guide, see the [Clerk blog post](https://clerk.com/blog/how-oauth-works). ## What is OAuth? OAuth enables users to grant applications access to their resources without sharing their username and password directly. This ensures secure, limited, and auditable access. For example, consider a brand manager who wants to schedule marketing content to be published across various social platforms, such as LinkedIn, Twitter, or Facebook. Many content management tools exist to help with this but they would need permission to post on the manager's behalf. Let's say the brand manager is using a fictional content management tool called "Content Planner". Rather than asking for a username and password for each social media platform, which could compromise account security, OAuth allows Content Planner to request limited permissions (such as posting content) while restricting sensitive actions like deleting the account or changing the password. > \[!QUIZ] > Why not use credentials directly? > > *** > > Using credentials directly is both insecure and impractical for the following reasons: > > * **Limited access and security**: users typically do not want to grant full access to their accounts. Granting full access would violate the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege), aiming to minimize potential damage in case of a security incident. OAuth allows apps to request only the permissions they truly need, reducing security risks. > > * **Automated logins and security controls**: even if an app had your credentials, it would need to sign in as you through an automated script. However, many authentication systems detect and block scripted logins to protect against bots and abuse. OAuth provides a standardized way to grant access without bypassing these controls. > > * **Modern authentication**: many platforms now require additional security measures beyond just a username and password, such as multi-factor authentication (MFA), one-time passwords (OTPs), or passkeys. OAuth is designed to work with these modern authentication methods, ensuring secure access without compromising the user's account. ## Key terminology Before diving deeper, it's essential to understand some common terminology around OAuth: * **Client**: The application requesting access to a user's data/resources. For example, in the earlier scenario, Content Planner acts as the **client**, since it needs permission to make posts from Twitter, Facebook, LinkedIn, etc. * **Authorization service (or Identity Provider, IdP)**: The service responsible for authenticating the user and granting third-party apps access to a user's account, based on user consent. For instance, Twitter's auth service manages this process for apps wanting to access Twitter resources. This is also known as an **authorization server** or **Identity Provider (IdP)**. * **Resource service (or Service Provider, SP)**: The service that holds the data or resources the **client** wants to access. Following the same example, Twitter's API would be the resource service. This is sometimes referred to as a **resource server** or **Service Provider (SP)**. * **OAuth access token**: A randomly generated string or JSON Web Token (JWT) that is given to the **client** by the **authorization service** if the OAuth process is completed successfully. The client can then send this token to the **resource service** to be allowed to access the relevant resources and data. * **Scopes**: Permissions that define which specific actions or data a **client** can access on the **resource service** on behalf of the user. For example, a **scope** might allow readings emails but not sending them. Scopes are requested by the client during the OAuth flow and are displayed to the user, usually via a consent screen. ## OAuth flow overview Here is what a typical OAuth flow, known as the [Authorization Code Flow](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1), looks like: 1. The user selects a "Connect" or "Sign in with" option in your app. 2. They're redirected to the OAuth provider's authorization page. 3. After they approve the request, the provider redirects them back to your app with a short-lived authorization code. 4. Your server exchanges this code (along with the **client\_id** and **client\_secret**) for an access token. 5. Your app can now use this access token to make authorized requests on behalf of the user. ![OAuth flow diagram](/docs/images/oauth/oauth-flow-diagram.jpg) > \[!QUIZ] > Why does this happen in two steps? Why return an "authorization code" and not just send back the OAuth token to save time and resources? > > *** > > The answer is security. If the token was returned directly in the browser, it could show up in browser history, be intercepted by browser extensions, or leak through network logs. Instead, this flow ensures that the sensitive access token is only shared in a server-to-server request, away from the browser. > > Additionally, any attacker with only the Client ID, which is **not** a sensitive or secret value that's already exposed to the browser, could obtain an OAuth token without any client verification, significantly compromising the security of your app. > > This is why OAuth flows rely on both a Client ID and a Client Secret. While the Client ID is safe to expose publicly, the Client Secret must remain confidential. It should never be sent through the browser and is only used in secure, server-to-server requests between your client backend and the authorization service. > > In environments without a secure server such as mobile apps or SPAs, a Client Secret can't be safely stored. In this case, [PKCE (Proof Key for Code Exchange)](https://datatracker.ietf.org/doc/html/rfc7636) can be used to improve security by ensuring only the client that requested the authorization code can exchange it. To learn more, see the [dedicated section on PKCE](/docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth#public-clients-and-pkce). ## OAuth use cases 1. **OAuth Scoped Access**: granting a third-party app limited access to a user's data through Clerk's API, given the user's consent. This is the use case described in the diagram above. If you'd like to implement this flow, see the [Use OAuth for scoped access guide](/docs/guides/configure/auth-strategies/oauth/scoped-access). 2. **OAuth Single Sign-On (SSO)**: allowing users to sign up/sign in to an app using a third-party provider (e.g. "Sign in with Google"). If you'd like to implement this flow, see the [Use OAuth for SSO guide](/docs/guides/configure/auth-strategies/oauth/single-sign-on). 3. **OAuth User Management**: using OAuth as a full user registration and sign-in/out mechanism (a full authorization service built with OAuth). **Please note this is not currently supported by Clerk**, as we use [our own architecture](/docs/guides/how-clerk-works/overview) for user management. ## OpenID Connect (OIDC) [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works/) is an extension to OAuth written and maintained by a different standards committee, the [OpenID Foundation](https://openid.net/foundation/). Built on top of OAuth 2.0 and often used with it, OIDC provides a simple, reliable process for a **client** to verify the authenticating user's identity and retrieve basic user details as part of the OAuth flow. The key addition that OIDC makes to OAuth is that, when returning the access and refresh tokens, as long as an `openid` scope is included, the authorization server should also return an additional property called `id_token`. This ID token is a JSON Web Token (JWT) containing basic user information such as name, email, and profile photo, helping the client identify the user who just went through the flow. Without OIDC, the client would need to use the access token to make another request to a separate API endpoint to retrieve user details. With OIDC, this extra step can be skipped since the user information is already included in the initial OAuth response. For more details on how Clerk supports OAuth & OIDC, including features and configuration options, refer to the [OAuth reference documentation](/docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth). --- title: Use OAuth for scoped access description: Learn how to use OAuth with Clerk to grant granular permissions and manage access securely. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/oauth/scoped-access sourceFile: /docs/guides/configure/auth-strategies/oauth/scoped-access.mdx --- Clerk's OAuth implementation supports **OAuth scoped access**, which lets third-party applications request limited access to specific parts of a user's data through Clerk's API. This enables applications to interact with user data in a secure and controlled manner, based on the user's explicit consent. The most common implementation of OAuth scoped access is the "[Authorization Code Flow](https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1)", which is the flow covered in this guide. ## How the flow works Before diving into implementations details, it's important to understand the different actors involved in this flow: * **Client**: The third-party app that wants to access a user's data from your application (resource service). This app is configured to obtain OAuth tokens from Clerk. * **Authorization service (or Identity Provider, IdP)**: The service that authenticates the user and grants the OAuth tokens. In this example, Clerk would be the authorization service or IdP. * **Resource service (or Service Provider, SP)**: The backend server that hosts the user's data that the **client** wants to access. In this example, this would be **your own application** that uses Clerk for authentication and route protection. > \[!NOTE] > If you would like to know more about the terminology around OAuth, check out the [OAuth terminology guide](/docs/guides/configure/auth-strategies/oauth/overview#key-terminology). This guide provides step-by-step instructions on how to build OAuth scoped access into a Clerk app. ### Create a Clerk OAuth application To create a Clerk OAuth application: 1. In the Clerk Dashboard, navigate to the [**OAuth Applications**](https://dashboard.clerk.com/~/oauth-applications) page. 2. Select **Add OAuth application**. A modal will open. 3. Complete the following fields: * `Name` - Helps you identify your application. * `Scopes` - The scopes that you would like to leverage. [Learn more about the scopes currently supported by Clerk](/docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth#scopes). 4. Select **Add**. A modal will open with your **Client Secret**. For security reasons, Clerk does not store your Client Secret and cannot show it to you again, so **ensure that you copy it and store it somewhere secure**, like an environment variable. 5. You'll be redirected to your app's settings page. Under **Application credentials**, save the **Client ID** somewhere secure as you'll need it later. 6. In the **Redirect URIs** field, add the redirect URI provided by your client. This is the URL that Clerk will redirect to with an authorization code after the user has authenticated and consented to the access request. This guide uses `http://localhost:3000/oauth_callback` as an example. To learn more about the other OAuth application configuration settings, like **Dynamic client registration**, see the [dedicated guide](/docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth). ### Test the OAuth flow If you are aiming to integrate your Clerk app with a third-party app that acts as an OAuth client, you can reference their documentation on how to integrate OAuth connections in order to test your OAuth flow. It will likely be necessary to provide the `client_id` and `client_secret` from the OAuth app created above. If you don't have a specific, existing OAuth client in mind, you can use the following [OAuth test client](https://github.com/clerk/test-oauth-client) project. It contains a minimal Express.js server that can run through an OAuth flow. Let's walk through how to use this test client below. > \[!NOTE] > This implementation follows [the OAuth specification](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13), and is not specific to Clerk or this test project. Any compliant OAuth client will behave the same way. 1. Clone the [following repository](https://github.com/clerk/test-oauth-client) to your machine. 2. In your terminal and within your project, run the following command: ```sh {{ filename: 'terminal' }} cp .env.sample .env ``` 3. In your newly created `.env` file, add the required credentials: * `CLERK_PUBLISHABLE_KEY`: Your Clerk Publishable Key from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. * `CLIENT_ID`: The client ID of your OAuth app from the Clerk Dashboard. * `CLIENT_SECRET`: The client secret of your OAuth app from the Clerk Dashboard. 4. In your terminal, run the following command to install dependencies: ```sh {{ filename: 'terminal' }} npm i ``` 5. In your terminal, run the following command to start the server: ```sh {{ filename: 'terminal' }} npm start ``` ### Finished 🎉 Once this is complete, you'll be able to see the OAuth flow begin. If you are not currently signed in, you'll first be presented with a sign in screen. After signing in, Clerk will redirect to an OAuth consent screen, showing the requested scopes and asking for your consent. > \[!NOTE] > The consent screen uses the scopes passed in the authorization request to inform the user exactly what they're granting access to, and to whom. > > By default, the consent screen is shown for all newly created OAuth apps, but this can be disabled in each app's settings [in the Clerk Dashboard](https://dashboard.clerk.com/~/oauth-applications), although not recommended. [Learn more about how Clerk's OAuth consent screen works](/docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth#consent-screen-management). Once you have accepted, you'll be redirected to the OAuth callback route, the `redirect_uri` specified earlier. This process will exchange the authorization code for an access token, and return the access token and refresh token as a JSON response, similar to this: ```json { "access_token": "xxx", "expires_in": 7200, "id_token": "xxx", "refresh_token": "xxx", "scope": "openid email profile", "token_type": "bearer" } ``` With the OAuth flow complete, the client now has a working access token. The next step would normally be for the client to use that token to make an authenticated request to your app's API endpoints. To learn more about how to accept and verify OAuth tokens using Clerk, see the guide on [verifying OAuth tokens](/docs/guides/configure/auth-strategies/oauth/verify-oauth-tokens). --- title: Use OAuth for Single Sign-On (SSO) description: Learn how to implement single sign-on with OAuth & OpenID Connect in your Clerk application or when signing into a third-party app. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/oauth/single-sign-on sourceFile: /docs/guides/configure/auth-strategies/oauth/single-sign-on.mdx --- Clerk supports two primary Single Sign-On (SSO) options using OAuth: * Authenticate users into your Clerk application using external social providers (e.g. Google) * Enable users to sign in to third-party apps using Clerk as an Identity Provider (IdP) These features help you streamline authentication for your users, whether they're signing into your Clerk-powered app or accessing external apps with their Clerk credentials. This guide covers both options in detail and provides links to additional resources where applicable. ## Option 1: Let users authenticate into your Clerk application with social providers This feature allows users to sign up/sign in to your Clerk app using their existing credentials from popular social providers, also known as IdPs, like Google, Facebook, or GitHub. For example, if you enable GitHub as a social provider, then a user can sign in to your Clerk app by selecting GitHub as an option and authenticating with their GitHub account credentials. Refer to the appropriate provider's [guide](/docs/guides/configure/auth-strategies/social-connections/overview) for implementation details. ## Option 2: Let users authenticate into third-party applications using Clerk as an Identity Provider (IdP) Clerk can be configured as an OAuth 2.0 and OpenID Connect (OIDC) IdP to enable Single Sign-On (SSO) with other clients that support these protocols. This feature allows users to authenticate to other applications using their Clerk credentials, enabling user information sharing between your Clerk app and OAuth clients. For example, if your user wants to sign in to a third-party app, they can select Clerk as the IdP and use their Clerk credentials to sign in. It's similar to the first option, but in reverse: instead of using an external app to authenticate into your Clerk app, users use their Clerk credentials to sign in to an external app. ## Configure Clerk as an IdP In this case, Clerk is the IdP for your application. The [**client**](/docs/guides/configure/auth-strategies/oauth/overview#key-terminology) is the third party site or tool that you want your users to authenticate to. Here is the general flow to set up your Clerk instance as an OAuth provider: 1. Create a connection or integration in the client. 2. Create an OAuth application in Clerk and configure it. 3. Obtain the Client ID and Client Secret from Clerk. 4. Enter these credentials into the client to complete the integration. ### Create a connection or integration in the client Ensure you have setup a new connection within the third-party client or tool where your users will authenticate. As part of this process, you'll be provided a **redirect URL** that you'll need to use in the next step. ### Create a Clerk OAuth application To create a Clerk OAuth application: 1. In the Clerk Dashboard, navigate to the [**OAuth Applications**](https://dashboard.clerk.com/~/oauth-applications) page. 2. Select **Add OAuth application**. A modal will open. 3. Complete the following fields: * `Name` - Helps you identify your application. * `Scopes` - The scopes that you would like to leverage. [Learn more about the scopes currently supported by Clerk](/docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth#scopes). 4. Select **Add**. A modal will open with your **Client Secret**. For security reasons, Clerk does not store your Client Secret and cannot show it to you again, so **ensure that you copy it and store it somewhere secure**, like an environment variable. 5. You'll be redirected to your app's settings page. Under **Application credentials**, save the **Client ID** somewhere secure as you'll need it later. 6. In the **Redirect URIs** field, add the redirect URI/URL provided by your client [in the earlier step](#create-a-connection-or-integration-in-the-client). This is the URL that Clerk will redirect to after the user has authenticated. To learn more about the other OAuth application configuration settings, like **Dynamic client registration**, see the [dedicated guide](/docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth). ### Configure your client Once you have set up a Clerk OAuth app, you'll need to configure a few settings in your client to establish the connection. All the necessary information can be found in your Clerk OAuth app's settings, starting with two key parameters: * **Client ID**: Public identifier of your Clerk OAuth app. * **Client Secret**: Confidential secret used to authenticate your Clerk OAuth app. Both of these are available in your Clerk OAuth app's settings in the Clerk Dashboard. They need to be entered into your client's setup interface to complete the integration. Once completed, your users will be able to authenticate into your app using their Clerk credentials. Other available settings that may be useful include: * **Discovery URL**: Used by the client to retrieve the configuration data of the Clerk OAuth app. * **Authorize URL**: Used by the client to request authorization from your user. * **Token URL**: Used by the client to exchange an authorization code for an access token and a refresh token. * **User Info URL**: Used by the client to retrieve additional user data upon authentication. ## Get additional user information with the OAuth 2.0 flow After a user has successfully completed an OAuth 2.0 flow, you can retrieve additional user information from Clerk's [`/oauth/userinfo`](/docs/reference/frontend-api/tag/oauth2-identify-provider/post/oauth/userinfo){{ target: '_blank' }} endpoint. When making the request to this endpoint, you must include the OAuth access token in the `Authorization` header. This example is written for Next.js App Router **but can be adapted for any framework/language**. It assumes the OAuth flow has already been completed and that you have obtained an access token from Clerk. ```tsx {{ filename: 'app/api/userinfo/route.ts' }} import { NextResponse } from 'next/server' export async function GET() { // Assume you already have the access token available here const accessToken = 'YOUR_ACCESS_TOKEN_HERE' try { // Your Frontend API URL can be found on the API keys page in the Clerk Dashboard // https://dashboard.clerk.com/~/api-keys const response = await fetch(`${process.env.CLERK_FRONTEND_API_URL}/oauth/userinfo`, { headers: { // Include the access token as a Bearer token in the Authorization header Authorization: `Bearer ${accessToken}`, }, }) if (!response.ok) { const errorData = await response.json() return NextResponse.json(errorData, { status: response.status }) } const data = await response.json() return NextResponse.json(data) } catch (error: unknown) { return NextResponse.json( { error: 'Failed to fetch user info', details: (error as Error).message }, { status: 500 }, ) } } ``` **Example response** ```json { "object": "string", "instance_id": "string", "user_id": "string", "sub": "string", "email": "string", "email_verified": true, "family_name": "string", "given_name": "string", "name": "string", "username": "string", "preferred_username": "string", "picture": "string", "public_metadata": {}, "private_metadata": {}, "unsafe_metadata": {} } ``` The `/oauth/userinfo` endpoint provides the following user properties, depending on the granted scopes: | Property | Description | | - | - | | `user_id` | The ID of the user | | `sub` | The ID of the user | | `given_name` | The user's first name | | `family_name` | The user's last name | | `name` | The user's full name | | `picture` | The user's avatar URL | | `preferred_username` | The user's username | | `email` | The user's primary email address | | `email_verified` | Whether the user's primary email address is verified | | `public_metadata` | The user's public metadata | | `private_metadata` | The user's private metadata | | `unsafe_metadata` | The user's unsafe metadata | ### Get token information For validating access tokens or refresh tokens and retrieving additional token metadata, Clerk provides a standard OAuth 2.0 [Token Introspection Endpoint](https://datatracker.ietf.org/doc/html/rfc7662) at [`/oauth/token_info`](/docs/reference/frontend-api/tag/oauth2-identify-provider/post/oauth/token_info){{ target: '_blank' }}. The endpoint returns detailed token information such as if the token is still active, the client ID, and the granted scopes. > \[!WARNING] > This endpoint is protected. You must provide your Clerk Client ID and Client Secret credentials to authenticate. This example is written for Next.js App Router **but can be adapted for any framework/language**. It demonstrates how to call the `/oauth/token_info` endpoint, assuming you already have the access token and refresh token available. ```tsx {{ filename: 'app/api/tokeninfo/route.ts' }} import { NextRequest, NextResponse } from 'next/server' // Assume you already have the access token and refresh token available here const tokens = { accessToken: 'YOUR_ACCESS_TOKEN_HERE', refreshToken: 'YOUR_REFRESH_TOKEN_HERE', } export async function POST(req: NextRequest) { try { // Your Frontend API URL can be found on the API keys page in the Clerk Dashboard // https://dashboard.clerk.com/~/api-keys const response = await fetch(`${process.env.CLERK_FRONTEND_API_URL}/oauth/token_info`, { method: 'POST', headers: { // Include the access token as a Bearer token in the Authorization header Authorization: `Bearer ${tokens.accessToken}`, 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ // Include the refresh token in the body token: tokens.refreshToken, }), }) if (!response.ok) { return NextResponse.json({ error: 'Failed to fetch token info' }, { status: response.status }) } const data = await response.json() return NextResponse.json(data) } catch (error) { return NextResponse.json({ error: 'Internal server error' }, { status: 500 }) } } ``` **Example response** ```json { "active": true, "client_id": "string", "iat": 0, "scope": "string", "sub": "string" } ``` ## Get additional user information with the OAuth 2.0 flow using the OpenID Connect (OIDC) protocol > \[!IMPORTANT] > Not all third-party apps expect or use OIDC. However, this feature was designed with OIDC compatibility in mind, which is why it's included in this guide. Ensure that your integration target supports OIDC before proceeding. In order to enable OIDC in your OAuth flow, you can follow the same steps outlined above, but ensure to select the `openid` scope when configuring your OAuth app in the Clerk Dashboard. This scope triggers OIDC and instructs the authorization server to issue an ID token alongside your access token. You'll also need to include this `openid` scope in the query parameters of your authorization endpoint when initiating the OAuth flow. For example: ```http GET /oauth/authorize? client_id=x& response_type=code& state=y& code_challenge=z& redirect_uri=a& scope=openid%20profile%20email&... Host: clerk..com ``` Once a user successfully authenticates using the OIDC flow, you'll receive: * An **access token** * A **refresh token** * An **ID token** The ID token is a JWT (JSON Web Token) that contains standard JWT claims as defined in [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519), as well as additional custom claims that represent the authenticated user's profile information. The token is signed using your instance's private key. You must verify the signature on the ID token before using any of the user information it contains. This will require your instance's public key. You can find your instance's public key by loading your **Frontend API URL** with `/.well-known/jwks.json` appended to it. For example: * `https://verb-noun-00.clerk.accounts.dev/.well-known/jwks.json` for a development environment. * `https://clerk..com/.well-known/jwks.json` for a production environment. Your **Frontend API URL** can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. Here is an example verifying the ID token using the [`jsonwebtoken`](https://www.npmjs.com/package/jsonwebtoken) library in a production environment: ```js const jwt = require('jsonwebtoken') function verifyIdToken(idToken) { jwt.verify( idToken, PUBLIC_KEY, { algorithms: ['RS256'], issuer: 'https://clerk..com', audience: '', }, (err, decoded) => { if (err) { console.error('Token verification failed:', err) } else { console.log('Token is valid:', decoded) } }, ) } ``` The ID token includes the following standard claims: | Standard claim | Description | | - | - | | `iss` | The issuer of the token, which matches your Clerk Frontend API URL | | `sub` | The subject of the token, which matches the authenticated user ID | | `aud` | The intended audience of the token, which matches the used Client ID | | `exp` | The expiration time of the token | | `iat` | The time at which the token was issued | | `jti` | A unique identifier for the token | Depending on the granted scopes, the ID token can include the following additional claims: | Additional claim | Description | | - | - | | `nonce` | The nonce provided and used during the request | | `family_name` | The user's last name | | `given_name` | The user's first name | | `name` | The user's full name | | `picture` | The user's avatar URL | | `preferred_username` | The user's username | | `email` | The user's primary email address | | `email_verified` | Whether the user's primary email address is verified | | `public_metadata` | The user's public metadata | | `private_metadata` | The user's private metadata | | `unsafe_metadata` | The user's unsafe metadata | --- title: Verify OAuth tokens with Clerk description: Learn how to verify OAuth tokens in your applications. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/oauth/verify-oauth-tokens sourceFile: /docs/guides/configure/auth-strategies/oauth/verify-oauth-tokens.mdx --- If you are building an application that uses Clerk and would like to incorporate OAuth, you'll want to ensure that after the [**client**](/docs/guides/configure/auth-strategies/oauth/overview#key-terminology) gets an OAuth access token, they can use it to make authenticated requests into your app (the [**resource service**](/docs/guides/configure/auth-strategies/oauth/overview#key-terminology)) using the token. > \[!NOTE] > OAuth tokens are machine tokens. Machine token usage is free during our public beta period but will be subject to pricing once generally available. Pricing is expected to be competitive and below market averages. Clerk's SDKs support this through the `acceptsToken` parameter that can be used in Clerk's route protection functions, such as auth(), auth.protect(), and authenticateRequest(). For examples and best practices on verifying OAuth tokens with Clerk SDKs, see our framework-specific guides for: * Next.js * React Router * Tanstack React Start You can also verify tokens manually via the [Clerk REST API](/docs/reference/backend-api/tag/oauth-access-tokens/post/oauth_applications/access_tokens/verify){{ target: '_blank' }}. Ensure you have your Clerk Secret Key on hand as you'll need to include it in the `Authorization` header; it can be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ```sh {{ filename: 'terminal' }} curl https://api.clerk.com/oauth_applications/access_tokens/verify \ -X POST \ -H 'Authorization: Bearer your-clerk-secret-key-here' \ -H 'Content-Type: application/json' \ -d '{ "access_token": "your-oauth-token-here" }' ``` --- title: Account linking description: Learn how Clerk handles account linking during Enterprise SSO. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/account-linking sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/account-linking.mdx --- Account linking is the process of connecting multiple user accounts from different services or platforms, allowing users to access various services with a single set of credentials. It enables seamless sign-in using Enterprise SSO alongside other authentication methods like username/password. Clerk automatically attempts to link accounts that share the same email address, assuming a single owner for each email. ## How it works When a user attempts to sign in or up, Clerk checks if the email address from the Identity Provider (IdP) matches an existing account and attempts to link them. Email addresses from IdPs are considered verified by default. The following sections explain the different scenarios that can occur during this process and how Clerk handles each one. ![Flow chart of the SAML SSO account linking process in various scenarios.](/docs/images/authentication/account-linking-flow-saml.webp) ### Email is verified in Clerk When a user signs into your app using an IdP that returns a matching verified email address, Clerk automatically links the Enterprise SSO account to the existing account and completes the sign-in process. This includes accounts protected by passwords, as the Enterprise SSO sign-in flow automatically bypasses password verification. ### Email is not verified and verification isn't required By default, Clerk requires email verification at sign-up. For instances that have disabled this behavior, there's a possibility that an account may be created using an unverified email address. To configure email verification at sign-up: 1. In the Clerk Dashboard, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page. 2. Under **Email**, ensure **Verify at sign-up** is enabled. When a user signs into your app using an IdP, Clerk automatically links the Enterprise SSO account to the existing account by **also verifying the existing email address** and signing the user in. This includes accounts protected by passwords, as the Enterprise SSO sign-in flow automatically bypasses password verification. ### Email is not verified When a user signs into your app using an IdP that returns a matching unverified email address, Clerk doesn't link the Enterprise SSO account to the existing account, but instead signs the user up and creates a completely new account. --- title: Enterprise SSO authentication flows description: Learn about the Enterprise SSO authentication flows. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/authentication-flows sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/authentication-flows.mdx --- Clerk offers the following types of Enterprise SSO connections: [SAML](#saml), [OIDC](#oidc), and [EASIE](#easie). ## SAML The SAML protocol supports two methods to start an SSO flow: [Service Provider-initiated (SP-initiated)](#service-provider-initiated-flow-recommended) and [Identity Provider-initiated (IdP-initiated)](#identity-provider-initiated-flow). For the best security practices, it's recommended to use the SP-initiated flow wherever possible. If you decide to enable IdP-initiated flows, ensure that proper [security measures](#clerks-security-measures), such as MFA and short validation periods, are in place to mitigate the associated risks. ### Service Provider-initiated flow (recommended) In an SP-initiated flow: * The user starts the authentication process from your application (Service Provider, or SP), by providing their email address. * The user is redirected to the SAML provider (Identity Provider, or IdP) where they must authenticate. * After successful authentication, the user is redirected back to your app, gaining access to their account. ### Identity Provider-initiated flow In an IdP-initiated flow: * The user starts the authentication flow from the SAML provider (IdP) by selecting which app (SP) they want to access. * The user is redirected to the app of their choice, gaining access to their account. > \[!NOTE] > IdP-Initiated flow carries a [security risk](#risks-of-id-p-initiated-flow). It is recommended to use an SP-Initiated flow whenever possible. To allow IdP-initiated flows for your SAML connection: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Select your **Identity Provider**. Complete the fields and select **Add connection**. You'll be redirected to the SAML connection's configuration page. 4. Select the **Advanced** tab. 5. In **Advanced Settings**, enable **Allow IdP-Initiated flow**. A modal will open. Select **Enable** to confirm. 6. Select **Save**. #### Risks of IdP-initiated flow While IdP-initiated flows might offer convenience, they are also susceptible to security risks, such as [meddler-in-the-middle (MITM) attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). A bad actor might hijack the IdP response to gain access to a compromised account. When enabling an IdP-initiated flow, it's possible for Clerk to receive unsolicited authentication requests, which neither the SP nor IdP can verify were initiated by the specified user. Additionally, a bad actor could intercept the IdP response and replace it, performing a CSRF attack to sign in as the attacker. #### Clerk's security measures To mitigate the risks associated with IdP-initiated flows, Clerk implements several security measures: * **Unsolicited `InResponseTo` attribute**: Clerk ensures that unsolicited responses don't contain an `InResponseTo` attribute, in accordance with the [SAML 2.0 profiles specification](https://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf). This prevents bad actors from stealing a response used in an SP-initiated flow and using it in an IdP-initiated flow. * **Replay detection**: Clerk consumes and remembers each response to prevent re-use. This ensures that bad actors cannot steal and reuse a response to gain access to a user's account. * **Multi-factor authentication**: Clerk supports [multi-factor authentication (MFA)](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) for SAML IdP-initiated flows. MFA requires users to provide two or more forms of verification, which significantly enhances security by reducing the risk of unauthorized access. * **Use small validation periods**: Each SAML response contains a timestamp indicating when it was issued and when it will expire. Since IdP-initiated flows are expected to be completed within seconds, validation periods must be as small as possible to prevent attacks. Common IdP providers such as Azure, Google, and Okta handle this by default. However, if you're using a custom IdP, you must ensure that the validation periods are set correctly. ## OIDC Clerk supports Enterprise SSO via the OpenID Connect (OIDC) protocol, either through [EASIE](#easie) or by [integrating with any OIDC-compatible provider](/docs/guides/configure/auth-strategies/enterprise-connections/oidc/custom-provider). ### EASIE EASIE connections support the authentication flows described at [easie.dev](https://easie.dev). --- title: Just-in-Time (JIT) Provisioning during SAML SSO description: Learn about Clerk's support for Just-in-Time (JIT) Provisioning during SAML SSO. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/jit-provisioning sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/jit-provisioning.mdx --- Just-in-Time (JIT) Provisioning, or automatic account provisioning, is a process by which accounts for employees are created on-demand during the first time they authenticate via SAML SSO in your application. Using JIT Provisioning means your IT department won't have to manually create user accounts for each of the services or apps your employees use to get work done. Clerk supports JIT account provisioning for all [supported SAML providers](/docs/guides/configure/auth-strategies/enterprise-connections/overview). Check your preferred SAML provider's documentation to enable JIT account provisioning on their side. ## Sync user attributes during sign in During SAML SSO and after a user has successfully authenticated, the IdP provides Clerk with the corresponding user data. After each successful sign in, Clerk handles keeping the user data up-to-date based on the response of the SAML provider. This means that if a user's data changes on the IdP side, Clerk will automatically update the user's data in the Clerk database. To disable this behavior: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the SAML connection you want to disable the sync for. 3. Select the **Advanced** tab. 4. Toggle off the **Sync user attributes during Sign in** option. --- title: Enterprise Single Sign-On (SSO) description: Clerk provides Enterprise SSO to authenticate users via federated Identity Providers such such as Azure AD, Okta, Google Workspace and more. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/overview sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/overview.mdx --- Enterprise Single Sign-On (SSO) allows users to sign in seamlessly using their Identity Provider (IdP) credentials (e.g.,Azure AD, Okta, or Google Workspace) and have their user data synchronized with Clerk. Clerk supports multiple protocols for implementing Enterprise SSO, including SAML and OIDC. Learn more about the process in the guides on [authentication flows](/docs/guides/configure/auth-strategies/enterprise-connections/authentication-flows) and [account linking](/docs/guides/configure/auth-strategies/enterprise-connections/account-linking). ## SAML Clerk supports Enterprise SSO via the SAML protocol, enabling you to create authentication strategies for an IdP. The following IdPs are supported: [Microsoft Azure AD](/docs/guides/configure/auth-strategies/enterprise-connections/saml/azure), [Google Workspace](/docs/guides/configure/auth-strategies/enterprise-connections/saml/google), and [Okta Workforce](/docs/guides/configure/auth-strategies/enterprise-connections/saml/okta). However, you can also [integrate with any other IdP](/docs/guides/configure/auth-strategies/enterprise-connections/saml/custom-provider) that supports the SAML protocol. ### Allow subdomains Authenticating via SAML SSO requires the user's email address domain to match the exact domain the SAML connection has been configured with. By default, subdomains are not supported. For example, a user with the email address `john@sales.example.com` wouldn't be able to use a SAML connection with the `example.com` domain to authenticate. To configure subdomains for a SAML connection: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the SAML connection you want to allow subdomains for. 3. Select the **Advanced** tab. 4. Enable or disable the **Allow subdomains** option. 5. Select **Save**. > \[!NOTE] > To enable the **Allow subdomains** option, your SAML connection domain must be an [eTLD+1](https://developer.mozilla.org/en-US/docs/Glossary/eTLD). ### Native applications Clerk ensures that security critical nonces are passed only to allowlisted URLs when the SSO flow is completed in native browsers or webviews. For maximum security in your **production** instances, you need to allowlist your custom redirect URLs via the [Clerk Dashboard](https://dashboard.clerk.com/) or the Clerk Backend API. To allowlist a redirect URL via the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Native applications**](https://dashboard.clerk.com/~/native-applications) page. 2. Scroll down to the **Allowlist for mobile SSO redirect** section. 3. Under **Redirect URLs**, paste your the URL and select **Add**. ## OIDC Clerk supports Enterprise SSO via the OpenID Connect (OIDC) protocol, either through [EASIE](#easie) or by [integrating with any OIDC-compatible provider](/docs/guides/configure/auth-strategies/enterprise-connections/oidc/custom-provider). ### EASIE [EASIE](https://easie.dev) SSO is a way for applications to provide enterprise-grade SSO through a multi-tenant OpenID provider. It is designed to be an easier alternative to SAML SSO. The following IdPs are supported: Google Workspace and Microsoft Entra ID. For *development instances*, Clerk uses preconfigured shared credentials and redirect URIs—no other configuration is needed. For *production instances*, you must provide custom credentials. Follow the steps outlined in the guides to complete the setup: * [Google](/docs/guides/configure/auth-strategies/enterprise-connections/easie/google) * [Microsoft](/docs/guides/configure/auth-strategies/enterprise-connections/easie/microsoft) #### Automatic deprovisioning Clerk prevents users linked to deprovisioned accounts in the OpenID provider from accessing the app. Before creating a new session token for an EASIE user, Clerk verifies whether the user has been deprovisioned from their OpenID provider (e.g., [suspended](https://support.google.com/a/answer/33312?hl=en) or [deleted](https://support.google.com/a/answer/33314?hl=en) in Google Workspace, or [deleted](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-create-delete-users#delete-a-user) in Microsoft Entra). This verification process might involve a delay of up to 10 minutes. If deprovisioning is detected, Clerk revokes that user's existing sessions and responds to any requests for a new session token with a `401 Unauthorized` error. It is ultimately the app's responsibility to handle this unauthenticated state and display something appropriate to the user. For example, Next.js apps using auth.protect() will automatically redirect the user to the sign-in page. ## SAML vs. EASIE The primary security difference between EASIE SSO and SAML SSO is that EASIE depends on a multi-tenant identity provider, while SAML depends on a single-tenant identity provider. Relying on a multi-tenant provider **increases** the risk that a user from one tenant will mistakenly be granted access to the resources of another tenant. While Clerk implements [measures to address this risk](https://easie.dev/#mitigating-tenant-crossover-vulnerabilities:~:text=4.%20Mitigating%20tenant%20crossover%20vulnerabilities), apps that require single-tenant IdPs should opt for SAML. For more information, see the [EASIE docs](https://easie.dev#security). ## Frequently asked questions (FAQ) ### Can I use multiple identifiers or authentication methods with enterprise connections? Yes, multiple identifiers (such as email, username, or other attributes) can be configured and used for SAML and OIDC connections. However, for EASIE connections, there can only be one identifier or authentication method. By default, additional identifiers are **disabled** for new connections. To enable multiple identifiers for a SAML or OIDC connection: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the enterprise connection you want to allow multiple identifiers for. 3. Select the **Advanced** tab. 4. Enable the **Allow additional identifiers** option. 5. Select **Save**. ### Will Enterprise SSO work for my existing users? Yes, Enterprise SSO will work for your existing users as well! If you enable SAML or EASIE, any existing users with an email address that matches the SAML or EASIE connection domain will have to authenticate on the IdP side and an Enterprise account will be linked to their existing account. ### What happens if I have multi-factor enabled at Clerk? Once the user returns from the IdP, they will need to complete additional authentication factors. This is useful if you want to add extra factors beyond what your IdP supports or if your IdP doesn’t support them. This feature is optional and can be disabled if not needed. ### What happens if I delete the Enterprise Connection? Will my users be deleted? The users will not be deleted, so your app will not break. However, they will need to use another [sign-in option](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) such as password or email codes to authenticate themselves moving forward. ### Does Clerk support IdP-initiated SSO? Yes, for SAML only. Clerk supports both Service Provider-initiated (SP-initiated) and Identity Provider-initiated (IdP-initiated) SSO flows. For more information, see the [authentication flows guide](/docs/guides/configure/auth-strategies/enterprise-connections/authentication-flows). ### How much does it cost? For development instances, Enterprise connections are always free but limited to a maximum of 25. Production instances require the Pro plan and the Enhanced Authentication Add-on. Please see [pricing](/pricing){{ target: '_blank' }} for more information. --- title: Add Google as an EASIE connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Google account using EASIE SSO. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/easie/google sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/easie/google.mdx --- Enabling [EASIE SSO](/docs/guides/configure/auth-strategies/enterprise-connections/overview#easie) with Google allows your users to sign up and sign in to your Clerk application with their Google account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Under **EASIE**, select **Google**. 4. Enter the **Domain**. This is the email domain of the users you want to allow to sign in to your application. Optionally, select an **Organization**. 5. Select **Add connection**. ## Configure for your production instance > \[!NOTE] > If you already [configured Google as a social provider](/docs/guides/configure/auth-strategies/social-connections/google), you can skip this step. EASIE SSO will automatically use the credentials you configured for your social connection. For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Google Cloud Console](https://console.cloud.google.com/). ### Enable Google as an EASIE connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Under **EASIE**, select **Google**. 4. Enter the **Domain**. This is the email domain of the users you want to allow to sign in to your application. Optionally, select an **Organization**. 5. Save the **Redirect URI** somewhere secure. Keep this modal open to enter the OAuth credentials in the following steps. ### Create a Google Developer project 1. Navigate to the [Google Cloud Console](https://console.cloud.google.com/). 2. Select a project or [create a new one](https://console.cloud.google.com/projectcreate). 3. If the **APIs & Services** page isn't already open, open the menu on the left and select **APIs & Services**. 4. In the left sidenav, select **Credentials**. 5. Select **Create Credentials**. Then, select **OAuth client ID.** You may need to [configure your OAuth consent screen](https://support.google.com/cloud/answer/6158849?hl=en#userconsent\&zippy=%2Cuser-consent). 6. Select the appropriate application type for your project. Most likely, you will choose **Web application**. 7. In the **Authorized redirect URIs** section, select **Add URI** and paste the **Redirect URI** value you saved from the Clerk Dashboard. 8. Select **Create**. ### Set the Client ID and Client Secret in the Clerk Dashboard Once the OAuth client is created in the Google Cloud Console, a modal will open with your **Client ID** and **Client Secret**. Save these values somewhere secure. Go back to the Clerk Dashboard, where the modal should still be open, and paste these values into the respective fields. Note that if you have any other Google EASIE connections or a [Google social connection](/docs/guides/configure/auth-strategies/social-connections/google), this will update the credentials for all of them. Select **Add connection**. --- title: Add Microsoft as an EASIE connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Microsoft account using EASIE SSO. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/easie/microsoft sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/easie/microsoft.mdx --- Enabling [EASIE SSO](/docs/guides/configure/auth-strategies/enterprise-connections/overview#easie) with Microsoft (formerly [Active Directory](https://learn.microsoft.com/en-us/entra/fundamentals/new-name)) allows your users to sign up and sign in to your Clerk application with their Microsoft account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Under **EASIE**, select **Microsoft**. 4. Enter the **Domain**. This is the email domain of the users you want to allow to sign in to your application. Optionally, select an **Organization**. 5. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. If you already [configured Microsoft as a social provider](/docs/guides/configure/auth-strategies/social-connections/microsoft), you can skip this step. EASIE SSO will automatically use the credentials you configured for your social connection. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Microsoft Azure portal](https://portal.azure.com). ### Enable Microsoft as an EASIE connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Under **EASIE**, select **Microsoft**. 4. Enter the **Domain**. This is the email domain of the users you want to allow to sign in to your application. Optionally, select an **Organization**. 5. Save the **Redirect URI** somewhere secure. Keep this modal and page open. ### Create a Microsoft Entra ID app > \[!TIP] > If you already have a Microsoft Entra ID app you'd like to connect to Clerk, select your app from the [Microsoft Azure portal](https://portal.azure.com/#home) and skip to [the next step in this tutorial](#get-your-client-id-and-client-secret). 1. On the homepage of the [Microsoft Azure portal](https://portal.azure.com/#home), in the **Azure services** section, select **[Microsoft Entra ID](https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/Overview)**. 2. In the sidenav, open the **Manage** dropdown and select **[App registrations](https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/RegisteredApps)**. 3. Select **New Registration**. You'll be redirected to the **Register an application** page. 4. Complete the form as follows: 1. Under **Name**, enter your app name. 2. Under **Supported account types**, select **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)**. 3. Under **Redirect URI (Optional)**, select **Web** as the platform and enter the **Redirect URI** you saved from the Clerk Dashboard. 4. Select **Register** to submit the form. You'll be redirected to the **Overview** page of your new app. Keep this page open. ### Get your Client ID and Client Secret 1. From your app's **Overview** page, save the **Application (client) ID** somewhere secure. 2. In the sidenav, select **Certificates & secrets**. 3. Select **New client secret**. 4. In the modal that opens, enter a description and set an expiration time for your secret. > \[!WARNING] > Microsoft requires an expiration time for client secrets. The default is 6 months, and the maximum is 24 months. When your secret expires, your social connection will stop working until you generate a new secret. It's recommended to set a reminder before the expiration date to avoid disruption to your sign-in flow. 5. Select **Add**. 6. Save the **Value** somewhere secure. ### Enable OpenID 1. In the left sidenav, open the **Manage** dropdown and select **Authentication**. 2. In the **Front-channel logout URL** field, paste the **Redirect URI** you copied from the Clerk Dashboard. 3. Under **Implicit grant and hybrid flows**, check both **Access tokens** and **ID tokens**. 4. Select **Save** to save the changes. ### Secure your app against the nOAuth vulnerability [nOAuth](https://www.descope.com/blog/post/noauth) is an exploit in Microsoft Entra ID OAuth apps that can lead to account takeovers via email address spoofing. Clerk mitigates this risk by enforcing stricter checks on verified email addresses. For further security, Microsoft offers an optional `xms_edov` [claim](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims-reference), which provides additional context to determine whether the returned email is verified. > \[!IMPORTANT] > When adding the `xms_edov` claim in the Azure portal, you may see a warning saying it's invalid or not recognized. You can safely ignore this warning - `xms_edov` is fully supported and documented by Microsoft Entra ID for stronger email domain verification, but the Azure portal's token configuration UI may not recognize it yet. To enable it, you must: 1. In the left sidenav, in the **Manage** dropdown, select **Token configuration**. 2. Select **Add optional claim**. 3. For the **Token type**, select **ID**. Then, in the table that opens, enable the `email` and `xms_pdl` claims. 4. At the bottom of the modal, select **Add**. A new modal will prompt you to turn on the Microsoft Graph email permission. Enable it, then select **Add** to complete the form. 5. Repeat the previous steps but for **Token type**, select **Access** instead of **ID**. The **Optional claims** list should now show two claims for `email` and two for `xms_pdl`: one each for **ID** and **Access**. 6. In the left sidenav, in the **Manage** dropdown, select **Manifest**. 7. In the text editor, search for `"acceptMappedClaims"` and set its value from `null` to `true`. 8. Search for `"optionalClaims"`, where you'll find the `idToken` and `accessToken` arrays. Each array has an object with the name `xms_pdl`. Change the name to `xms_edov`. 9. At the top of the page, select **Save**. 10. In the left sidenav, in the **Manage** dropdown, select **Token configuration** to confirm that the **Optional claims** list includes two claims for `email` and two for `xms_edov`: one each for **ID** and **Access**. With these steps complete, Microsoft will send the `xms_edov` claim in the token, which Clerk will use to determine whether the email is verified, even when used with Microsoft Entra ID. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Microsoft Entra ID as a SAML connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Microsoft account using SAML SSO. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/saml/azure sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/saml/azure.mdx --- Enabling SAML with Microsoft Entra ID (formerly [Azure Active Directory](https://learn.microsoft.com/en-us/entra/fundamentals/new-name)) allows your users to sign up and sign in to your Clerk application with their Microsoft account. It requires that a SAML connection is configured in both the Clerk Dashboard and Microsoft Entra ID. This guide assumes that you have access to the Clerk app's settings in the Clerk Dashboard. The "customer" in this case is whoever has access to the Microsoft Entra ID settings. ## Create a Microsoft Entra ID SAML connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Under **SAML**, select **Microsoft Entra ID (Formerly AD)**. 4. Enter the **Domain**. This is the email domain of the users you want to allow to sign in to your application. Optionally, select an **Organization**. 5. Enter the **Name**. This will be displayed on the sign-in form. 6. Select **Add connection**. You'll be redirected to the connection's configuration page. Note that the connection is disabled by default. 7. In the **Service Provider Configuration** section, save the **Reply URL (Assertion Consumer Service URL)** and **Identifier (Entity ID)** values somewhere secure. You'll need to give these to the customer so they can configure their Microsoft Entra ID application. ## Configure SAML application Now that the enterprise connection is configured in Clerk and the **Reply URL** and **Identifier** are known, the customer's Microsoft application needs to be configured. At a high level, the process is: * Create a new enterprise app in Microsoft Azure. * Assign selected users or groups to that Microsoft application. * Add the **Reply URL** and **Identifier** from Clerk to the Microsoft application's SAML configuration. * Verify that the attribute mappings are correct. * Obtain and share the application's metadata URL. You are welcome the use the below email template with detailed instructions. They contain the following template strings that you should replace with your actual values: * \[YOUR\_APPLICATION\_NAME] * \[YOUR\_CLERK\_ENTITY\_ID] * \[YOUR\_CLERK\_REPLY\_URL] Here are the instructions for setting up SAML SSO with Microsoft Entra ID: **Step 1: Create a new enterprise application in Microsoft** 1. Navigate to the [Microsoft Azure portal](https://azure.microsoft.com/en-us/get-started/azure-portal) and sign in. 2. Under the **Azure Services** section, find and select **Enterprise applications**. You may have to go to the [**All services**](https://portal.azure.com/#allservices) page and then scroll down to the **Identity** section to find it. 3. Select **New application**. You'll be redirected to the **Browse Microsoft Entra Gallery** page. 4. Select **Create your own application**. 5. In the modal that opens: * **Name** of your application (likely \[YOUR\_APPLICATION\_NAME]). * Select **Integrate any other application you don't find in the gallery (Non-gallery)**. * Select **Create**. **Step 2: Assign your users or groups in Microsoft** Now that you have created the enterprise app, you need to assign users or groups before they can use it to log in. Below are instructions for assigning an individual user, but for more options and instructions for groups, see Microsoft's docs [here](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/assign-user-or-group-access-portal?pivots=portal). 1. In the **Getting Started** section, select the **Assign users and groups** link. 2. Select **Add user/group**. You'll be redirected to the **Add Assignment** page. 3. Select the **None Selected** link. 4. To assign a user to the enterprise app, you can either use the search field to find a user or select the checkbox next to the user in the table. 5. Select **Select** at the bottom of the page. You'll be redirected to the **Add Assignment** page. 6. Select **Assign** at the bottom of the page. **Step 3: Set Basic SAML Configuration** 1. In the navigation sidenav, open the **Manage** dropdown and select **Single sign-on**. 2. In the **Select a single sign-on method** section, select **SAML**. You'll be redirected to the **Set up Single Sign-On with SAML** page. 3. Find the **Basic SAML Configuration** section. 4. Select **Edit**. The **Basic SAML Configuration** panel will open. 5. Add the following **Identifier (Entity ID)** and **Reply URL (Assertion Consumer Service URL)** values. These values will be saved automatically. * **Identifier (Entity ID)**: `[YOUR_CLERK_ENTITY_ID]` * **Reply URL (Assertion Consumer Service URL)**: `[YOUR_CLERK_REPLY_URL]` 6. Select **Save** at the top of the panel. Close the panel. **Step 4: Verify correct configuration of attributes and claims** We expect your SAML responses to have the following specific attributes: Email address (required). This is the email address that your users will use to authenticate into your app: * Claim name: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` * Value: `user.mail` First name (optional): * Claim name: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname` * Value: `user.givenname` Last name (optional): * Claim name: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname` * Value: `user.surname` These are the defaults, and probably won't need you to change them. However, many SAML configuration errors are due to incorrect attribute mappings, so it's worth double-checking. Here's how: 1. Still on the **Set up Single Sign-On with SAML** page, find the **Attributes & Claims** section. 2. Select **Edit**. 3. Verify that the above three attributes and values are present. **Step 5: Share the application's metadata URL** 1. Still on the **Set up Single Sign-On with SAML** page, find the **SAML Certificates** section. 2. Copy the **App Federation Metadata Url**, and reply to this email with it. This is the final piece of information we need to enable SAML. ## Add App Federation Metadata URL in the Clerk Dashboard After following the instructions in the email, your customer should have sent you the Microsoft app's **App Federation Metadata URL**. Now, you're going to add it to the Clerk connection, completing the SAML connection configuration. 1. Navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. 2. Select the SAML connection. 3. In the **Identity Provider Configuration** section, under **App Federation Metadata Url**, paste the **App Federation Metadata URL**. 4. Select **Fetch & save**. Keep the page open for the next step. ## Enable the connection in Clerk The SAML connection is ready to enable! Once enabled, all users with email addresses ending in the domain will be redirected to Microsoft at sign-up and sign-in. > \[!WARNING] > If there are existing users with email domains that match the SAML connection, and there is an error in the SAML configuration in Clerk or Microsoft, those users will be **unable to sign in** when the connection is enabled. If this is a concern, we recommend coordinating with your counterpart to test the connection at an off-peak time. To make the connection available for users to authenticate with: 1. Navigate back to the Clerk Dashboard where you should still have the connection's configuration page open. If not, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page and select the connection. 2. At the top of the page, toggle on **Enable connection** and select **Save**. --- title: Add a custom Identity Provider (IdP) as a SAML connection description: Learn how to integrate an Identity Provider (IdP) with Clerk using SAML SSO. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/saml/custom-provider sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/saml/custom-provider.mdx --- Clerk supports Enterprise SSO via the SAML protocol, enabling you to create authentication strategies for an Identity Provider (IdP). Currently, Clerk offers direct integrations with the following IdPs: [Microsoft Azure AD](/docs/guides/configure/auth-strategies/enterprise-connections/saml/azure), [Google Workspace](/docs/guides/configure/auth-strategies/enterprise-connections/saml/google), and [Okta Workforce](/docs/guides/configure/auth-strategies/enterprise-connections/saml/okta). However, you can also integrate with any other IdPs that supports the SAML protocol. This guide shows you how to set up a SAML connection with a custom IdP in Clerk. ## Set up an enterprise connection in Clerk To create a SAML connection in Clerk: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Under **SAML**, select **Custom SAML Provider**. 4. Add the **Domain** for which you want to enable this connection. This is the domain of the users you wish to allow to sign in to your application. Optionally, select an **Organization**. 5. Enter the **Name**. This will be displayed on the sign-in form. 6. Select **Add connection**. You'll be redirected to the connection's configuration page. ## Create a new enterprise application in your IdP Create a new application in your IdP. In the next steps, you'll configure your IdP with the settings provided by your Service Provider (Clerk), and configure Clerk with the settings provided by your IdP. Keep both the IdP and Clerk Dashboard open. ## Configure your Identity Provider There are two options for configuring your IdP: * [**Metadata configuration**](#metadata-configuration) - This is where you can download your IdP's metadata file or input the metadata URL that you got from your IdP. This is the recommended way to configure your IdP, but not all IdPs support this method. * [**Custom configuration**](#custom-configuration) - This is where you can manually input the configuration settings for your IdP. ### Metadata configuration 1. In your IdP dashboard, find where you can download the metadata file or copy the metadata URL. 2. In the Clerk Dashboard on the connection's configuration page, under **Identity Provider Configuration**,select **Add via metadata**. Input the metadata URL or upload the metadata file that you got from your IdP. ### Custom configuration If you choose to manually input the configuration settings for your IdP, you will need to fill these three fields in the Clerk Dashboard: * **SSO URL** - This is your IdP's URL that Clerk will redirect your users to so that they authenticate. * **Entity ID** - This is the unique identifier of your IdP application. * **Certificate** - This is the certificate needed for Clerk to securely connect to your IdP. 1. In your IdP dashboard, find these values and copy them. 2. In the Clerk Dashboard, paste the values you copied from your IdP into the appropriate fields, and upload the certificate you got from your IdP. ### Configure your Service Provider To configure your Service Provider (Clerk), your IdP will either ask for the **Assertion Consumer Service (ACS) URL** and **Entity ID** or it will ask for the **Metadata URL**. If your IdP gives you the option to choose between the two, it is recommended to choose the **Metadata URL** as it is the quickest and most reliable way to configure your Service Provider. Here are what these settings mean: * **Assertion Consumer Service (ACS) URL** - This is your application's URL that your IdP will redirect your users back to after they have authenticated in your IdP. * **Entity ID** - This is a unique identifier for your SAML connection that your IdP application needs. * **Metadata URL** - This is the URL to your SAML connection's metadata file. This is the recommended way to configure your Service Provider. To find the values for these settings: 1. In the Clerk Dashboard, on the connection's configuration page, find the **Service Provider configuration** section. 2. Copy the values you need for your IdP. 3. In your IdP dashboard, paste the values in the appropriate fields. > \[!TIP] > If you closed the connection's configuration page in the Clerk Dashboard, you can find it by navigating to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page and selecting the settings icon next to the connection you want to configure. ### Map your IdP's claims to Clerk fields Mapping the claims in your IdP to the attributes in Clerk ensures that the data from your IdP is correctly mapped to the data in Clerk. In the Clerk Dashboard, find the **Attribute mapping** section. Here, you are shown what properties on the User object in Clerk are being mapped to the claims in your IdP. In your IdP dashboard, there should be a section where you can map the IdP's claims to the attributes in Clerk. For example, Google has a `Primary email` claim that needs to be mapped to Clerk's `mail` property. During SAML configuration in the Google dashboard, Google provides a section where these claims can be mapped. If you have additional claims that you would like to map to Clerk that are not listed in the **Attribute mapping** section, you can do so by following the steps in the [Map other claims](#map-other-claims-optional) section. ### Map other claims (optional) In Clerk, the User object has a `publicMetadata` property that you can use to store additional information about your users. To map other claims from your IdP that do not have a direct mapping to Clerk attributes, you can map them to the `publicMetadata` property. To do this, prepend the Clerk claims with `public_metadata_` during the mapping process. For example, say you were using Google as your IdP. Google users have the "Phone number" attribute. Clerk does not have a direct mapping for this attribute, as you can see in the Clerk Dashboard in the **Attribute mapping** section. Instead, in the Google dashboard, you would map Google's "Phone number" claim to `public_metadata_phone_number`. Then, in Clerk, the value for the user's phone number would be saved in the user's `User.publicMetadata` under the key `phone_number`. Learn more about [how to access the metadata from our APIs](/docs/guides/users/extending). ### Enable the connection for Clerk To make the connection available for your users to authenticate with: 1. In the Clerk Dashboard, you should still have the connection's configuration page open. If not, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page and select the connection. 2. Toggle on **Enable connection** and select **Save**. --- title: Add Google Workspace as a SAML connection description: Learn how to integrate Google Workspace with Clerk using SAML SSO. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/saml/google sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/saml/google.mdx --- Enabling SAML with Google allows your users to sign up and sign in to your Clerk application with their Google account. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Google Admin Console](https://admin.google.com/). ## Enable Google as a SAML connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Under **SAML**, select **Google Workspace**. 4. Enter the **Domain**. This is the email domain of the users you want to allow to sign in to your application. Optionally, select an **Organization**. 5. Enter the **Name**. This will be displayed on the sign-in form. 6. Select **Add connection**. You'll be redirected to the connection's configuration page. 7. In the **Service Provider Configuration** section, save the **ACS URL** and **Entity ID** values somewhere secure. Keep this page open. ## Create a new enterprise application in Google 1. Navigate to the [Google Admin Console](https://admin.google.com/) and sign in. 2. In the navigation sidenav, under **Apps**, select **Web and mobile apps**. 3. Select the **Add app** button. 4. From the dropdown, select **Add custom SAML app**. 5. In the **App details** section, an **App name** is required. 6. Select the **Continue** button. ## Configure Google as your Identity Provider There are two options for configuring your identity provider: * **[Metadata configuration](#metadata-configuration) (recommended)** - A URL or file to your IdP's metadata. This is quicker than manually inputting the configuration settings. * [**Custom configuration**](#custom-configuration) - Manually input the configuration settings for your IdP. ### Metadata configuration 1. In the Google Admin Console, under **Option 1: Download IdP Metadata**, select the **Download Metadata** button. 2. Navigate back to the Clerk Dashboard and in the **Identity Provider Configuration** section, select the **Upload file** button. 3. Upload the metadata file you downloaded from Google. ### Custom configuration If you choose to manually input the configuration settings for your IdP, you must add these three fields to your Clerk settings: * **SSO URL** - The unique identifier of your IdP application. * **Entity ID** - Your IdP's URL that Clerk will redirect your users to so that they can authenticate. * **Certificate** - The certificate needed for Clerk to securely connect to your IdP. 1. In the Google Admin Console, under **Option 2**, copy the **SSO URL**, **Entity ID**, and download the **Certificate**. 2. Navigate back to the Clerk Dashboard and in the **Identity Provider Configuration** section, select **Use manual configuration**. 3. Fill in the **SSO URL**, **Entity ID**, and upload the **Certificate**. Don't forget to select **Save**. 4. In the Google Admin Console, select the **Continue** button. ## Configure Clerk as your Service Provider 1. In the Google Admin Console, paste the **ACS URL** and **Entity ID** values you saved from the Clerk Dashboard into their respective fields. 2. Under the **Name ID** section, select the **Name ID format** dropdown and select **Email**. 3. Select **Continue**. ## Map Google claims to Clerk attributes Mapping the claims in your IdP to the attributes in Clerk ensures that the data from your IdP is correctly mapped to the data in Clerk. | Clerk attribute | Google claim | | - | - | | `mail` | Basic Information > Primary email | | `firstName` | Basic Information > First name | | `lastName` | Basic Information > Last name | The only Google claim that is necessary to map is the **Primary email**. This is the email address that your users will use to authenticate into your application. 1. In the Google Admin Console, under the **Attributes** section, select **Add mapping**. 2. Select the dropdown under **Google Directory attributes**. 3. Select **Primary email**. 4. In the **App attributes** field, enter `mail`. 5. If you have additional claims that you would like to map to Clerk, you can do so by following the steps in the [Map other claims](#map-other-claims-optional) section. Otherwise, select the **Finish** button. ### Map other claims (optional) In Clerk, the User object has a `publicMetadata` property that you can use to store additional information about your users. To map other claims from Google that don't have a direct mapping to Clerk attributes, you can map them to Clerk's `publicMetadata` property. To do this, prepend the Clerk claims with `public_metadata_` during the mapping process. For example, say your users have the "Phone number" attribute in Google. You can map this to your users' public metadata in Clerk by mapping the Google field to `public_metadata_phone_number`. 1. In the Google Admin Console, under the **Attributes** section, select the dropdown under **Google Directory attributes**. 2. Select **Phone number**. 3. In the **App attributes** field, enter `public_metadata_phone_number`. 4. Select the **Finish** button. The value for the user's phone number will be saved in the user's `User.publicMetadata` under the key `phone_number`. Learn more about [how to access the metadata from our APIs](/docs/guides/users/extending). ## Enable the connection in Google Once the configuration is complete in Google, you'll be redirected to the app's overview page. 1. In the **User access** section, select **OFF for everyone**. You'll be redirected to the **Service status** page. 2. Select **ON for everyone**. 3. Select **Save**. ## Enable the connection in Clerk The SAML connection is ready to enable! Once enabled, all users with email addresses ending in the domain will be redirected to Okta at sign-up and sign-in. > \[!WARNING] > If there are existing users with email domains that match the SAML connection, and there is an error in the SAML configuration in Clerk or Okta, those users will be **unable to sign in** when the connection is enabled. If this is a concern, we recommend coordinating with your counterpart to test the connection at an off-peak time. To make the connection available for your users to authenticate with: 1. Navigate back to the Clerk Dashboard where you should still have the connection's configuration page open. If not, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page and select the connection. 2. At the top of the page, toggle on **Enable connection** and select **Save**. --- title: Add Okta Workforce as a SAML connection description: Learn how to integrate Okta Workforce with Clerk using SAML SSO. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/saml/okta sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/saml/okta.mdx --- Enabling SAML with Okta Workforce allows your users to sign up and sign in to your Clerk application with their Okta account. It requires that a SAML connection is configured in both the Clerk Dashboard and Okta. This guide assumes that you have access to the Clerk app's settings in the Clerk Dashboard. The "customer" in this case is whoever has access to the Okta Workforce's app settings. ## Create an Okta SAML connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Under **SAML**, select **Okta Workforce**. 4. Enter the **Domain**. This is the email domain of the users you want to allow to sign in to your app. Optionally, select an **Organization**. 5. Enter the **Name**. This will be displayed on the sign-in form. 6. Select **Add connection**. You'll be redirected to the connection's configuration page. Note that the connection is disabled by default. 7. In the **Service Provider Configuration** section, save the **Single sign-on URL** and **Audience URI (SP Entity ID)** values somewhere secure. You'll need to give these to the customer so they can configure their Okta app. ## Configure SAML app Now that the enterprise connection is configured in Clerk and the **Single sign-on URL** and **Audience URI (SP Entity ID)** are known, the customer's Okta app needs to be configured. At a high level, the process is: * Create a new enterprise app in Okta. * Add the **Single sign-on URL** and **Audience URI (SP Entity ID)** from Clerk to the Okta app's SAML configuration. * Verify that the attribute mappings are correct. * Assign selected users or groups to the app. * Obtain and share the app's **Metadata URL**. To get you started, you can use the following email template with detailed instructions: Here are the instructions for setting up SAML SSO with Okta Workforce: **Step 1: Create a new enterprise app in Okta** 1. Navigate to [Okta](https://www.okta.com/) and sign in. 2. In the Okta dashboard, select **Admin** in the top right corner. 3. In the navigation sidenav, select the **Applications** dropdown and select **Applications**. 4. Select **Create App Integration**. 5. In the **Create a new app integration** modal, select the **SAML 2.0** option and select the **Next** button. 6. Once redirected to the **Create SAML Integration** page, complete the **General Settings** fields. An **App name** is required. 7. Select **Next**. You'll be redirected to the **Configure SAML** page. 8. Paste the **Single sign-on URL** and the **Audience URI (SP Entity ID)** values that you saved from the Clerk Dashboard into their respective fields. **Step 2: Verify correct configuration of attributes and claims** We expect your SAML responses to have the following specific attributes: * Email address (required). This is the email address that your users will use to authenticate into your app: * Claim name: `user.email` * First name (optional): * Claim name: `user.firstName` * Last name (optional): * Claim name: `user.lastName` These are the defaults, and probably won't need you to change them. However, many SAML configuration errors are due to incorrect attribute mappings, so it's worth double-checking. Here's how: 1. In the Okta dashboard, find the **Attribute Statements (optional)** section. 2. For the **Name** field, enter `mail`. 3. For the **Value** field, choose `user.email` from the dropdown. 4. Select the **Add Another** button to add another attribute. 5. For the **Name** field, enter `firstName`. 6. For the **Value** field, choose `user.firstName` from the dropdown. 7. Select the **Add Another** button to add another attribute. 8. For the **Name** field, enter `lastName`. 9. For the **Value** field, choose `user.lastName` from the dropdown. 10. Scroll to the bottom of the page and select the **Next** button to continue. 11. You will be redirected to the **Feedback** page. Fill out the feedback however you would like and select the **Finish** button to complete the setup. **Step 3: Assign selected user or group in Okta** You need to assign users or groups to your enterprise app before they can use it to sign in. 1. In the Okta dashboard, select the **Assignments** tab. 2. Select the **Assign** dropdown. You can either select **Assign to people** or **Assign to groups**. 3. In the search field, enter the user or group of users that you want to assign to the enterprise app. 4. Select the **Assign** button next to the user or group that you want to assign. 5. Select the **Done** button to complete the assignment. **Step 4: Share the app's metadata URL** Once you have completed the setup in Okta, you will be redirected to the application's instances page with the **Sign On** tab selected. Under **Sign on methods**, copy the **Metadata URL**. ## Add the Metadata URL in the Clerk Dashboard After following the instructions in the email, your customer should have sent you the Okta app's **Metadata URL**. Now, you're going to add it to the Clerk connection, completing the SAML connection configuration. 1. Navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. 2. Select the SAML connection. 3. In the **Identity Provider Configuration** section, under **Metadata configuration**, paste the **Metadata URL** that you received from the customer. 4. Select **Fetch & save**. Keep the page open for the next step. ## Enable the connection in Clerk The SAML connection is ready to enable! Once enabled, all users with email addresses ending in the domain will be redirected to Okta at sign-up and sign-in. > \[!WARNING] > If there are existing users with email domains that match the SAML connection, and there is an error in the SAML configuration in Clerk or Okta, those users will be **unable to sign in** when the connection is enabled. If this is a concern, we recommend coordinating with your counterpart to test the connection at an off-peak time. To make the connection available for your users to authenticate with: 1. Navigate back to the Clerk Dashboard where you should still have the connection's configuration page open. If not, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page and select the connection. 2. At the top of the page, toggle on **Enable connection** and select **Save**. --- title: Add a custom OpenID Connect (OIDC) Provider as an enterprise connection description: Learn how to integrate a custom OIDC provider with Clerk for Enterprise SSO. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/enterprise-connections/oidc/custom-provider sourceFile: /docs/guides/configure/auth-strategies/enterprise-connections/oidc/custom-provider.mdx --- This guide explains how to use a custom [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works) provider to authenticate users via Enterprise SSO. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your Identity Provider (IdP). ## Set up an enterprise connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO Connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For specific domains or organizations**. 3. Under **OpenID Connect (OIDC)**, select **Custom OIDC Provider**. 4. Add the **Name** of the connection. 5. Add the **Key** of the provider. This is the provider's unique identifier (cannot be changed after creation). 6. Enter the **Domain**. This is the email domain of the users you want to allow to sign in to your application. Optionally, select an **Organization**. 7. Select **Add connection**. You will be redirected to the connection's configuration page. Keep this page open. ## Configure your IdP 1. If necessary, create a new application in your IdP. 2. In the connection's configuration page of the Clerk Dashboard, copy the **Authorized redirect URI**. 3. Add the value to your IdP's allowed URLs. 4. Find your application's **Discovery Endpoint**, **Client ID**, and **Client Secret** and copy them. ## Set the Discovery Endpoint, Client ID, and Client Secret in Clerk 1. In your IdP settings, copy your application's **Discovery Endpoint**, **Client ID**, and **Client Secret**. 2. In the connection's configuration page in the Clerk Dashboard, paste these values in their respective fields. 3. Under **Scopes**, add the minimum required scopes based on the IdP's documentation if needed. Common OIDC scopes include `openid`, `email`, and `profile`. 4. Select **Save**. > \[!NOTE] > Most IdPs provide a **Discovery Endpoint** to retrieve metadata about an OIDC provider. If your IdP doesn't offer this endpoint or if you need greater control over the setup process, in the connection's configuration page in the Clerk Dashboard, find the **Identity Provider Configuration** section and select **Use Manual Configuration** to manually configure the connection. ## Configure attribute mapping (optional) Clerk expects the claims returned by your IdP to follow the [OIDC Standard](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims). If your provider returns claims in a non-standard format, use the **Attribute Mapping** section on the connection's configuration page to adjust the mapping of Clerk's user properties to match the IdP's claim attributes. > \[!WARNING] > OIDC Enterprise connections require the [`email_verified`](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims:~:text=Section%C2%A05.7.-,email_verified,-boolean) claim to verify email ownership. However, some IdPs, such as Microsoft Azure Active Directory, might not return this claim or use a non-standard format. > > If the IdP doesn't return this claim, you can leave the **Email address verified** field blank and set the **Default value** to **True**. This should only be done if you fully trust the IdP, as it can expose your app to [OAuth attacks](https://www.descope.com/blog/post/noauth). ## Allow additional identifiers (optional) User profile information is sourced from the IdP. To allow users to add new identifiers (e.g., email address or phone number) to their profiles: 1. In the connection's configuration page of the Clerk Dashboard, navigate to the **Advanced** tab. 2. Enable **Allow additional identifiers**. 3. Select **Save**. ## Enable the connection for Clerk To make the connection available for your users to authenticate with: 1. Navigate back to the Clerk Dashboard where you should still have the connection's configuration page open. If not, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page and select the connection. 2. At the top of the page, toggle on **Enable connection** and select **Save**. ## Test your connection The simplest way to test your enterprise connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to the **Sign-in** URL, select **Visit**. The URL should resemble: * **For development** – `https://your-domain.accounts.dev/sign-in` * **For production** – `https://accounts.your-domain.com/sign-in` 3. Sign in with your IdP account. --- title: Account linking for OAuth description: Learn how Clerk handles account linking and manages unverified email addresses from OAuth providers. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/account-linking sourceFile: /docs/guides/configure/auth-strategies/social-connections/account-linking.mdx --- Account linking is the process of connecting multiple user accounts from different services or platforms, allowing users to access various services with a single set of credentials. By using the email address as the common identifier, Clerk automatically attempts to link accounts whenever possible. Account linking is triggered when an OAuth provider returns an email address that matches an existing account, assuming a single owner for each email address. ## How it works When a user attempts to sign in or sign up, Clerk first checks the provided email address. Clerk will attempt to link the OAuth account with any existing Clerk account that shares the same email address. In the following sections, we'll look at the different scenarios that can occur during this process and explain how Clerk handles each one. ![Flow chart of the account linking process in various scenarios](/docs/images/authentication/account-linking-flow-oauth.webp) ### Email address is verified in both OAuth and Clerk When a user signs in to your app using an OAuth provider that returns a **verified** email address, Clerk links the OAuth account to the existing account and signs the user in. This even applies to password-protected accounts, as the OAuth sign-in process automatically bypasses password verification. ### Email address is verified in Clerk but not in OAuth When a user signs in to your app using an OAuth provider that returns an **unverified** email address, Clerk will initiate a verification process. Once the email address is verified, the OAuth account is linked to the existing one, and the user is signed in. ### Email address is unverified in Clerk By default, users are required to verify their email addresses before they can sign up. If you disabled the **Verify at sign-up** option in the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/user-and-authentication), users will be able to sign up without verifying their email addresses. When a user signs up with an **unverified** email address and later attempts to sign in with an OAuth provider, Clerk implements security measures to prevent potential account takeovers. For example, if an account was created with an unverified email/password combination and the user later signs in with Google (where the email is verified), Clerk will prompt the user to change their password before linking the accounts. This process begins with email verification, regardless of the method used. After successful verification, Clerk may require additional steps, such as validating existing connections or passwords, to ensure the account's security. These measures are in place because Clerk cannot confirm the original ownership of the account, which could otherwise lead to unauthorized access. ## Users with different email addresses If a user has a different email from the one associated with the OAuth account, they can manually associate the two by following these steps: 1. Sign in to their Clerk application with the account that uses their main email address. 2. In the \, add the different email. After following these steps, the user's OAuth accounts associated with both their primary and added email addresses will be linked to their main account. --- title: Social connection (OAuth) providers description: Browse the wide range of social providers that Clerk provides to ease your user's sign-up and sign-in processes. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/all-providers sourceFile: /docs/guides/configure/auth-strategies/social-connections/all-providers.mdx --- Clerk provides a wide range of social providers to ease your user's sign-up and sign-in processes. Select a provider to learn how to configure it for your Clerk app. * [Apple](/docs/guides/configure/auth-strategies/social-connections/apple) * Add Apple as an authentication provider for your Clerk app. * {} *** * [Atlassian](/docs/guides/configure/auth-strategies/social-connections/atlassian) * Add Atlassian as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/atlassian.svg) *** * [Bitbucket](/docs/guides/configure/auth-strategies/social-connections/bitbucket) * Add Bitbucket as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/bitbucket.svg) *** * [Box](/docs/guides/configure/auth-strategies/social-connections/box) * Add Box as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/box.svg) *** * [Coinbase](/docs/guides/configure/auth-strategies/social-connections/coinbase) * Add Coinbase as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/coinbase.svg) *** * [Discord](/docs/guides/configure/auth-strategies/social-connections/discord) * Add Discord as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/discord.svg) *** * [Dropbox](/docs/guides/configure/auth-strategies/social-connections/dropbox) * Add Dropbox as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/dropbox.svg) *** * [Facebook](/docs/guides/configure/auth-strategies/social-connections/facebook) * Add Facebook as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/facebook.svg) *** * [GitHub](/docs/guides/configure/auth-strategies/social-connections/github) * Add GitHub as an authentication provider for your Clerk app. * {} *** * [GitLab](/docs/guides/configure/auth-strategies/social-connections/gitlab) * Add GitLab as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/gitlab.svg) *** * [Google](/docs/guides/configure/auth-strategies/social-connections/google) * Add Google as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/google.svg) *** * [HubSpot](/docs/guides/configure/auth-strategies/social-connections/hubspot) * Add HubSpot as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/hubspot.svg) *** * [Hugging Face](/docs/guides/configure/auth-strategies/social-connections/hugging-face) * Add Hugging Face as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/huggingface.svg) *** * [LINE](/docs/guides/configure/auth-strategies/social-connections/line) * Add LINE as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/line.svg) *** * [Linear](/docs/guides/configure/auth-strategies/social-connections/linear) * Add Linear as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/linear.svg) *** * [LinkedIn](/docs/guides/configure/auth-strategies/social-connections/linkedin-oidc) * Add LinkedIn as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/linkedin.svg) *** * [Microsoft](/docs/guides/configure/auth-strategies/social-connections/microsoft) * Add Microsoft as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/microsoft.svg) *** * [Notion](/docs/guides/configure/auth-strategies/social-connections/notion) * Add Notion as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/notion.svg) *** * [Slack](/docs/guides/configure/auth-strategies/social-connections/slack) * Add Slack as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/slack.svg) *** * [Spotify](/docs/guides/configure/auth-strategies/social-connections/spotify) * Add Spotify as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/spotify.svg) *** * [TikTok](/docs/guides/configure/auth-strategies/social-connections/tiktok) * Add TikTok as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/tiktok.svg) *** * [Twitch](/docs/guides/configure/auth-strategies/social-connections/twitch) * Add Twitch as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/twitch.svg) *** * [X/Twitter v2](/docs/guides/configure/auth-strategies/social-connections/x-twitter) * Add X (Twitter v2) as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/x-twitter.svg) *** * [Xero](/docs/guides/configure/auth-strategies/social-connections/xero) * Add Xero as an authentication provider for your Clerk app. * ![](/docs/images/logos/auth_providers/xero.svg) Don't see the provider you're looking for? You can [configure a custom OIDC-compatible provider](/docs/guides/configure/auth-strategies/social-connections/custom-provider) or [request a new one](https://feedback.clerk.com/roadmap/f9045ac8-0c8e-4f30-b84f-8d551b0767b9?_gl=1*1ywoqdy*_gcl_au*OTUwODgxMjg2LjE3MTI1OTEwNzMuMTczNjk0NTcxMC4xNzE1MTk4MTEyLjE3MTUxOTgxMTI.). --- title: Add Apple as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Apple ID using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/apple sourceFile: /docs/guides/configure/auth-strategies/social-connections/apple.mdx --- Enabling OAuth via [Sign in with Apple](https://developer.apple.com/sign-in-with-apple/) allows your users to sign in and sign up to your Clerk app with their Apple ID. > \[!IMPORTANT] > This guide explains how to configure Sign in with Apple for web based flows. To configure native Sign in with Apple on native applications (iOS), see the dedicated guide. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs. To configure your development instance, follow these steps: 1. In the Clerk Dashboard, navigate to the [**SSO Connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Apple**. 4. Then, select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. You must generate and provide your own **Apple Services ID**, **Apple Private Key**, **Apple Team ID**, and **Apple Key ID** using your Apple Developer account. To make the setup process easier, it's recommended to keep two browser tabs open: one for your [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Apple Developer dashboard](https://developer.apple.com/account). ### Enable Apple as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO Connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Apple**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Email Source for Apple Private Email Relay** and **Return URL** values somewhere secure, as you'll need to provide them to Apple later. Keep this page and modal open. ### Get your Apple Team ID To get your **Apple Team ID**, create a new **App ID** in the Apple Developer portal by following these steps: 1. On a separate page, navigate to the [Apple Developer dashboard](https://developer.apple.com/account). 2. Under **Certificates, IDs and Profiles**, select [**Identifiers**](https://developer.apple.com/account/resources/identifiers/list). 3. In the top-right, select the dropdown and select **App IDs**. 4. Next to **Identifiers** at the top of the page, select the plus icon (+) to register a new identifier. You'll be redirected to the **Register a new identifier** page. 5. Select **App IDs**, then select **Continue**. 6. On the next page, you'll be prompted to **Select a type** for your app. Choose **App** and select **Continue**. You will be redirected to the **Register an App ID** page. 7. Fill in a description for your **App ID** and a **Bundle ID**. Under **Capabilities**, ensure that **Sign In with Apple** is enabled. Then select **Continue**. You'll be redirected to the **Confirm your App ID** page. 8. At the top of the page, you'll see your **App ID Prefix**. Save this value somewhere secure. This is your **Apple Team ID** in Clerk. 9. Finally, select **Register**. You'll be redirected to the **Identifiers** page. ### Get your Apple Services ID To get your **Apple Services ID**, create a new **Services ID** in the Apple Developer portal. 1. On the **Identifiers** page, in the dropdown near the top-right of the page, select the **Services IDs** option from the list. 2. Next to **Identifiers** at the top of the page, select the plus icon (+) to register a new identifier. You'll be redirected to the **Register a new identifier** page. 3. Select **Services IDs**, then select **Continue**. You'll be redirected to the **Register a Services ID** page. 4. Add a description for your **Services ID**, and set an **Identifier**. Save the **Identifier** value somewhere secure. This is your **Apple Services ID** in Clerk. Finally, select **Continue**. 5. In the confirmation view, select **Register**. 6. After the registration is finished, select the newly-created **Services ID**. Ensure the **Sign In with Apple** box is enabled and select **Configure**. 7. Under **Primary App ID**, select the **App ID** you created in the previous step. 8. Under **Domains and Subdomains**, add your Clerk **Frontend API URL** **without the protocol**. For example, if your domain is `https://myapp.com`, then your **Frontend API URL** is `https://clerk.myapp.com`, and you would add `clerk.myapp.com` to **Domains and Subdomains**. 9. Under **Return URLS**, add the **Return URL** value you saved from the Clerk Dashboard. 10. Select **Next**. You'll be redirected to the **Confirm your web authentication configuration** screen. 11. Select **Done**. You'll be redirected to the **Edit your Services ID Configuration** page. 12. Select **Continue**. You'll be redirected to the confirmation page. 13. Select **Save**. You'll be redirected to the **Identifiers** page. ### Get your Apple Private Key and Key ID To get your **Apple Private Key** and **Key ID**, create a new **Key** in the Apple Developer portal. 1. On the **Identifiers** page, in the sidenav, select **Keys**. 2. Next to **Keys** at the top of the page, select the plus icon (+) to register a new key. You'll be redirected to the **Register a New Key** page. 3. Add a **Key Name** and ensure the **Sign In with Apple** box is enabled and select **Configure**. You'll be redirected to the **Configure Key** page. 4. Under **Primary App ID**, select the **App ID** you created in the first step of this guide. Then select **Save**. You'll be redirected to the previous **Register a New Key** page. 5. Select **Continue** and you'll be presented with the final confirmation screen. Verify that **Sign in with Apple** is checked. Select **Register**. You'll be redirected to the **Download Your Key** page. 6. Save the **Key ID** value somewhere secure. This is your **Apple Key ID** in Clerk. 7. Download the private key file. This is your **Apple Private Key** in Clerk. Ensure you back up the key in a secure location, as it cannot be downloaded again later. 8. Select **Done**. You'll be redirected to the **Keys** page. ### Configure Email Source for Apple Private Relay > \[!NOTE] > In some regions (such as China and India), Apple IDs may not include an email address at all, and instead are tied only to a phone number. If your instance requires all users to have an email, Sign in with Apple may fail for these users. Depending on your user base, you may want to navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page in the Clerk Dashboard and disable the **Sign-up with email** setting. > > If you'd like to know more about this, see the [Apple documentation](https://support.apple.com/en-au/105034). Apple provides a privacy feature called [Hide My Email](https://support.apple.com/en-us/HT210425#hideemail), allowing users to sign in to your app with Apple without disclosing their actual email addresses. Instead, your instance receives an app-specific email address that forwards any emails to the user real's address. To be able to send emails properly to users with hidden addresses, you must configure an additional setting in the Apple Developer portal. 1. In the sidenav of the Apple Developer Portal, select [**Services**](https://developer.apple.com/account/resources/services/list). 2. Under **Sign in with Apple for Email Communication**, select **Configure**. You'll be redirected to the **Configure Sign in with Apple for Email Communication** page. 3. Next to **Email Sources** at the top of the page, select the plus icon (+) to add a new **Email Source**. 4. In the **Register your email sources** modal that opens, under **Email Addresses**, add the **Email Source for Apple Private Email Relay** value that you copied from the [**Apple SSO custom credentials**](https://dashboard.clerk.com/~/user-authentication/sso-connections) in the Clerk Dashboard. It should look something like this: `bounces+00000000@clkmail.myapp.com`. 5. Select **Next**. The modal will redirect to the **Confirm your email sources** screen. 6. Select **Register**. The modal will redirect to the **Email Source Registration Complete** screen. 7. Select **Done**. After this step, the email address should appear in the list and display a green check icon, indicating it has been verified. If it's not marked as verified yet, DNS propagation may still be in progress. Wait for the propagation to complete before attempting to select **Reverify SPF**. For more info about Apple's Private Relay service, refer to the following documentation: * [https://support.apple.com/en-us/HT210425#hideemail](https://support.apple.com/en-us/HT210425#hideemail) * [https://developer.apple.com/help/account/configure-app-capabilities/configure-private-email-relay-service](https://developer.apple.com/help/account/configure-app-capabilities/configure-private-email-relay-service) ### Connect your Apple app to your Clerk app By now, you should have the following values saved from the Apple Developer portal: * **Apple Team ID** * **Apple Services ID** * **Apple Key ID** * **Apple Private Key** file Connect your Apple app to your Clerk app by adding these values to the Clerk Dashboard. 1. Navigate back to the Clerk Dashboard where the configuration modal should still be open. 2. Add all the corresponding fields depending on your desired flow. For the **Apple Private Key** file, open it with a text editor and copy/paste the contents. You must include the `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----` lines. 3. Select **Add connection**. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Atlassian as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Atlassian account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/atlassian sourceFile: /docs/guides/configure/auth-strategies/social-connections/atlassian.mdx --- Enabling OAuth with Atlassian allows your users to sign up and sign in to your Clerk app with their Atlassian account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Atlassian**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Atlassian Developer console](https://developer.atlassian.com/console/myapps/). ### Enable Atlassian as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Atlassian**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Callback URL** somewhere secure. Keep this modal and page open. ### Create an Atlassian workspace > \[!TIP] > If you already have an Atlassian workspace you'd like to connect to Clerk, select your workspace from the [Atlassian Developer console](https://developer.atlassian.com/console/myapps/) and skip to [the next step in this tutorial](#configure-your-atlassian-app). 1. In the [Atlassian Developer console](https://developer.atlassian.com/console/myapps/), next to **My apps**, select **Create**. Then, select **OAuth 2.0 integration**. You'll be redirected to the **Create a new OAuth 2.0 (3LO) integration** page. 2. Fill out the necessary information. Then, select **Create**. Once the integration is created, you'll be redirected to the app's **Overview** page. ### Configure your Atlassian app 1. In the left sidenav of your app's **Overview** page, select **Permissions**. Configure the OAuth 2.0 scopes to request from your users when they connect with Atlassian. At a minimum, next to **User identity API**, select **Add**. 2. In the left sidenav, select **Authorization**. 3. Next to **OAuth 2.0 (3LO)**, select **Add**. 4. In the **Callback URL** field, paste the **Callback URL** you saved from the Clerk Dashboard. 5. Select **Save changes**. 6. In the left sidenav, select **Settings**. 7. Under **Authentication details**, save the **Client ID** and **Secret** somewhere secure. 8. In the left sidenav, select **Distribution**. 9. Select **Edit**. 10. Set the **Distribution Status** to **Sharing**. 11. Complete the required fields. For **Does your app store personal data?**, select **Yes**, as Clerk uses the user's personal data to authenticate them. 12. Select **Save changes**. ### Set the Client ID and Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection > \[!WARNING] > To be able to connect, the user must have access to at least one Atlassian site (e.g. JIRA, Confluence). Currently, the user can authorize access only to a single Atlassian site. The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Bitbucket as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Bitbucket account with OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/bitbucket sourceFile: /docs/guides/configure/auth-strategies/social-connections/bitbucket.mdx --- Enabling OAuth with [Bitbucket](https://developer.atlassian.com/cloud/bitbucket/oauth-2) allows your users to sign up and sign in to your Clerk application with their Bitbucket account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Bitbucket**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Bitbucket Workspaces](https://bitbucket.org/account/workspaces/) page. ### Enable Bitbucket as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Bitbucket**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Callback URL** somewhere secure. Keep the modal and page open. ### Create a Bitbucket OAuth Consumer 1. On a separate page, go to the [Bitbucket Workspaces](https://bitbucket.org/account/workspaces/) page and sign in. 2. Under **Workspaces**, find your workspace and select **Manage**. 3. In the sidenav, scroll down and select **OAuth consumers**. 4. Select **Add consumer**. 5. Complete the required fields. In **Permissions** , under **Account**, select **Email** and **Read**. 6. Select **Save**. You'll be redirected to the **OAuth consumers** page. 7. Select your consumer and save the **Key** and **Secret** values somewhere secure. ### Set the Key and Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Key** and **Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Box as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Box account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/box sourceFile: /docs/guides/configure/auth-strategies/social-connections/box.mdx --- Enabling OAuth with Box allows your users to sign up and sign in to your Clerk app with their Box account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Box**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Box Developer Console](https://app.box.com/developers/console). ### Enable Box as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Box**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep this modal and page open. ### Create a Box app 1. On the homepage of the [Box Developer Console](https://app.box.com/developers/console), select **Custom App**. A modal will open. 2. Fill out the necessary information. Use Box's [guide on OAuth 2.0 setup](https://developer.box.com/guides/authentication/oauth2/oauth2-setup/#app-creation-steps) to help you. 3. Select **Next**. 4. In the list of authentication methods, select **User Authentication (OAuth 2.0)**. 5. Select **Create App**. You'll be redirected to the app's **Configuration** page. 6. In the **OAuth 2.0 Redirect URIs** section, paste the **Redirect URI** value you saved from the Clerk Dashboard. 7. In the **OAuth 2.0 Credentials** section, save the **Client ID** and **Client Secret** somewhere secure. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Xero as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Xero account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/xero sourceFile: /docs/guides/configure/auth-strategies/social-connections/xero.mdx --- Enabling OAuth with Xero allows your users to sign up and sign in to your Clerk app with their Xero account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Xero**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Xero Developer](https://developer.xero.com) page. ### Enable Xero as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Xero**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep this modal and page open. ### Create a Xero app 1. In the top-right of the [Xero Developer](https://developer.xero.com/app/manage/) home page, select **New app**. The **Add a new app** modal will open. 2. Fill out the necessary information. In the **Redirect URI** field, paste the **Redirect URI** value you saved from the Clerk Dashboard. 3. Select **Create app**. You'll be redirected to the app's **App details** page. 4. In the left sidenav, select **Configuration**. 5. Select **Generate a secret**. Save the **Client ID** and **Client Secret** somewhere secure. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Coinbase as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Coinbase account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/coinbase sourceFile: /docs/guides/configure/auth-strategies/social-connections/coinbase.mdx --- Enabling OAuth with [Coinbase](https://docs.cdp.coinbase.com/coinbase-app/docs/coinbase-app) allows your users to sign up and sign in to your Clerk app with their Coinbase account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Coinbase**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Coinbase Developer Platform](https://portal.cdp.coinbase.com). ### Enable Coinbase as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Coinbase**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep the modal and page open. ### Create a Coinbase app > \[!NOTE] > Coinbase automatically creates a default project for you named `Project 1`. Select the icon next to the project name to rename it. 1. In your [Coinbase Developer Platform project dashboard](https://portal.cdp.coinbase.com/projects), select the **API keys** tab. 2. Select **OAuth**, then select **Create client**. 3. Complete the required fields. In **Redirect URIs**, paste the **Redirect URI** you saved from the Clerk Dashboard. 4. Select **Create client**. The page will refresh and you should see the **Client ID** and **Client Secret**. Save these values somewhere secure. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add GitLab as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their GitLab account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/gitlab sourceFile: /docs/guides/configure/auth-strategies/social-connections/gitlab.mdx --- Enabling OAuth with [GitLab](https://docs.gitlab.com/ee/integration/oauth_provider.html) allows your users to sign up and sign in to your Clerk app with their GitLab account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **GitLab**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [GitLab](https://gitlab.com) account. ### Enable GitLab as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **GitLab**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep the modal and page open. ### Create a GitLab app 1. In [Gitlab](https://gitlab.com), navigate to the [**Applications**](https://gitlab.com/-/user_settings/applications) page. 2. Select **Add new application**. 3. Enter your app name in **Name**. 4. In **Redirect URI**, paste the **Redirect URI** you saved from the Clerk Dashboard. 5. Select the **Scopes** needed for your app. At minimum, select `read_user`. 6. Select **Save application**. You'll be redirected to your app's settings page. Save the **Application ID** and **Secret** somewhere secure. ### Set the Application ID and Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Application ID** and **Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is not still open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, you can paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add a custom OAuth provider as a social connection description: Configure a custom OpenID Connect (OIDC) compatible authentication provider for your Clerk application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/custom-provider sourceFile: /docs/guides/configure/auth-strategies/social-connections/custom-provider.mdx --- Clerk allows you to configure custom OpenID Connect (OIDC) compatible authentication providers for your application. This guide walks you through the steps to set up a custom OAuth provider. ## Configuration 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the **Add connection** button, and select **For all users**. 3. At the top of the modal that opened, select **Custom provider**. 4. Fill in the following fields: * **Name**: The provider name (visible to users) * **Key**: A unique identifier for the provider (cannot be changed after creation) * **Discovery Endpoint**: The OIDC discovery endpoint URL of your provider * Alternatively, select **Manual configuration** to set up provider endpoints manually * **Client ID**: Obtained from your provider * **Client Secret**: Obtained from your provider 5. Select **Add connection**. You will be redirected to the connection's configuration page. The provider is now configured but not yet enabled. On the connection's configuration page, find the **Authorized redirect URLs** to configure in your provider's settings. Enable the provider either from the provider list or the top of the details page when ready. ## Attribute mapping If your provider returns claims in a non-standard format: 1. Go to the provider's details page. 2. Under **Attribute mapping**, configure the mapping to match your provider's claim format. ### Tips * For fields like **Email address verified**, set default values for missing claims. * If the provider returns a claim but you don't want to set it, leave the mapping field empty. * If you set a user info URL, it takes priority over the ID Token for claim retrieval. ## Handling edge cases Sometimes [attribute mapping](#attribute-mapping) isn't enough to get a provider working. For example, the call to the **User info URL** might require additional credentials or API calls. In these instances you should implement a proxy between Clerk and the provider to handle these transformations. The proxy will then be set as the **User info URL**. The proxy receives the request from Clerk (which contains an `Authorization` header) and should return a JSON object which you can use for attribute mapping. ### Example: Hono with Cloudflare Workers 1. Initialize a new [Hono + Cloudflare Workers](https://hono.dev/docs/getting-started/cloudflare-workers) project 2. Implement your proxy logic, e.g. making an additional API call. Here's a minimal example: ```ts {{ filename: 'src/index.ts' }} import { Hono } from 'hono' const app = new Hono() app.get('/', async (c) => { const authorization = c.req.header('authorization') const userRes = await fetch('https://api.com/user', { headers: { 'Content-Type': 'application/json', Authorization: authorization, 'api-key': 'some-api-key', }, }) const user = await userRes.json() return c.json({ uuid: user.uuid, avatar_url: user.avatar, name: user.name, username: user.username, slug: user.id.slug, }) }) export default app ``` 3. Deploy your proxy 4. Set the URL of the deployed Cloudflare worker as the **User info URL** 5. Map the returned claim format of the proxy to the respective attributes in the **Attribute mapping** section ## References * [OpenID Connect Specification](https://openid.net/specs/openid-connect-core-1_0.html) * [OAuth 2.0 Framework](https://oauth.net/2/) --- title: Add Google as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Google account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/google sourceFile: /docs/guides/configure/auth-strategies/social-connections/google.mdx --- Enabling OAuth with [Google](https://developers.google.com/identity/protocols/oauth2) allows your users to sign up and sign in to your Clerk application with their Google account. > \[!WARNING] > Google OAuth 2.0 **does not** allow apps to use WebViews for authentication. See the dedicated [Google blog post](https://developers.googleblog.com/en/modernizing-oauth-interactions-in-native-apps-for-better-usability-and-security) for more information. If your app requires users to sign in via in-app browsers, follow the setup instructions in the [Google Help guide](https://support.google.com/faqs/answer/12284343). ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Google**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Google Cloud Console](https://console.cloud.google.com/). ### Enable Google as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Google**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Authorized Redirect URI** somewhere secure. Keep this modal and page open. ### Create a Google Developer project 1. Navigate to the [Google Cloud Console](https://console.cloud.google.com/). 2. Select a project or [create a new one](https://console.cloud.google.com/projectcreate). You'll be redirected to your project's **Dashboard** page. 3. In the top-left, select the menu icon (**≡**) and select **APIs & Services**. Then, select **Credentials**. 4. Next to **Credentials**, select **Create Credentials**. Then, select **OAuth client ID.** You might need to [configure your OAuth consent screen](https://support.google.com/cloud/answer/6158849#userconsent). Otherwise, you'll be redirected to the **Create OAuth client ID** page. 5. Select the appropriate application type for your project. In most cases, it's **Web application**. 6. In the **Authorized JavaScript origins** setting, select **Add URI** and add your domain (e.g., `https://your-domain.com` and `https://www.your-domain.com` if you have a `www` version). For local development, add `http://localhost:PORT` (replace `PORT` with the port number of your local development server). 7. In the **Authorized Redirect URIs** setting, paste the **Authorized Redirect URI** value you saved from the Clerk Dashboard. 8. Select **Create**. A modal will open with your **Client ID** and **Client Secret**. Save these values somewhere secure. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. > \[!WARNING] > Google sign-in [**does not** allow users to sign in via in-app browsers](https://developers.googleblog.com/en/modernizing-oauth-interactions-in-native-apps-for-better-usability-and-security). ### Important note about switching to production Google OAuth apps have a publishing status that determines who can access the app. The publishing status setting can be found in the Google Cloud Platform console on the **APIs & Services > OAuth consent screen** page. You can only view the publishing status if the **User type** is set to **External**. By default, Google OAuth apps are set to the **"Testing"** [publishing status](https://support.google.com/cloud/answer/10311615#publishing-status), which is intended for internal testing before opening connections to your [intended audience](https://support.google.com/cloud/answer/10311615#user-type). It's limited to 100 test users and depending on the requested OAuth scopes, they might need to be explicitly added to your trusted user list to be able to connect. To switch a Google OAuth app to production, **you must set the publishing status to "In production".** This involves a verification process with regard to your app name, logo, and scopes requested before Google accepts the switch to production. Ensure that your Clerk production app always uses a corresponding Google OAuth app that is set to the **"In production"** publishing status, so your end users don't encounter any issues using Google as a social connection. ### Block email subaddresses By default, your app will block any Google account with an email address that contains the characters `+`, `=` or `#` from being able to sign up, sign in, or be added to existing accounts. For a Google organization with the domain `example.com`, blocking email subaddresses prevents someone with access to `user@example.com` from signing up with `user+alias@example.com`. This is a known [Google OAuth vulnerability](https://trufflesecurity.com/blog/google-oauth-is-broken-sort-of/) that could allow unauthorized, as Google organization administrators cannot suspend or delete the email alias account. It's recommended to keep this setting enabled for enhanced security. To configure this setting: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the **Google** connection. 3. Enable or disable **Block email subaddresses**. > \[!NOTE] > Existing Google accounts with email subaddresses will be blocked by this restriction and won't be able to sign in. ## Google One Tap [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) enables users to sign up or sign in to your Clerk app with the press of a button. After adding Google to your Clerk app as a social connection, you can use the prebuilt `` component to render the One Tap UI in your app. See the `` component reference to learn more. --- title: Add Discord as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Discord account with OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/discord sourceFile: /docs/guides/configure/auth-strategies/social-connections/discord.mdx --- Enabling OAuth with [Discord](https://discord.com/developers/docs/topics/oauth2) allows your users to sign up and sign in to your Clerk application with their Discord account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Discord**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Discord Developer Portal](https://discord.com/developers/applications). ### Enable Discord as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Discord**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep the modal and page open. ### Create a Discord Developer app 1. On a separate page, go to the [Discord Developer Portal](https://discord.com/developers/applications) and sign in. 2. In the top-right, select **New Application**. 3. Complete the required fields and select **Create**. You'll be redirected to the **General Information** page. 4. In the left sidenav, select **OAuth2**. 5. Under **Redirects**, select **Add Redirect**. Paste the **Redirect URI** you saved from the Clerk Dashboard. 6. Select **Save Changes**. You may need to tap anywhere on the screen for the button to show. 7. Save the **Client ID** and **Client Secret** somewhere secure. If you don't see the **Copy** button under the **Client Secret**, select **Reset Secret** to generate a new one. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add HubSpot as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their HubSpot account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/hubspot sourceFile: /docs/guides/configure/auth-strategies/social-connections/hubspot.mdx --- Enabling OAuth with HubSpot allows your users to sign up and sign in to your Clerk application with their HubSpot account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **HubSpot**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials, which involves generating your own **Client ID** and **Client Secret** using your HubSpot Developer account. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [HubSpot developer account](https://app.hubspot.com/signup-hubspot/developers). ### Enable HubSpot as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **HubSpot**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep this modal and page open. ### Create a HubSpot Developer project 1. Navigate to the [HubSpot account selection page](https://app.hubspot.com/myaccounts-beta) and select the **developer** account you want to use. You'll be redirected to the **Developer home** page. 2. Select **Create app**. You'll be redirected to the app's configuration settings. 3. In the **App Info** tab, complete the form. The **Public app name** is required. 4. Select the **Auth** tab. 5. In the **Redirect URLs** section, paste the **Redirect URI** value you saved from the Clerk Dashboard. 6. In the **Scopes** section, select **Add new scope**. 7. Enable the **crm.objects.owners.read** scope and select **Update**. 8. Select **Create app**. You'll be redirected back to the **App Info** tab. 9. Select the **Auth** tab. 10. Save the **Client ID** and **Client Secret** values somewhere secure. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Dropbox as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Dropbox account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/dropbox sourceFile: /docs/guides/configure/auth-strategies/social-connections/dropbox.mdx --- Enabling OAuth with Dropbox allows your users to sign up and sign in to your Clerk application with their Dropbox account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Dropbox**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Dropbox App Console](https://www.dropbox.com/developers/apps). ### Enable Dropbox as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Dropbox**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep this modal and page open. ### Configure your Dropbox app 1. In the [Dropbox App Console](https://www.dropbox.com/developers/apps), select a project or [create a new one](https://www.dropbox.com/developers/apps/create). 2. On your app's **Settings** page, save the **App key** and **App secret** somewhere secure. 3. In the **Redirect URIs** input, paste the **Redirect URI** value you saved from the Clerk Dashboard and select **Add**. ### Set the App Key and App Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **App key** and **App secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is not still open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, you can paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Hugging Face as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Hugging Face account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/hugging-face sourceFile: /docs/guides/configure/auth-strategies/social-connections/hugging-face.mdx --- Enabling OAuth with [Hugging Face](https://huggingface.co/) allows your users to sign up and sign in to your Clerk application with their Hugging Face account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs — no other configuration is needed. To configure your development instance, follow these steps: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the **Add connection** button and select **For all users**. 3. In the **Choose provider** dropdown, select **Hugging Face**. 4. Select **Add connection**. ## Configure for your production instance In *production instances*, you must provide custom credentials. To configure your production instance, follow these steps: ### Enable Hugging Face as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the **Add connection** button and select **For all users**. 3. In the **Choose provider** dropdown, select **Hugging Face**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URL** somewhere secure. Keep this modal and page open. ### Create a Hugging Face Connected App 1. In the top-right of [Hugging Face](https://huggingface.co/), select your avatar and select **Settings**. 2. In the left sidenav, select **Connected Apps**. 3. Under **Developer Applications**, select **Create App**. 4. Complete the form. Under **Scopes**, select the scopes that your app requires. At minimum, select **openid**, **profile**, and **email**. Under **Redirect URLs**, paste the **Redirect URL** value you saved from the Clerk Dashboard. 5. Select **Create**. The page should refresh and display the **Client ID** and **App Secret**. Save these values somewhere secure. ### Set the Client ID and App Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **App Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is not still open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, you can paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Facebook as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Facebook account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/facebook sourceFile: /docs/guides/configure/auth-strategies/social-connections/facebook.mdx --- Enabling OAuth with Facebook allows your users to sign up and sign in to your Clerk app with their Facebook account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Facebook**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Facebook Developer](https://developers.facebook.com) page. ### Enable Facebook as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Facebook**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep this modal and page open. ### Create a Facebook app 1. In the top-right of the Facebook Developer page, select [**My Apps**](https://developers.facebook.com/apps). 2. In the top-right, select **Create App**. You'll be redirected to the **Create an app** process. 1. In the **App details** step, fill out the necessary information and select **Next**. 2. In the **Use Cases** step, select **Authenticate and request data from users with Facebook Login** and then select **Next**. 3. In the **Business** step, select the business portfolio to connect to your app and then select **Next**. 4. In the **Finalize** step, select **Go to dashboard**. You'll be redirected to the app's **Dashboard** page. 3. In the left sidenav, select **Use cases**. 4. Next to **Authenticate and request data from users with Facebook Login**, select **Customize**. You'll be redirected to the **Permissions** tab of the **Customize use case** page. 5. Next to **email**, select **Add**. This permission allows Clerk to read your user's primary email address. 6. In the left sidenav, under **Facebook Login**, select **Settings**. 7. In the **Client OAuth settings** section, in the **Valid OAuth Redirect URIs** field, paste the **Redirect URI** value you saved from the Clerk Dashboard. 8. Select **Save changes**. 9. In the left sidenav, select **App settings** (hover over the settings icon to view the title or expand the menu), and then select **Basic**. 10. Save the **App ID** and **App Secret** somewhere secure. ### Set the App ID and App Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **App ID** and **App Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is not still open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, you can paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add LINE as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their LINE account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/line sourceFile: /docs/guides/configure/auth-strategies/social-connections/line.mdx --- Enabling OAuth with LINE allows your users to sign up and sign in to your Clerk app with their LINE account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **LINE**. 4. Select **Add connection**. Clerk's preconfigured shared OAuth credentials use **Japan** as the LINE region. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [LINE Developers Console](https://developers.line.biz/console/). ### Enable LINE as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **LINE**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Callback URL** somewhere secure. Keep this modal and page open. ### Create a LINE app 1. In the [LINE Developers Console](https://developers.line.biz/console/), select **Create a new provider**. A modal will open. 2. Fill out the necessary information. Select **Create**. You'll be redirected to the app's **Channels** tab. 3. Select **Create a LINE Login channel**. 4. Fill out the necessary information. Select **Create**. You'll be redirected to the app's **Basic settings**. 5. Save the **Channel ID** and **Channel secret** somewhere secure. 6. Select the **LINE Login** tab. 7. Under **Callback URL**, select **Edit**. Paste the **Callback URL** value you saved from the Clerk Dashboard. 8. Select **Update**. ### Set the Channel ID and Channel Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Channel ID** and **Channel Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is not still open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, you can paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add GitHub as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their GitHub account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/github sourceFile: /docs/guides/configure/auth-strategies/social-connections/github.mdx --- Enabling OAuth with [GitHub](https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app) allows your users to sign up and sign in to your Clerk app with their GitHub account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **GitHub**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for [GitHub's Developer Settings](https://github.com/settings/apps). ### Enable GitHub as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and choose **For all users**. 3. In the **Choose provider** dropdown, select **GitHub**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Authorization Callback URL** somewhere secure. Keep the modal and page open. ### Create a GitHub app 1. In the left sidenav of your [GitHub's Developer Settings](https://github.com/settings/apps), select **OAuth Apps**. 2. Select **New OAuth app**. You'll be redirected to the **Register a new OAuth app** page. 3. Complete the required fields. In **Authorization Callback URL**, paste the **Authorization Callback URL** you saved from the Clerk Dashboard. 4. Select **Register application**. You'll be redirected to your app's **General** page. 5. Select **Generate a new client secret**. Save the **Client ID** and **Client Secret** somewhere secure. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Linear as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Linear account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/linear sourceFile: /docs/guides/configure/auth-strategies/social-connections/linear.mdx --- Enabling OAuth with [Linear](https://developers.linear.app/docs/oauth/authentication) allows your users to sign up and sign in to your Clerk app with their Linear account. > \[!IMPORTANT] > You must be a workspace admin to create and manage OAuth apps in Linear. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Linear**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Linear's API settings](https://linear.app/clerk/settings/api) page. ### Enable Linear as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Linear**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Callback URL** somewhere secure. Keep the modal and page open. ### Create a Linear app 1. In the top-left of [Linear](https://linear.app/), select your workspace, then select **Settings**. 2. In the sidenav, under **Account**, select **API**. Scroll down to **OAuth Applications** and select **Create new OAuth Application**. You'll be navigated to the [**Create new application**](https://linear.app/clerk/settings/api/applications/new) page. 3. Complete the required fields. In **Callback URLs**, paste the **Redirect URI** you saved from the Clerk Dashboard. 4. Select **Save**. The page will refresh and you should see the **Client ID** and **Client Secret** at the top. Save both values somewhere secure. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add LinkedIn Open ID Connect (OIDC) as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their LinkedIn Open ID Connect (OIDC) account. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/linkedin-oidc sourceFile: /docs/guides/configure/auth-strategies/social-connections/linkedin-oidc.mdx --- Enabling OpenID Connect (OIDC) with [LinkedIn](https://learn.microsoft.com/en-us/linkedin/shared/authentication/authentication) allows your users to sign up and sign in to your Clerk application with their LinkedIn account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs — no other configuration is needed. To configure your development instance, follow these steps: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the **Add connection** button and select **For all users**. 3. In the **Choose provider** dropdown, select **LinkedIn**. 4. Select **Add connection**. ## Configure for your production instance In *production instances*, you must provide custom credentials, which involves generating your own **Client ID** and **Client Secret** using your LinkedIn Developer account. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [LinkedIn Developer Portal](https://developer.linkedin.com/). ### Enable LinkedIn as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the **Add connection** button, and select **For all users**. 3. In the **Choose provider** dropdown, select **LinkedIn**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep this modal and page open. ### Create a LinkedIn application > \[!TIP] > If you already have a LinkedIn app you'd like to connect to Clerk, select your app from the [**My apps**](https://www.linkedin.com/developers/apps?appStatus=active) page in the LinkedIn Developer Portal and proceed to the [next step](#set-the-client-id-and-primary-client-secret-in-the-clerk-dashboard) in this tutorial. 1. On the homepage of the [LinkedIn Developer Portal](https://developer.linkedin.com/), select **Create app**. You'll be redirected to the **Create an app** form. 2. Fill out the necessary information. Then, select **Create app**. You'll be redirected to the app's **Products** page. 3. Select the **Auth** tab. 4. Under **Application credentials**, save the **Client ID** and **Primary Client Secret** somewhere secure. 5. Under the **OAuth 2.0 settings** section, next to **Authorized redirect URLs for your app**, select the **Edit** icon. 6. Select **Add redirect URL** and paste the **Redirect URL** you copied from the Clerk Dashboard. 7. Select **Update**. ### Set the Client ID and Primary Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Primary Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Enable OpenID Connect in your LinkedIn application 1. Select the **Products** tab. 2. Next to **Sign In with LinkedIn using OpenID Connect**, select **Request access**. A modal will open. 3. Follow the instructions and select **Request access**. > \[!NOTE] > If you need to ensure the longevity of the user's access token without requiring re-authentication, consider getting approval as a [Marketing Developer Platform (MDP) partner](https://learn.microsoft.com/en-us/linkedin/marketing/quick-start?view=li-lms-2023-10#step-1-apply-for-api-access). This isn't necessary if you don't directly interact with the LinkedIn API using the access token. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: LinkedIn (deprecated) description: Learn how to set up social connection with LinkedIn. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/linkedin sourceFile: /docs/guides/configure/auth-strategies/social-connections/linkedin.mdx --- > \[!CAUTION] > This page is now deprecated. Please see the new [guide](/docs/guides/configure/auth-strategies/social-connections/linkedin-oidc) on how to set up a social connection with LinkedIn. ## Overview Adding social connection with LinkedIn to your app with Clerk is done in a few steps - you only need to set the **Client ID**, **Client Secret** and **Authorized Redirect URI** in your instance settings. To make the development flow as smooth as possible, Clerk uses preconfigured shared OAuth credentials and redirect URIs for development instances - no other configuration is needed. For production instances, you will need to generate your own Client ID and Client secret using your LinkedIn account. > \[!NOTE] > The purpose of this guide is to help you create a LinkedIn account and a LinkedIn OAuth app - if you're looking for step-by-step instructions using Clerk to add social connection (OAuth) to your application, follow the [Social connection (OAuth) guide](/docs/guides/configure/auth-strategies/social-connections/overview). ## Before you start * You need to create a Clerk Application in the [Clerk Dashboard](https://dashboard.clerk.com/). For more information, see the [setup guide](/docs/getting-started/quickstart/setup-clerk). * You need to have a LinkedIn account. To create one, [click here](https://developer.linkedin.com/). ## Configuring LinkedIn social connection First, you need to create a new OAuth LinkedIn app. ![Creating an OAuth LinkedIn app](/docs/images/authentication-providers/linkedin/148540a6928a19c42d105d50c91bd4a61c1d3326-1096x978.png) You need to set a name, associate a LinkedIn page with it, and upload a logo for your new application. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. Select the **Add connection** button, and select **For all users**. In the **Choose provider** dropdown, select **LinkedIn**. Toggle on **Use custom credentials** and copy **Authorized Redirect URI**. Paste the value into the **Redirect URL** of your LinkedIn app, as shown below. ![Obtaining the Application ID and Client secret](/docs/images/authentication-providers/linkedin/c3532a2089d98362370241bc43355e95035555da-1089x837.png) The last thing you have to do is to enable the *Sign in with LinkedIn* product for your OAuth application. ![Enable Sign In with LinkedIn product](/docs/images/authentication-providers/linkedin/9b2aae3fa3612dd7ae3b982b2c5a7e1d41409d49-1064x765.png) > \[!NOTE] > If you need to ensure the longevity of the user's access token without the need for re-authentication, make sure to obtain approval as a [Marketing Developer Platform (MDP) partner](https://learn.microsoft.com/en-us/linkedin/marketing/quick-start?view=li-lms-2023-10#step-1-apply-for-api-access). This is not required if you don't directly interact with the LinkedIn API using the access token. Copy the **Application ID** and **Secret** from the previous screen. Go back to the Clerk Dashboard and paste them into the respective fields. Finally, select **Add connection** so that the settings are applied. Congratulations! Social connection with LinkedIn is now configured for your instance. --- title: Add Microsoft Azure Entra ID as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Microsoft account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/microsoft sourceFile: /docs/guides/configure/auth-strategies/social-connections/microsoft.mdx --- Enabling OAuth with Microsoft Azure Entra ID (formerly [Active Directory](https://learn.microsoft.com/en-us/entra/fundamentals/new-name)) allows your users to sign up and sign in to your Clerk app with their Microsoft account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Microsoft**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. If you already [configured Microsoft as an EASIE connection](/docs/guides/configure/auth-strategies/enterprise-connections/easie/microsoft), you can skip this step. EASIE SSO will automatically use the credentials you configured for your enterprise connection. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Microsoft Azure portal](https://portal.azure.com). ### Enable Microsoft as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Microsoft**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep this modal and page open. ### Create a Microsoft Entra ID app > \[!TIP] > If you already have a Microsoft Entra ID app you'd like to connect to Clerk, select your app from the [Microsoft Azure portal](https://portal.azure.com/#home) and skip to [the next step in this tutorial](#get-your-client-id-and-client-secret). 1. On the homepage of the [Microsoft Azure portal](https://portal.azure.com/#home), in the **Azure services** section, select **[Microsoft Entra ID](https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/Overview)**. 2. In the sidenav, open the **Manage** dropdown and select **[App registrations](https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/RegisteredApps)**. 3. Select **New Registration**. You'll be redirected to the **Register an application** page. 4. Complete the form as follows: 1. Under **Name**, enter your app name. 2. Under **Supported account types**, select **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)**. 3. Under **Redirect URI (Optional)**, select **Web** as the platform and enter the **Redirect URI** you saved from the Clerk Dashboard. 4. Select **Register** to submit the form. You'll be redirected to the **Overview** page of your new app. Keep this page open. ### Get your Client ID and Client Secret 1. From your app's **Overview** page, save the **Application (client) ID** somewhere secure. 2. In the sidenav, select **Certificates & secrets**. 3. Select **New client secret**. 4. In the modal that opens, enter a description and set an expiration time for your secret. > \[!WARNING] > Microsoft requires an expiration time for client secrets. The default is 6 months, and the maximum is 24 months. When your secret expires, your social connection will stop working until you generate a new secret. It's recommended to set a reminder before the expiration date to avoid disruption to your sign-in flow. 5. Select **Add**. 6. Save the **Value** somewhere secure. ### Enable OpenID 1. In the left sidenav, open the **Manage** dropdown and select **Authentication**. 2. In the **Front-channel logout URL** field, paste the **Redirect URI** you copied from the Clerk Dashboard. 3. Under **Implicit grant and hybrid flows**, check both **Access tokens** and **ID tokens**. 4. Select **Save** to save the changes. ### Secure your app against the nOAuth vulnerability [nOAuth](https://www.descope.com/blog/post/noauth) is an exploit in Microsoft Entra ID OAuth apps that can lead to account takeovers via email address spoofing. Clerk mitigates this risk by enforcing stricter checks on verified email addresses. For further security, Microsoft offers an optional `xms_edov` [claim](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims-reference), which provides additional context to determine whether the returned email is verified. > \[!IMPORTANT] > When adding the `xms_edov` claim in the Azure portal, you may see a warning saying it's invalid or not recognized. You can safely ignore this warning - `xms_edov` is fully supported and documented by Microsoft Entra ID for stronger email domain verification, but the Azure portal's token configuration UI may not recognize it yet. To enable it, you must: 1. In the left sidenav, in the **Manage** dropdown, select **Token configuration**. 2. Select **Add optional claim**. 3. For the **Token type**, select **ID**. Then, in the table that opens, enable the `email` and `xms_pdl` claims. 4. At the bottom of the modal, select **Add**. A new modal will prompt you to turn on the Microsoft Graph email permission. Enable it, then select **Add** to complete the form. 5. Repeat the previous steps but for **Token type**, select **Access** instead of **ID**. The **Optional claims** list should now show two claims for `email` and two for `xms_pdl`: one each for **ID** and **Access**. 6. In the left sidenav, in the **Manage** dropdown, select **Manifest**. 7. In the text editor, search for `"acceptMappedClaims"` and set its value from `null` to `true`. 8. Search for `"optionalClaims"`, where you'll find the `idToken` and `accessToken` arrays. Each array has an object with the name `xms_pdl`. Change the name to `xms_edov`. 9. At the top of the page, select **Save**. 10. In the left sidenav, in the **Manage** dropdown, select **Token configuration** to confirm that the **Optional claims** list includes two claims for `email` and two for `xms_edov`: one each for **ID** and **Access**. With these steps complete, Microsoft will send the `xms_edov` claim in the token, which Clerk will use to determine whether the email is verified, even when used with Microsoft Entra ID. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. ## Limitations * Currently, Clerk supports only the `common` tenant type, which allows sign-ins both from organization members and public Microsoft users. * The option to selecting the desired tenant type (`common`, `organizations`, `consumers` or specific tenant ID) will be available in an upcoming version of Clerk. * Only credentials of type `secret` are supported (not the `certificate` type). > \[!TIP] > If you're using [SAML with Microsoft](/docs/guides/configure/auth-strategies/enterprise-connections/saml/azure), the different tenant types *are* supported, and you can disregard these limitations. --- title: Add Notion as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Notion account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/notion sourceFile: /docs/guides/configure/auth-strategies/social-connections/notion.mdx --- Enabling OAuth with Notion allows your users to sign up and sign in to your Clerk app with their Notion account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Notion**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Notion Developer](https://developers.notion.com) page. ### Enable Notion as a social connection 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Notion**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Authorization URL** somewhere secure. Keep this modal and page open. ### Create a Notion app 1. In the top-right of the [Notion Developer](https://developers.notion.com) home page, select **View my integrations**. You'll be redirected to the **Integrations** page. 2. Select **New integration**. 3. Fill out the necessary information. In the **Type** dropdown, select **Public**. Under **Authorization URL**, paste the **Authorization URL** value you saved from the Clerk Dashboard and then select it. 4. Select **Save**. The **Integration successfully created** modal will open. Select **Configure integration settings**. You'll be redirected to the app's **Configuration** page. 5. Save the **OAuth Client ID** and **OAuth Client Secret** somewhere secure. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Social connections (OAuth) description: Learn how to effortlessly add social connections to your application using popular social providers like Google, Facebook, GitHub and more. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/overview sourceFile: /docs/guides/configure/auth-strategies/social-connections/overview.mdx --- Social connections, also known as OAuth connections in Clerk, allow users to gain access to your application by using their existing credentials from an Identity Provider (IdP), like Google or Microsoft. For example, if you enable Google as a social provider, then when a user wants to sign in to your application, they can select Google and use their Google account to sign in. > \[!NOTE] > When using social connections, the sign-up and sign-in flows are equivalent. If a user doesn't have an account and tries to sign in, an account will be made for them, and vice versa. The easiest way to add social connections to your Clerk app is by using prebuilt components. If prebuilt components don't meet your specific needs or if you require more control over the logic, you can [rebuild the existing Clerk flows using the Clerk API](/docs/guides/development/custom-flows/authentication/oauth-connections). ## Before you start * You need to create a Clerk application in the [Clerk Dashboard](https://dashboard.clerk.com/). For more information, check out the [setup guide](/docs/getting-started/quickstart/setup-clerk). * You need to install the correct SDK for your application. For more information, see the [quickstart guides](/docs/getting-started/quickstart/overview). ## Enable a social connection ### Development instances For **development** instances, Clerk uses **pre-configured shared** OAuth credentials and redirect URIs to make the development flow as smooth as possible. This means that you can enable most social providers **without additional configuration**. To enable a social connection: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the **Add connection** button, and select **For all users**. 3. In the **Choose provider** dropdown, select the provider you want to use. 4. Select **Add connection**. ### Production instances For **production** instances, you will need to configure the provider with custom OAuth credentials. See the social provider's [dedicated guide](/docs/guides/configure/auth-strategies/social-connections/all-providers) for more information. ## Configure additional OAuth scopes Each OAuth provider requires a specific set of scopes that are necessary for proper authentication with Clerk. These essential scopes are pre-configured and automatically included by Clerk. They typically include permissions for basic profile information and email access, which are fundamental for user authentication and account creation. In addition to the core scopes, you can specify additional scopes supported by the provider. These scopes can be used to access additional user data from the provider. To add additional OAuth scopes, when you are [enabling a new social connection](#enable-a-social-connection), enable **Use custom credentials**. The **Scopes** field will appear. ## Request additional OAuth scopes after sign-up Clerk allows you to request additional OAuth scopes even after a user has signed up. Pass the additionalOAuthScopes prop to the \ or \ component, with any additional OAuth scope you would like per provider. The user will be prompted to reconnect their account on their user profile page. Use the following tabs to see how to add additional OAuth scopes to the `` and `` components. ", ""]}> ```tsx {{ filename: 'app/page.tsx' }} ``` ```tsx {{ filename: 'app/page.tsx' }} ``` ## Get an OAuth access token for a social provider You can use a social provider's OAuth access token to access user data from that provider in addition to their data from Clerk. Use the getUserOauthAccessToken() method to get the user's OAuth access token. **This method must be used in a server environment, and cannot be run on the client.** Clerk ensures that the OAuth access token will be always fresh so that you don't have to worry about refresh tokens. The following example demonstrates how to retrieve the OAuth access token for a user and use it to fetch user data from the Notion API. It assumes: * You have already [enabled the Notion social connection in the Clerk Dashboard](/docs/guides/configure/auth-strategies/social-connections/notion). * The user has already connected their Notion account to your application. * The user has the correct permissions to access the Notion API. **If your SDK isn't listed, you can use the comments in the example to help you adapt it to your SDK.** ```tsx {{ filename: 'app/api/notion/route.tsx' }} import { auth, clerkClient } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function GET() { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await auth() // Protect the route from unauthenticated users if (!isAuthenticated) { return NextResponse.json({ message: 'User not found' }) } const provider = 'notion' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const client = await clerkClient() // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token const clerkResponse = await client.users.getUserOauthAccessToken(userId, provider) const accessToken = clerkResponse.data[0].token || '' if (!accessToken) { return NextResponse.json({ message: 'Access token not found' }, { status: 401 }) } // Fetch the user data from the Notion API // This endpoint fetches a list of users // https://developers.notion.com/reference/get-users const notionUrl = 'https://api.notion.com/v1/users' const notionResponse = await fetch(notionUrl, { headers: { Authorization: `Bearer ${accessToken}`, 'Notion-Version': '2022-06-28', }, }) // Handle the response from the Notion API const notionData = await notionResponse.json() return NextResponse.json({ message: notionData }) } ``` ```tsx {{ filename: 'src/api/notion.ts' }} import { clerkClient } from '@clerk/astro/server' import type { APIRoute } from 'astro' export const GET: APIRoute = async (context) => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/references/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = context.locals.auth() // Protect the route from unauthenticated users if (!isAuthenticated) { return new Response('Unauthorized', { status: 401 }) } const provider = 'notion' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token const clerkResponse = await clerkClient(context).users.getUserOauthAccessToken(userId, provider) const accessToken = clerkResponse.data[0].token || '' if (!accessToken) { return new Response('Access token not found', { status: 401 }) } // Fetch the user data from the Notion API // This endpoint fetches a list of users // https://developers.notion.com/reference/get-users const notionUrl = 'https://api.notion.com/v1/users' const notionResponse = await fetch(notionUrl, { headers: { Authorization: `Bearer ${accessToken}`, 'Notion-Version': '2022-06-28', }, }) // Handle the response from the Notion API const notionData = await notionResponse.json() // Return the Notion data return new Response(JSON.stringify({ notionData })) } ``` ```js {{ filename: 'notion.js' }} import { createClerkClient, getAuth } from '@clerk/express' import express from 'express' const app = express() // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) app.get('/user', async (req, res) => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = getAuth(req) // Protect the route from unauthenticated users if (!isAuthenticated) { res.status(401).json({ error: 'User not authenticated' }) } const provider = 'notion' // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token const clerkResponse = await clerkClient.users.getUserOauthAccessToken(userId, provider) const accessToken = clerkResponse.data[0].token || '' if (!accessToken) { res.status(401).json({ error: 'Access token not found' }) } // Fetch the user data from the Notion API // This endpoint fetches a list of users // https://developers.notion.com/reference/get-users const notionUrl = 'https://api.notion.com/v1/users' const notionResponse = await fetch(notionUrl, { headers: { Authorization: `Bearer ${accessToken}`, 'Notion-Version': '2022-06-28', }, }) // Handle the response from the Notion API const notionData = await notionResponse.json() // Return the Notion data res.json(notionData) }) ``` ```js import { createClerkClient } from '@clerk/backend' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) async function getNotionData(request) { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = request.auth // Protect the route from unauthenticated users if (!isAuthenticated) { return null } // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token const provider = 'notion' const clerkResponse = await clerkClient.users.getUserOauthAccessToken(userId, provider) const accessToken = clerkResponse.data[0].token || '' if (!accessToken) { return null } // Fetch the user data from the Notion API // This endpoint fetches a list of users // https://developers.notion.com/reference/get-users const notionUrl = 'https://api.notion.com/v1/users' const notionResponse = await fetch(notionUrl, { headers: { Authorization: `Bearer ${accessToken}`, 'Notion-Version': '2022-06-28', }, }) // Handle the response from the Notion API const notionData = await notionResponse.json() // Return the Notion data return notionData } ``` ```tsx {{ filename: 'app/routes/notion.tsx' }} import { getAuth } from '@clerk/react-router/ssr.server' import { createClerkClient } from '@clerk/react-router/api.server' import type { Route } from './+types/notion' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) export async function loader(args: Route.LoaderArgs) { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await getAuth(args) // Protect the route from unauthenticated users if (!isAuthenticated) { return new Response('User not authenticated', { status: 404, }) } const provider = 'notion' // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token const clerkResponse = await clerkClient.users.getUserOauthAccessToken(userId, provider) const accessToken = clerkResponse.data[0].token || '' if (!accessToken) { return new Response('Access token not found', { status: 401, }) } // Fetch the user data from the Notion API // This endpoint fetches a list of users // https://developers.notion.com/reference/get-users const notionUrl = 'https://api.notion.com/v1/users' const notionResponse = await fetch(notionUrl, { headers: { Authorization: `Bearer ${accessToken}`, 'Notion-Version': '2022-06-28', }, }) // Handle the response from the Notion API const notionData = await notionResponse.json() // Return the Notion data return json({ notionData }) } ``` ```tsx {{ filename: 'app/routes/api/notion.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { auth, clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/notion')({ server: { handlers: { GET: async () => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await auth() // Protect the route from unauthenticated users if (!isAuthenticated) { return new Response('User not authenticated', { status: 404, }) } const provider = 'notion' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart // Use the `getUserOauthAccessToken()` method to get the user's OAuth access token const clerkResponse = await clerkClient().users.getUserOauthAccessToken(userId, provider) const accessToken = clerkResponse.data[0].token || '' if (!accessToken) { return new Response('Access token not found', { status: 401, }) } // Fetch the user data from the Notion API // This endpoint fetches a list of users // https://developers.notion.com/reference/get-users const notionUrl = 'https://api.notion.com/v1/users' const notionResponse = await fetch(notionUrl, { headers: { Authorization: `Bearer ${accessToken}`, 'Notion-Version': '2022-06-28', }, }) // Handle the response from the Notion API const notionData = await notionResponse.json() return json(notionData) }, }, }, }) ``` ## Add a social connection after sign-up For each social provider, you can disable the option to sign up and sign in to your application using the provider. This is especially useful for users that want to connect their OAuth account *after* authentication. For example, say your application wants to read a user's GitHub repository data but doesn't want to allow the user to authenticate with their GitHub account. The user can sign up with their email and password, or whatever authentication method you choose, and then afterwards, connect their GitHub account to your application through their user profile. The easiest way to enable this for your users is by using the \ component. If you prefer to build a custom user interface, see how to [build a social connection flow using the Clerk API](/docs/guides/development/custom-flows/authentication/oauth-connections). To configure the option for users to sign up and sign in with a social provider: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the social provider you want to configure. 3. Enable or disable **Enable for sign-up and sign-in**. 4. Save the changes. ## Connecting to social providers while signed in When signed in, a user can connect to further social providers. There is no need to perform another sign-up. When using the [Account Portal](/docs/guides/customizing-clerk/account-portal) pages, users can see which providers they have already connected to and which ones they can still connect to on their [user profile page](/docs/guides/customizing-clerk/account-portal#user-profile). When using the prebuilt components, you can use the \ component to allow users to connect to further social providers. ## OAuth for native applications Currently, the prebuilt components are not supported in native applications, but you can use the Clerk API to [build a custom flow for authenticating with social connections](/docs/guides/development/custom-flows/authentication/oauth-connections). Clerk ensures that security critical nonces are passed only to allowlisted URLs when the OAuth flow is completed in native browsers or webviews. For maximum security in your **production** instances, you need to allowlist your custom redirect URLs via the [Clerk Dashboard](https://dashboard.clerk.com/) or the Clerk Backend API. To allowlist a redirect URL via the Clerk Dashboard: 1. In the Clerk Dashboard, navigate to the [**Native applications**](https://dashboard.clerk.com/~/native-applications) page. 2. Scroll to the **Allowlist for mobile OAuth redirect** section and add your redirect URLs. ## OAuth for Apple native applications You can use [Sign in with Apple](https://developer.apple.com/sign-in-with-apple/) to offer a native authentication experience in your iOS, watchOS, macOS or tvOS apps. Instead of the typical OAuth flow that performs redirects in a browser context, you can utilize Apple's native authorization and provide the openID token and grant code to Clerk. Clerk ensures that the user will be verified in a secure and reliable way with the information that Apple has provided about the user. For additional information on how to configure Apple as a social provider for your Clerk instance, see the [dedicated guide](/docs/guides/configure/auth-strategies/social-connections/apple). --- title: Add Slack as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Slack account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/slack sourceFile: /docs/guides/configure/auth-strategies/social-connections/slack.mdx --- Enabling OAuth with [Slack](https://api.slack.com/authentication) allows your users to sign up and sign in to your Clerk app with their Slack account. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Slack**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Slack's API Platform](https://api.slack.com/). ### Enable Slack as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Slack**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URL** somewhere secure. Keep the modal and page open. ### Create a Slack app 1. In the Slack API Platform, navigate to the [**Your Apps**](https://api.slack.com/apps) page and select **Create New App**. 2. The **Create an app** modal will open. Depending on your app needs, select either **From a manifest** or **From scratch**. For more information on which to choose, refer to [Slack's doc on manifests](https://api.slack.com/reference/manifests). 3. After following the respective steps for either option, you'll be redirected to the **App Credentials** page. Save the **Client ID** and **Client Secret** somewhere secure. Keep this page open. 4. In the sidenav, navigate to the **OAuth & Permissions** page. 5. Scroll down to the **Redirect URLs** section and select **Add New Redirect URL**. Paste the **Redirect URL** you saved from the Clerk Dashboard. Select **Add**, then select **Save URLs**. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Spotify as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Spotify account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/spotify sourceFile: /docs/guides/configure/auth-strategies/social-connections/spotify.mdx --- Enabling OAuth with [Spotify](https://developer.spotify.com/documentation/web-api/concepts/authorization) allows your users to sign up and sign in to your Clerk application with their Spotify account. > \[!CAUTION] > For **development** instances, [Spotify](https://developer.spotify.com/documentation/web-api/concepts/quota-modes) requires users to be added to the app's allowlist in order to use Spotify as a social provider in your Clerk app. If they are not allowlisted, any API requests made with an access token associated with that user and the Spotify app will receive a 403 status code. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Spotify Developer Dashboard](https://developer.spotify.com/). ## Enable Spotify as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Spotify**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **Redirect URI** somewhere secure. Keep the modal and page open. ## Create a Spotify app 1. In the top-right of the [Spotify Developer Dashboard](https://developer.spotify.com/), select **Create app**. 2. Complete the required fields. For **Redirect URIs**, paste the **Redirect URI** that you saved from Clerk Dashboard. 3. Select **Save**. You'll be redirected to your app's **All Stats** page. 4. Select **Settings**. 5. Save the **Client ID** and **Client secret** somewhere secure. To get the **Client secret**, select **View client secret**. ## Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ## Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add TikTok as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their TikTok account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/tiktok sourceFile: /docs/guides/configure/auth-strategies/social-connections/tiktok.mdx --- Enabling OAuth with [TikTok](https://developers.tiktok.com/doc/login-kit-manage-user-access-tokens) allows your users to sign up and sign in to your Clerk app with their TikTok account. ## Configure for your development instance Due to TikTok's requirement to verify URL ownership for all redirect URLs, **TikTok cannot be used with shared credentials in development environments.** This is because individual users can't verify ownership of the Clerk development URL (`accounts.dev`). However, TikTok can still be used in development environments if you create a sandbox app and configure custom credentials. In this case, there is no need to verify redirect URLs in the [sandbox environment](https://developers.tiktok.com/blog/introducing-sandbox). Instead, you can invite users who are allowed to sign in. It is recommended to test this integration in a staging or preview environment, as shared credentials require URL verification to function properly. ## Configure for your production instance To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [TikTok Developer Portal](https://developers.tiktok.com/). ### Enable TikTok as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **TikTok**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. Keep the modal and page open. ### Create your app in TikTok > \[!TIP] > If you're creating an app as an organization rather than as an individual developer, you must first [create an organization](https://developers.tiktok.com/organizations). For guidance on which option to choose, refer to [TikTok's guide on working with organizations](https://developers.tiktok.com/doc/working-with-organizations/)**.** 1. On a separate page, go to the [TikTok Developer Portal](https://developers.tiktok.com/) and sign in. 2. In the top-right, select [**Developer Portal**](https://developers.tiktok.com/apps), then select **Manage apps**. You'll be redirected to the **Manage apps** page. 3. Select **Connect an app**. Complete the form then select **Confirm**. You'll be redirected to your **App details** page. 4. In the **Basic information** section, complete the form. 5. Select **Verify URL properties** under any of the URL fields to verify your app URL. A modal will open. 6. Select **Verify properties**. For the property type, select either **Domain** to verify ownership of the enter website, including subdomains, or **URL prefix** to verify ownership of a specific part of the website (e.g., `example.com/shop/`). See [the TikTok guide](https://developers.tiktok.com/doc/getting-started-create-an-app#verify_url_ownership) for more information. 7. Enter your website and select **Verify**. 8. Follow the instructions in the modal to verify your domain with your host provider. After entering the necessary information in your hosting provider's DNS settings, select **Verified**. Once your property is verified, select **Ok**. 9. Select **Submit for review**. 10. On the **App details** page, select the icons next to the **Client key** and **Client secret** to reveal them. Save these values somewhere secure. > \[!NOTE] > Your app needs to be reviewed by TikTok before the registration completes. This process may take a few days. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Add Twitch as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their Twitch account with OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/twitch sourceFile: /docs/guides/configure/auth-strategies/social-connections/twitch.mdx --- Enabling OAuth with [Twitch](https://dev.twitch.tv/docs/api/reference#oauth-client-credentials-flow) allows your users to sign up and sign in to your Clerk application with their Twitch account. You must have Two-Factor Authentication (2FA) enabled on your Twitch account to setup OAuth. To enable 2FA: 1. In the top-right of the [Twitch Developer console](https://dev.twitch.tv/console), select your avatar and select **Account Settings**. 2. Select the **Security & Privacy** tab. 3. Under **Security**, select **Set Up Two-Factor Authentication**. 4. Select **Enable 2FA**. A modal will open. 5. Enter your phone number and select **Continue**. 6. Enter the code sent to your phone and select **Continue**. 7. If you want to use an authenticator app, follow the instructions on the screen. Otherwise, select **Skip & Use SMS**. 8. Select **Done**. ## Configure for your development instance For *development instances*, Clerk uses preconfigured shared OAuth credentials and redirect URIs—no other configuration is needed. 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Twitch**. 4. Select **Add connection**. ## Configure for your production instance For *production instances*, you must provide custom credentials. To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [Twitch Developer Console](https://dev.twitch.tv/console). ### Enable Twitch as a social connection in Clerk 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select **Add connection** and select **For all users**. 3. In the **Choose provider** dropdown, select **Twitch**. 4. Ensure that both **Enable for sign-up and sign-in** and **Use custom credentials** are toggled on. 5. Save the **OAuth Redirect URL** somewhere secure. Keep the modal and page open. ### Create a Twitch Developer app 1. In the left sidenav of the [Twitch Developer Console](https://dev.twitch.tv/console), select **Applications**. 2. Select **Register Your Application**. You'll be redirected to the [**Register Your Application**](https://dev.twitch.tv/console/apps/create) page. 3. Complete the required fields. Under **OAuth Redirect URLs**, paste the **OAuth Redirect URL** you saved from the Clerk Dashboard. 4. Select **Create**. You'll be redirected to the **Developer Applications** page where you can see your new application listed. 5. Select **Manage** next to the application you created. You'll be redirected to your app's settings page. 6. Select **New Secret**. Save the **Client Secret** and **Client ID** somewhere secure. ### Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ### Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Twitter v1 (deprecated) description: Learn how to set up social connection with Twitter v1. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/twitter sourceFile: /docs/guides/configure/auth-strategies/social-connections/twitter.mdx --- > \[!CAUTION] > [X/Twitter](https://twitter.com/XDevelopers/status/1641222782594990080) considers this method deprecated. We strongly recommend using the [latest version (v2)](/docs/guides/configure/auth-strategies/social-connections/x-twitter) for future-proofing your application. How to set up social connection with Twitter v1 ## Overview Adding social connection with Twitter to your app with Clerk is done in a few steps - you only need to set the **Client ID**, **Client Secret** and **Redirect URI** in your instance settings. Clerk does not currently support preconfigured shared OAuth credentials for Twitter on development instances. You will have to provide custom credentials for both development *and* production instances, which includes generating your own Client ID and Client Secret using your Twitter Developer account. Don't worry, this guide will walk you through that process in just a few simple steps. > \[!NOTE] > The purpose of this guide is to help you create a Twitter account and a Twitter OAuth app - if you're looking for step-by-step instructions using Clerk to add social connection (OAuth) to your application, follow the [Social connection (OAuth) guide](/docs/guides/configure/auth-strategies/social-connections/overview). ## Before you start * You need to create a Clerk Application in the [Clerk Dashboard](https://dashboard.clerk.com/). For more information, see the [setup guide](/docs/getting-started/quickstart/setup-clerk). * You need to have a Twitter Application set up so it can be used as a social connection. If you don't have a Twitter Application, click [here](https://developer.twitter.com/en/docs/apps/overview) for instructions on how to create one. If you already have one, go to your [Twitter app settings](https://developer.twitter.com/en/portal/projects-and-apps) and ensure that the *"Allow this app to be used to Sign in with Twitter?*” option is enabled. ## Configuring Twitter social connection If you don't have an existing Twitter Application you've set up for social connection, you need to register a new one at the [Twitter Developer Portal](https://developer.twitter.com/en/portal/dashboard). Note that the process requires approval from Twitter before your new application can be used. To do so, go to "[Projects & Apps](https://developer.twitter.com/en/portal/projects-and-apps)" and click "**+ Add App**" to create a new application. After entering a name, you'll be presented with your app's credentials: **API Key** and **API Secret**. Copy those values as you will be needing those shortly. > \[!NOTE] > You will need your application to be approved for elevated status to be able to use it with Clerk. You can apply for the status in [Twitter developer dashboard](https://developer.twitter.com/en/portal/products/elevated) In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. Select the **Add connection** button, and select **For all users**. In the **Choose provider** dropdown, select **Twitter**. Toggle on **Use custom credentials** and paste the **API Key** and **API Secret** values which you copied in the previous step. Then, copy the **Authorized Redirect URI**. Navigate to your application settings screen and scroll down to the **User authentication settings** section and select **Set up**. ![Setting up User Authentication settings of a Twitter app](/docs/images/authentication-providers/twitter/a5b63a206cc6a04fd8b143dd191483c4f6e81d66-979x618.png) In the next screen you'll be presented with the user authentication settings. Make sure that both **OAuth 1.0a** and **Request email address from users** are enabled. Also, enter the **Authorized Redirect URI** that you grabbed in the previous step from your Clerk instance's settings and insert it in the **Callback URI** setting. Your app's settings should like similar to the ones below. Fill any other required fields and click save. Your Twitter App is now ready. ![Fill in the Callback URI](/docs/images/authentication-providers/twitter/89fc23c0ac843ba74831c669e17c44a31896a8d7-1196x954.png) Finally, select **Add connection** so that the settings are applied. Congratulations! Social connection with Twitter is now configured for your instance. --- title: Add X/Twitter v2 as a social connection description: Learn how to allow users to sign up and sign in to your Clerk app with their X/Twitter account using OAuth. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/configure/auth-strategies/social-connections/x-twitter sourceFile: /docs/guides/configure/auth-strategies/social-connections/x-twitter.mdx --- Enabling OAuth with [X/Twitter](https://developer.twitter.com/en/docs/x/overview) allows your users to sign up and sign in to your Clerk app with their X/Twitter account. Clerk doesn't currently support preconfigured shared OAuth credentials for X/Twitter on development instances. You must provide custom credentials for both development *and* production instances, which involves generating your own **Client ID** and **Client Secret** using your X/Twitter Developer account. ## Configure for your production instance To make the setup process easier, it's recommended to keep two browser tabs open: one for the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/sso-connections) and one for your [X/Twitter Developer Portal](https://developer.twitter.com/en/portal/dashboard). > \[!WARNING] > X/Twitter v2 doesn't currently provide users' email addresses. Users must manually enter their email address when they return to your application after authenticating with X/Twitter. ## Enable X/Twitter as a social connection To enable X/Twitter as a social connection for your Clerk application: 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. 2. Select the **Add connection** button, and select **For all users**. 3. In the **Choose provider** dropdown, select **X/Twitter**. 4. Save the **Redirect URI** somewhere secure. Keep the modal and page open. ## Configure additional OAuth scopes (optional) Scopes are the permissions your app requests from a user's X/Twitter account. Clerk pre-configures the required OAuth scopes for X/Twitter as a social connection, but you can configure additional scopes if needed. The scopes you define should align with your app's functionality and your selected **App Permissions** in the X/Twitter Developer Portal. For example, if you only select **Read** in the X/Twitter Developer Portal, Clerk's request for `tweet.write` will be rejected, even if you include it in Clerk's configuration. To configure OAuth scopes for X/Twitter as a social connection in Clerk: {/* TODO: "The modal should still be open" would be a good opportunity for a tooltip, and then we put the callout below into the tooltip. */} 1. In the Clerk Dashboard, the modal should still be open. Under **Scopes**, add any additional scopes you need. For a complete list of available scopes and their details, see [X/Twitter OAuth 2.0 Scopes documentation](https://docs.x.com/resources/fundamentals/authentication/oauth-2-0/authorization-code#scopes). > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. ## Create an X/Twitter application When signing up for a new X/Twitter Developer account, you'll be required to describe your app's use cases. After completing this step, you'll be redirected to the **Dashboard** page. Under **Projects**, you'll see an automatically generated app with a randomly generated string as its name. If you want to create a new X/Twitter application, follow these steps: 1. In the X/Twitter Developer Portal, under [**Projects**](https://developer.twitter.com/en/portal/projects-and-apps), select **Add App**. You'll be redirected to the **App name** tab. If you have a **Free** account, you can only have one app at a time, so you'll need to delete the existing app before being able to create a new one. 2. Enter your application name and select **Next**. You'll be redirected to the **Keys & Tokens** tab where your app's credentials are displayed. However, these credentials aren't needed to set up the X/Twitter social connection with Clerk, as the setup uses the OAuth 2.0 flow, which relies on different credentials. 3. Select **App settings**. You'll be redirected to your app's **Settings** tab. 4. Under **User authentication settings**, next to **User authentication not set up**, select **Set up**. You'll be redirected to the **User authentication settings** page. 5. Under **App permissions**, choose the permissions you want to request from your user. At minimum, select the **Read** permission. 6. Under **Type of App**, select **Web App, Automated App or Bot**. 7. Under **App info**, in the **Callback URI / Redirect URL** field, paste the **Callback URI / Redirect URL** value you copied from the Clerk Dashboard. 8. Complete any other required fields, such as the **Website URL**. 9. Select **Save**. You'll be redirected to a page that shows your app's **Client ID** and **Client Secret**. Save these values somewhere secure. ## Set the Client ID and Client Secret in the Clerk Dashboard 1. Navigate back to the Clerk Dashboard where the modal should still be open. Paste the **Client ID** and **Client Secret** values that you saved into the respective fields. 2. Select **Add connection**. > \[!NOTE] > If the modal or page is no longer open, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page in the Clerk Dashboard. Select the connection. Under **Use custom credentials**, paste the values into their respective fields. ## Test your connection The simplest way to test your connection is to visit your Clerk app's [Account Portal](/docs/guides/customizing-clerk/account-portal), which is available for all Clerk apps out-of-the-box. 1. In the Clerk Dashboard, navigate to the [**Account Portal**](https://dashboard.clerk.com/~/account-portal) page. 2. Next to **Sign-in**, select the button to visit the sign-in page. The URL should resemble: * **For development** - `https://your-domain.accounts.dev/sign-in` * **For production** - `https://accounts.your-domain.com/sign-in` 3. Sign in with your connection's credentials. --- title: Clerk Dashboard overview description: Learn how to use the Clerk Dashboard to manage your application settings, users, and more. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/dashboard/overview sourceFile: /docs/guides/dashboard/overview.mdx --- The Clerk Dashboard is where you create your Clerk application and is the central hub for managing your instance's settings, users, Organizations, and more. At the top of the Clerk Dashboard, you will see a few notable features: * The workspace dropdown: Allows you to switch between [workspaces](#workspaces). * The application dropdown: Allows you to choose which application you want to manage. * The instance dropdown: Allows you to switch between your [development and production instances](#instances). * The \: Allows you to manage your account and sign out. We try to make the Clerk Dashboard as intuitive as possible, but if you ever need help or have any feedback, you can always reach out to our [support team](https://clerk.com/support). ## Workspaces ### Create additional workspaces 1. In the top-left of the [Clerk Dashboard](https://dashboard.clerk.com), select the workspace dropdown. 2. Select **Create workspace**. A modal will open. 3. Complete the form. Workspace slugs are unique across all instances, so common naming conventions might already be in use by another instance. 4. Select **Create workspace**. The newly created workspace will be set the active workspace. ### Invite collaborators to your workspace 1. In the top-left of the [Clerk Dashboard](https://dashboard.clerk.com), select the workspace dropdown. 2. Select **Manage**. You will be redirected to the Team settings page of the active workspace. 3. Select **Invite user**. 4. In the **Invite user** form, enter the email of the user you want to invite and select the role to assign. 5. Select **Invite**. ### Transfer ownership of an application Transferring an application between two workspaces does not cause disruptions. Your API keys, settings, domains, and other configurations remain unchanged, and your app will continue to function as expected. Only the ownership is updated, so no further action is needed to maintain continuity for existing users. 1. In the top-left of the [Clerk Dashboard](https://dashboard.clerk.com), open the workspace dropdown and select the workspace that contains the application you want to transfer. 2. Locate and select the application to transfer. 3. At the top of the Clerk Dashboard, select **Configure**. 4. In the navigation sidenav, under the **Application** heading, select [**Settings**](https://dashboard.clerk.com/~/settings). 5. Select **Transfer ownership**. A modal will open. 6. Complete the form and select **Transfer ownership**. The page will redirect to the **Applications** page and show the transferred application. #### Transfer to a workspace without billing information **An application with an existing paid subscription can only be transferred to a workspace with active billing information**. You can set up billing information on the receiving workspace without being charged. To set up a payment method without being charged: 1. In the top-left of the [Clerk Dashboard](https://dashboard.clerk.com), select the workspace dropdown. 2. Select the workspace that you want to transfer the application to. 3. Select the workspace dropdown again, and select **Manage**. 4. In the top menu bar, select **Billing**, then select **Upgrade to unlimited members**. 5. Add your billing information. **You will not be charged immediately**. Doing this just ensures billing information is added to the workspace. 6. Once that billing information is added, you will be able to transfer your Clerk app to the receiving workspace. > \[!NOTE] > This is a temporary solution for this issue. Clerk is actively working to improve this process. ## Instances When creating a new application within Clerk, you are provided with two instances: `Development` and `Production`. The names are self-explanatory, but you can learn more about the differences between the two in the [dedicated guide](/docs/guides/development/managing-environments). --- title: Proxying the Clerk Frontend API description: Learn how to proxy the Clerk Frontend API through your domain. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/dashboard/dns-domains/proxy-fapi sourceFile: /docs/guides/dashboard/dns-domains/proxy-fapi.mdx --- > \[!WARNING] > This guide is for users who need to proxy the Frontend API for **production** (proxying does not work for Clerk development instances). If your application already uses a CNAME subdomain that is required for deploying with Clerk, then you must proxy the Frontend API using a different subdomain. Refer to the [deployment guide](/docs/guides/development/deployment/production#dns-records) on how to configure DNS records for deployment. Clerk supports two configuration methods for connecting to the Clerk Frontend API: CNAME and Proxy. The recommended way to connect to the Clerk Frontend API is to [set up CNAME records and use DNS](/docs/guides/development/deployment/production). However, if you're unable to use this approach, or would like more control over your integration with Clerk, you can use a proxy. When using a proxy, all requests to the Frontend API will be made through your domain. This allows you to use your own SSL certificate, and gives you more control over how you configure your application. ## How to use proxying ### Create your application and install Clerk To get started, you need to create an application from the [Clerk Dashboard](https://dashboard.clerk.com/). Once you create an instance via the Clerk Dashboard, you will be prompted to choose a domain. For the purposes of this guide, the domain will be `app.dev`. > \[!NOTE] > For more information on creating a Clerk application, see the [setup guide](/docs/getting-started/quickstart/setup-clerk). ### Configure your proxy server For this example, `/__clerk` is used as the path for the proxy. Your proxy server must be on the same domain as your application. You can choose any path you'd like, but it must be unique and not conflict with any other routes in your application. #### Requirements Requests to `https://app.dev/__clerk/*` must be forwarded to `https://frontend-api.clerk.dev/*` with the body and all headers intact. Three additional headers must be set * `Clerk-Proxy-Url`: Needs to have the full proxy URL. * `Clerk-Secret-Key`: The Secret Key for your Clerk instance. * `X-Forwarded-For`: The IP address of the original client making the request. #### Example configuration ```nginx {{ filename: 'nginx.conf' }} http { # ... server { # ... location /__clerk/ { rewrite ^/__clerk/(.*)$ /$1 break; proxy_pass https://frontend-api.clerk.dev; proxy_set_header Clerk-Proxy-Url https://app.dev/__clerk; proxy_set_header Clerk-Secret-Key sk_live_***; proxy_set_header X-Forwarded-For $remote_addr; proxy_redirect off; } } } ``` ```ts {{ filename: 'src/index.ts' }} export default { async fetch(req: Request, env: Env, _ctx: ExecutionContext): Promise { const url = req.url.replace(env.CLERK_PROXY_URL, env.CLERK_FAPI) const proxyReq = new Request(req, { redirect: 'manual', }) proxyReq.headers.set('Clerk-Proxy-Url', env.CLERK_PROXY_URL) proxyReq.headers.set('Clerk-Secret-Key', env.CLERK_SECRET_KEY) proxyReq.headers.set('X-Forwarded-For', req.headers.get('CF-Connecting-IP') || '') return fetch(url, proxyReq) }, } ``` ```toml {{ filename: 'wrangler.toml' }} name = "cloudflare-proxy" main = "src/index.ts" compatibility_date = "2023-10-02" [vars] CLERK_FAPI="https://frontend-api.clerk.dev" ``` ```env {{ filename: '.dev.vars' }} # Do not commit this file to source control CLERK_PROXY_URL="https://app.dev/__clerk" CLERK_SECRET_KEY="sk_live_xxxxx" ``` ```ts {{ filename: 'worker-configuration.d.ts' }} interface Env { CLERK_FAPI: string CLERK_PROXY_URL: string CLERK_SECRET_KEY: string } ``` > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. ```ts {{ filename: 'proxy.ts' }} import { NextResponse } from 'next/server' import { clerkMiddleware } from '@clerk/nextjs/server' function proxyMiddleware(req) { if (req.nextUrl.pathname.match('__clerk')) { const proxyHeaders = new Headers(req.headers) proxyHeaders.set('Clerk-Proxy-Url', process.env.NEXT_PUBLIC_CLERK_PROXY_URL || '') proxyHeaders.set('Clerk-Secret-Key', process.env.CLERK_SECRET_KEY || '') if (req.ip) { proxyHeaders.set('X-Forwarded-For', req.ip) } else { proxyHeaders.set('X-Forwarded-For', req.headers.get('X-Forwarded-For') || '') } const proxyUrl = new URL(req.url) proxyUrl.host = 'frontend-api.clerk.dev' proxyUrl.port = '443' proxyUrl.protocol = 'https' proxyUrl.pathname = proxyUrl.pathname.replace('/__clerk', '') return NextResponse.rewrite(proxyUrl, { request: { headers: proxyHeaders, }, }) } return null } const clerkHandler = clerkMiddleware() export default function middleware(req) { // First check if it's a proxy request const proxyResponse = proxyMiddleware(req) if (proxyResponse) { return proxyResponse } // Otherwise, use Clerk's middleware return clerkHandler(req) } export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes AND anything passed through the proxy '/(api|trpc|__clerk)(.*)', ], } ``` > \[!NOTE] > Every proxy configuration will be different and we're here to help. [Contact support](/contact/support){{ target: '_blank' }} if there's a specific use-case you're looking to solve. ### Enable proxying In order to enable proxying, you need to set a proxy URL for your Clerk instance's domain. This can be done through the Clerk Dashboard or through the Backend API. > \[!NOTE] > To avoid downtime, your proxy must be set up according to the above configuration before it can be enabled for your instance. > Make sure your proxy forwards requests to the Clerk Frontend API correctly and includes the required headers. 1. In the Clerk Dashboard, navigate to the **[Domains](https://dashboard.clerk.com/~/domains)** page. 2. In the **Frontend API** section, select the **Advanced** dropdown. 3. In the **Proxy URL** field, enter your proxy URL. The proxy URL must be a valid URL and resolve correctly. The request below will update the domain to use the proxy URL `https://app.dev/__clerk`. In doing so, it will trigger checks to validate the proxy URL. ```bash curl -X PATCH https://api.clerk.com/v1/domains/{{DOMAIN ID}} \ -H "Authorization: Bearer {{SECRET KEY}}" \ -H "Content-Type: application/json" \ -d '{"proxy_url": "https://app.dev/__clerk"}}' ``` ### Configure your proxy setup You can configure your proxy setup by either: * Setting environment variables * Using properties in your application #### Environment variables To configure your proxy setup using environment variables, your `.env` file should look like this: ```env {{ filename: '.env' }} NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} NEXT_PUBLIC_CLERK_PROXY_URL=https://app.dev/__clerk/ ``` ```env {{ filename: '.env' }} CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} CLERK_PROXY_URL=https://app.dev/__clerk ``` You will only need to set environment variables in your JavaScript application if you are using a bundler (the `NPM module` method for ClerkJS installation). If you are using the ` ``` In the following example, the fr-FR locale is imported as `frFR`. The imported localization is then passed to the `localization` prop in the ClerkApp options. ```tsx {{ filename: 'app/root.tsx', mark: [[6, 7], [39, 41]] }} import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' // Import ClerkApp import { ClerkApp } from '@clerk/remix' // fr-FR locale is imported as frFR import { frFR } from '@clerk/localizations' export const meta: MetaFunction = () => [ { charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }, ] export const loader: LoaderFunction = (args) => rootAuthLoader(args) export function Layout({ children }: { children: React.ReactNode }) { return ( {children} ) } function App() { return } export default ClerkApp(App, { localization: frFR, }) ``` ```ts {{ filename: 'src/main.ts', mark: [4, 5, 9] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' // fr-FR locale is imported as frFR import { frFR } from '@clerk/localizations' const app = createApp(App) app.use(clerkPlugin, { localization: frFR, }) app.mount('#app') ``` ```ts {{ filename: 'nuxt.config.ts', mark: [1, 2, [6, 8]] }} // fr-FR locale is imported as frFR import { frFR } from '@clerk/localizations' export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { localization: frFR, }, }) ``` ## Adding or updating a localization Clerk's localizations are customer-sourced and we encourage customers to add or update localizations. To do so, follow these steps: 1. Fork the [https://github.com/clerk/javascript/](https://github.com/clerk/javascript/) repo. 2. Clone it locally to edit it. 3. Review Clerk's [Contributing](https://github.com/clerk/javascript/blob/main/docs/CONTRIBUTING.md) guide. 4. If you are updating an existing localization locate the file in `packages/localizations/src` 5. If you are adding a new language, copy the `en-US.ts` file and name it according to your language. The naming is the abbreviated language-region. For example, for French in Canada, it would be `fr-CA.ts.` 6. Go through the file and edit the entries. 7. If you are adding a new localization, add the language to the `packages/localizations/src/index.ts` file. 8. Commit your changes to git and push them to your fork. Create a [Pull Request](https://github.com/clerk/clerk-docs/pulls) from your fork to Clerk's repo against the `main` branch. We will review and either approve or ask for updates. ## Custom localizations You can also provide your own localizations for the Clerk components. This is useful if you want to provide limited or quick localization for a language Clerk doesn't currently support, adjust the wording to match your brand, or customize default error messages. First, you need to find the key for the element that you want to customize. To find the key for your translation, open up Clerk's [English localization file](https://github.com/clerk/javascript/blob/main/packages/localizations/src/en-US.ts). Search the file for the term that you want to customize. For example, say you want to change the text of the "Continue" button on the `` component to say "LETS GO!". In this case, you'd search for "Continue". The first result that comes up is `formButtonPrimary`, which is the key for the "Continue" button. Now that you know the key, you can pass it to the `localization` prop and set the value to the text you want to display. In this case, you'd set the value to "LETS GO!", as shown in the following example. In Next.js, pass the `localization` prop to the \ component. ```tsx {{ filename: 'app/layout.tsx', mark: [[4, 7], 12] }} import { ClerkProvider } from '@clerk/nextjs' import './globals.css' // Set your customizations in a `localization` object const localization = { formButtonPrimary: 'LETS GO!', } export default function RootLayout({ children }: { children: React.ReactNode }) { return ( // Pass the `localization` object to the `localization` prop on the `` component {children} ) } ``` In Astro, pass the `localization` prop to the clerk() integration. ```tsx {{ filename: 'astro.config.mjs', mark: [[6, 10]] }} import { defineConfig } from 'astro/config' import clerk from '@clerk/astro' export default defineConfig({ integrations: [ clerk({ localization: { formButtonPrimary: 'LETS GO!', }, }), ], }) ``` In JavaScript, pass the `localization` prop to the clerk.load() method. Use the following tabs to view the code necessary for each file. ```js {{ filename: 'main.js', mark: [[6, 10]] }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load({ localization: { formButtonPrimary: 'LETS GO!', }, }) if (clerk.isSignedIn) { document.getElementById('app').innerHTML = `
` const userButtonDiv = document.getElementById('user-button') clerk.mountUserButton(userButtonDiv) } else { document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ``` ```html {{ filename: 'index.html' }} Clerk + JavaScript App
```
In Remix, pass the `localization` prop to the ClerkApp options. ```tsx {{ filename: 'app/root.tsx', mark: [[37, 41]] }} import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' // Import ClerkApp import { ClerkApp } from '@clerk/remix' export const meta: MetaFunction = () => [ { charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }, ] export const loader: LoaderFunction = (args) => rootAuthLoader(args) export function Layout({ children }: { children: React.ReactNode }) { return ( {children} ) } function App() { return } export default ClerkApp(App, { localization: { formButtonPrimary: 'LETS GO!', }, }) ``` In Vue, pass the `localization` prop to the clerkPlugin() integration. ```ts {{ filename: 'src/main.ts', mark: [[6, 10]] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const app = createApp(App) app.use(clerkPlugin, { localization: { formButtonPrimary: 'LETS GO!', }, }) app.mount('#app') ``` In Nuxt, pass the `localization` prop to the defineNuxtConfig() integration. ```ts {{ filename: 'nuxt.config.ts', mark: [[3, 7]] }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { localization: { formButtonPrimary: 'LETS GO!', }, }, }) ```
You can also customize multiple entries by passing multiple keys. The following example updates the "to continue to" subtitles on the `` component to say "to access" instead. In Next.js, pass the `localization` prop to the \ component. ```tsx {{ filename: 'app/layout.tsx', mark: [[4, 14], 19] }} import { ClerkProvider } from '@clerk/nextjs' import './globals.css' // Set your customizations in a `localization` object const localization = { signUp: { start: { subtitle: 'to access {{applicationName}}', }, emailCode: { subtitle: 'to access {{applicationName}}', }, }, } export default function RootLayout({ children }: { children: React.ReactNode }) { return ( // Pass the `localization` object to the `localization` prop on the `` component {children} ) } ``` In Astro, pass the `localization` prop to the clerk() integration. ```tsx {{ filename: 'astro.config.mjs', mark: [[6, 17]] }} import { defineConfig } from 'astro/config' import clerk from '@clerk/astro' export default defineConfig({ integrations: [ clerk({ localization: { signUp: { start: { subtitle: 'to access {{applicationName}}', }, emailCode: { subtitle: 'to access {{applicationName}}', }, }, }, }), ], }) ``` In JavaScript, pass the `localization` prop to the clerk.load() method. Use the following tabs to view the code necessary for each file. ```js {{ filename: 'main.js', mark: [[6, 17]] }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load({ localization: { signUp: { start: { subtitle: 'to access {{applicationName}}', }, emailCode: { subtitle: 'to access {{applicationName}}', }, }, }, }) if (clerk.isSignedIn) { document.getElementById('app').innerHTML = `
` const userButtonDiv = document.getElementById('user-button') clerk.mountUserButton(userButtonDiv) } else { document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ``` ```html {{ filename: 'index.html' }} Clerk + JavaScript App
```
In Remix, pass the `localization` prop to the ClerkApp options. ```tsx {{ filename: 'app/root.tsx', mark: [[37, 48]] }} import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' // Import ClerkApp import { ClerkApp } from '@clerk/remix' export const meta: MetaFunction = () => [ { charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }, ] export const loader: LoaderFunction = (args) => rootAuthLoader(args) export function Layout({ children }: { children: React.ReactNode }) { return ( {children} ) } function App() { return } export default ClerkApp(App, { localization: { signUp: { start: { subtitle: 'to access {{applicationName}}', }, emailCode: { subtitle: 'to access {{applicationName}}', }, }, }, }) ``` In Vue, pass the `localization` prop to the clerkPlugin() integration. ```ts {{ filename: 'src/main.ts', mark: [[6, 17]] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const app = createApp(App) app.use(clerkPlugin, { localization: { signUp: { start: { subtitle: 'to access {{applicationName}}', }, emailCode: { subtitle: 'to access {{applicationName}}', }, }, }, }) app.mount('#app') ``` In Nuxt, pass the `localization` prop to the defineNuxtConfig() integration. ```ts {{ filename: 'nuxt.config.ts', mark: [[3, 14]] }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { localization: { signUp: { start: { subtitle: 'to access {{applicationName}}', }, emailCode: { subtitle: 'to access {{applicationName}}', }, }, }, }, }) ```
### Example: Customize error messages You can customize Clerk's default error messages by targeting the `unstable__errors` key. This key lets you define specific error keys for different error types and assign them custom message strings. You can find the full list of error keys in the [English localization file](https://github.com/clerk/javascript/blob/main/packages/localizations/src/en-US.ts). Search for the `unstable__errors` object to find the keys you can customize. The following example updates the `not_allowed_access` error message. This message appears when a user tries to sign in with an email domain that isn't allowed to access your application. In Next.js, pass the `localization` prop to the \ component. ```tsx {{ filename: 'app/layout.tsx', mark: [[4, 9], 14] }} import { ClerkProvider } from '@clerk/nextjs' import './globals.css' const localization = { unstable__errors: { not_allowed_access: 'Send us an email if you want your corporate email domain allowlisted for access', }, } export default function RootLayout({ children }: { children: React.ReactNode }) { return ( // Add the localization prop to the ClerkProvider {children} ) } ``` ```tsx {{ filename: '_app.tsx', mark: [[4, 9], 14] }} import { ClerkProvider } from '@clerk/nextjs' import type { AppProps } from 'next/app' const localization = { unstable__errors: { not_allowed_access: 'Send us an email if you want your corporate email domain allowlisted for access', }, } function MyApp({ Component, pageProps }: AppProps) { return ( // Add the localization prop to the ClerkProvider ) } export default MyApp ``` In Astro, pass the `localization` prop to the clerk() integration. ```tsx {{ filename: 'astro.config.mjs', mark: [[6, 13]] }} import { defineConfig } from 'astro/config' import clerk from '@clerk/astro' export default defineConfig({ integrations: [ clerk({ localization: { unstable__errors: { not_allowed_access: 'Send us an email if you want your corporate email domain allowlisted for access', }, }, }), ], }) ``` In JavaScript, pass the `localization` prop to the clerk.load() method. Use the following tabs to view the code necessary for each file. ```js {{ filename: 'main.js', mark: [[6, 13]] }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load({ localization: { unstable__errors: { not_allowed_access: 'Send us an email if you want your corporate email domain allowlisted for access', }, }, }) if (clerk.isSignedIn) { document.getElementById('app').innerHTML = `
` const userButtonDiv = document.getElementById('user-button') clerk.mountUserButton(userButtonDiv) } else { document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ``` ```html {{ filename: 'index.html' }} Clerk + JavaScript App
```
In Remix, pass the `localization` prop to the ClerkApp options. ```tsx {{ filename: 'app/root.tsx', mark: [[37, 44]] }} import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' // Import ClerkApp import { ClerkApp } from '@clerk/remix' export const meta: MetaFunction = () => [ { charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }, ] export const loader: LoaderFunction = (args) => rootAuthLoader(args) export function Layout({ children }: { children: React.ReactNode }) { return ( {children} ) } function App() { return } export default ClerkApp(App, { localization: { unstable__errors: { not_allowed_access: 'Send us an email if you want your corporate email domain allowlisted for access', }, }, }) ``` In Vue, pass the `localization` prop to the clerkPlugin() integration. ```ts {{ filename: 'src/main.ts', mark: [[6, 13]] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const app = createApp(App) app.use(clerkPlugin, { localization: { unstable__errors: { not_allowed_access: 'Send us an email if you want your corporate email domain allowlisted for access', }, }, }) app.mount('#app') ``` In Nuxt, pass the `localization` prop to the defineNuxtConfig() integration. ```ts {{ filename: 'nuxt.config.ts', mark: [[3, 10]] }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { localization: { unstable__errors: { not_allowed_access: 'Send us an email if you want your corporate email domain allowlisted for access', }, }, }, }) ```
--- title: "`captcha` prop" description: Utilize Clerk's `captcha` prop in order to change the appearance of the CAPTCHA widget. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/appearance-prop/captcha sourceFile: /docs/guides/customizing-clerk/appearance-prop/captcha.mdx --- {/* JS file: https://github.com/clerk/javascript/blob/main/packages/types/src/appearance.ts#L538 */} The `captcha` property can be used to change the appearance of the CAPTCHA widget. It is passed as a parameter to the [`appearance` prop](/docs/guides/customizing-clerk/appearance-prop/overview). ## Properties * `theme` * `'auto' | 'light' | 'dark'` The CAPTCHA widget theme. Defaults to `auto`. *** * `size` * `'normal' | 'flexible' | 'compact'` The CAPTCHA widget size. Defaults to `normal`. *** * `language` * `string` The CAPTCHA widget language/locale. When setting the language for CAPTCHA, this is how localization is prioritized: * `appearance.captcha.language`: Set by this `language` property. * `localization.locale`: Set by the [`localization` prop on ``](/docs/guides/customizing-clerk/localization). Some languages are [supported by Clerk](/docs/guides/customizing-clerk/localization) but not by Cloudflare Turnstile, which is used for the CAPTCHA widget. See [Cloudflare Turnstile's supported languages](https://developers.cloudflare.com/turnstile/reference/supported-languages). * `en-US`: Clerk's default language. ## Usage ```tsx {{ prettier: false, filename: 'app.tsx' }} import { ClerkProvider } from '@clerk/nextjs'; {/* ... */} ; ``` ```js {{ filename: 'astro.config.mjs' }} import clerk from '@clerk/astro' export default defineConfig({ integrations: [ clerk({ appearance: { captcha: { theme: 'dark', size: 'flexible', language: 'es-ES', }, }, }), ], }) ``` ```tsx {{ filename: 'app.tsx', mark: [[13, 18]] }} import React from 'react' import './App.css' import { ClerkProvider } from '@clerk/clerk-react' if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) { throw new Error('Missing Publishable Key') } const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY function App() { return ( {/* ... */} ) } export default App ``` ```tsx {{ filename: 'app/root.tsx', mark: [[35, 40]] }} // Import ClerkApp import { ClerkApp } from '@clerk/remix' import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' export const meta: MetaFunction = () => ({ charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }) export const loader: LoaderFunction = (args) => rootAuthLoader(args) function App() { return ( ) } export default ClerkApp(App, { appearance: { captcha: { theme: 'dark', size: 'flexible', language: 'es-ES', }, }, }) ``` ```ts {{ filename: 'nuxt.config.ts' }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { appearance: { captcha: { theme: 'dark', size: 'flexible', language: 'es-ES', }, }, }, }) ``` ```ts {{ filename: 'src/main.ts' }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const app = createApp(App) app.use(clerkPlugin, { appearance: { captcha: { theme: 'dark', size: 'flexible', language: 'es-ES', }, }, }) app.mount('#app') ``` --- title: "`Layout` prop" description: Utilize Clerk's layout prop in order to change the layout of the and components, as well as set important links to your support, terms and privacy pages. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/appearance-prop/layout sourceFile: /docs/guides/customizing-clerk/appearance-prop/layout.mdx --- {/* JS file: https://github.com/clerk/javascript/blob/main/packages/types/src/appearance.ts#L538 */} The `layout` property can be used to change the layout of the \ and \ components, as well as set important links to your support, terms, and privacy pages. ## Properties * `animations` * `boolean` Whether to enable animations inside the components. Defaults to `true`. *** * `helpPageUrl` * `string` The URL to your help page. *** * `logoImageUrl` * `string` The URL to your logo image. By default, the components will use the logo you've set in the Clerk Dashboard. This option is helpful when you need to display different logos for different themes, for example: white logo on dark themes, black logo on light themes. *** * `logoLinkUrl` * `string` Controls where the browser will redirect to after the user clicks the application logo. If a URL is provided, it will be used as the `href` of the link. If a value is not passed in, the components will use the Home URL as set in the Clerk Dashboard. Defaults to `undefined`. *** * `logoPlacement` * `'inside' | 'outside'` The placement of your logo. Defaults to `'inside'`. *** * `privacyPageUrl` * `string` The URL to your privacy page. *** * `shimmer` * `boolean` This option enables the shimmer animation for the avatars of `` and ``. Defaults to `true`. *** * `showOptionalFields` * `boolean` Whether to show optional fields on the sign in and sign up forms. Defaults to `true`. *** * `socialButtonsPlacement` * `'bottom' | 'top'` The placement of your social buttons. Defaults to `'top'`. *** * `socialButtonsVariant` * `'blockButton' | 'iconButton' | 'auto'` The variant of your social buttons. By default, the components will use `blockButton` if you have less than 3 social providers enabled, otherwise `iconButton` will be used. *** * `termsPageUrl` * `string` The URL to your terms page. *** * `unsafe_disableDevelopmentModeWarnings` * `boolean` Whether development warnings show up in development mode. **Only enable this if you want to preview how the components will look in production.** ## Usage ```tsx {{ prettier: false, filename: 'app.tsx' }} import { ClerkProvider } from '@clerk/nextjs'; {/* ... */} ; ``` ```js {{ filename: 'astro.config.mjs' }} import clerk from '@clerk/astro' export default defineConfig({ integrations: [ clerk({ appearance: { layout: { socialButtonsPlacement: 'bottom', socialButtonsVariant: 'iconButton', termsPageUrl: 'https://clerk.com/terms', }, }, }), ], }) ``` ```ts {{ filename: 'src/main.ts' }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const app = createApp(App) app.use(clerkPlugin, { appearance: { layout: { socialButtonsPlacement: 'bottom', socialButtonsVariant: 'iconButton', termsPageUrl: 'https://clerk.com/terms', }, }, }) app.mount('#app') ``` ```ts {{ filename: 'nuxt.config.ts' }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { appearance: { layout: { socialButtonsPlacement: 'bottom', socialButtonsVariant: 'iconButton', termsPageUrl: 'https://clerk.com/terms', }, }, }, }) ``` --- title: "`Appearance` prop" description: Utilize Clerk's appearance property in order to share styles across every component or individually to any of the Clerk components. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/appearance-prop/overview sourceFile: /docs/guides/customizing-clerk/appearance-prop/overview.mdx --- {/* JS file: https://github.com/clerk/javascript/blob/main/packages/types/src/appearance.ts#L619 */} Customizing the appearance of Clerk components is a powerful way to make your application look and feel unique. Clerk provides a way to customize the appearance of its components using the `appearance` prop. The `appearance` prop can be applied to \ to share styles across every component, or individually to any of the Clerk components. This applies to all of the React-based packages, like Next.js, as well as the pure JavaScript ClerkJS package. ## Properties The `appearance` prop accepts the following properties: * `theme?` * `BaseTheme | BaseTheme[]` A theme used as the base theme for the components. For more information, see [Themes](/docs/guides/customizing-clerk/appearance-prop/themes). *** * `layout?` * `Layout` Configuration options that affect the layout of the components, allowing customizations that are hard to implement with just CSS. For more information, see [Layout](/docs/guides/customizing-clerk/appearance-prop/layout). *** * `variables?` * `Variables` General theme overrides. This styles will be merged with our base theme. Can override global styles like colors, fonts, etc. For more information, see [Variables](/docs/guides/customizing-clerk/appearance-prop/variables). *** * `elements?` * `Elements` Fine-grained theme overrides. Useful when you want to style specific elements or elements that are under a specific state. For more information, see the [Customize elements of a Clerk component](#customize-elements-of-a-clerk-component) section. *** * `captcha?` * `Captcha` Configuration options that affect the appearance of the CAPTCHA widget. For more information, see the [dedicated guide](/docs/guides/customizing-clerk/appearance-prop/captcha). *** * `cssLayerName?` * `string` The name of the CSS layer for Clerk component styles. This is useful for advanced CSS customization, allowing you to control the cascade and prevent style conflicts by isolating Clerk's styles within a specific layer. For more information on CSS layers, see the [MDN documentation on @layer](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer). ## Using a prebuilt theme Clerk offers a set of prebuilt themes that can be used to quickly style Clerk components. See the [Themes](/docs/guides/customizing-clerk/appearance-prop/themes) docs for more information. ## Customize the layout The `layout` property is used to adjust the layout of the \ and \ components, as well as set important links to your support, terms, and privacy pages. See the [Layout](/docs/guides/customizing-clerk/appearance-prop/layout) docs for more information. ## Customize the base theme The `variables` property is used to adjust the general styles of a component's base theme, like colors, backgrounds, and typography. See the [Variables](/docs/guides/customizing-clerk/appearance-prop/variables) docs for more information. ## Customize elements of a Clerk component If you want full control over the appearance of a Clerk component, you can target the underlying elements by using their CSS classes and then apply your own styles. First, you need to identify the underlying element of the Clerk component you want to style. You can do this by **inspecting** the HTML of the component. For example, if you want to style the primary button in a Clerk component, you can right-click on the primary button and select "Inspect" from the menu. This will open the browser's developer tools and highlight the element in the HTML, as shown in the following image: ![The inspect element tab opened with an element selected. It shows a list of classes and a lock icon in between human-readable classnames and randomly generated ones](/docs/images/customization/identifying_elements.png) When you select an element that is part of a Clerk component, you'll notice a list of classes like so: ```html cl-formButtonPrimary cl-button 🔒️ cl-internal-1ta0xpz ``` Any of the classes listed before the lock icon (🔒️) are safe to rely on, such as `cl-formButtonPrimary` or `cl-button` from the previous example. You'll use these classes to target the necessary elements of the Clerk component. > \[!NOTE] > Anything after the lock icon (🔒️) are internal classes used for Clerk's internal styling and should not be modified. Once you have identified the classes of the element you want to target, there are many ways to apply your custom styles depending on your preference: 1. [Use global CSS styling](#use-global-css-to-style-clerk-components) 2. [Pass custom CSS classes](#use-custom-css-classes-to-style-clerk-components) * [Using Tailwind](#use-tailwind-classes-to-style-clerk-components) * [Using CSS modules](#use-css-modules-to-style-clerk-components) 3. [Pass inline CSS to your Clerk options](#use-inline-css-objects-to-style-clerk-components) ### Use global CSS to style Clerk components You can style the elements of a Clerk component with global CSS. For this example, say you want to style the primary button in a Clerk component. You inspect the primary button to find the classes that you can use to target the element: ```html cl-formButtonPrimary cl-button 🔒️ cl-internal-1ta0xpz ``` You can then create a global CSS file, use the classes you identified to target the primary button, and apply your custom styles. In this case, `cl-formButtonPrimary` is the class you want to use because it's specific to the primary button: ```css {{ filename: 'styles/global.css' }} .cl-formButtonPrimary { font-size: 14px; text-transform: none; background-color: #611bbd; } .cl-formButtonPrimary:hover, .cl-formButtonPrimary:focus, .cl-formButtonPrimary:active { background-color: #49247a; } ``` ### Use custom CSS classes to style Clerk components You can pass additional classes to Clerk component elements by using the `elements` property on the `appearance` prop. For example, an element in a Clerk component will have classes that look something like this: ```html cl-formButtonPrimary cl-button 🔒️ cl-internal-1ta0xpz ``` Remove the `cl-` prefix from a class and use it as the key for a new object in the `elements` property. The value of this object should be the string of classes you want to apply to the element. The following example shows how to style the primary button in a `` component with custom CSS classes: ```tsx {{ mark: [4] }} ``` #### Use Tailwind classes to style Clerk components To use Tailwind CSS v4, you must set the `cssLayerName` property to ensure that Tailwind's utility styles are applied after Clerk's styles. It's recommended to add this to the `` that wraps your app so that it's applied to all Clerk components, as shown in the following example. The example names the layer `clerk` but you can name it anything you want. ```tsx {{ mark: ["cssLayerName: 'clerk'"] }} import { ClerkProvider } from '@clerk/nextjs' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ```css {{ mark: ['clerk'] }} @layer theme, base, clerk, components, utilities; @import 'tailwindcss'; ``` ```ts {{ mark: ["cssLayerName: 'clerk'"] }} import { defineConfig } from 'astro/config' import node from '@astrojs/node' import clerk from '@clerk/astro' import tailwind from '@tailwindcss/vite' export default defineConfig({ integrations: [ clerk({ appearance: { cssLayerName: 'clerk', }, }), ], output: 'server', adapter: node({ mode: 'standalone', }), vite: { plugins: [tailwind()], }, }) ``` ```css {{ mark: ['clerk'] }} @layer theme, base, clerk, components, utilities; @import 'tailwindcss'; ``` ```tsx {{ mark: ["cssLayerName: 'clerk'"] }} import { createApp } from 'vue' import './style.css' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Add your Clerk Publishable Key to the .env file') } const app = createApp(App) app.use(clerkPlugin, { appearance: { cssLayerName: 'clerk', }, publishableKey: PUBLISHABLE_KEY, }) app.mount('#app') ``` ```css {{ mark: ['clerk'] }} @layer theme, base, clerk, components, utilities; @import 'tailwindcss'; ``` ```html {{ mark: ["cssLayerName: 'clerk'"] }} ``` ```css {{ mark: ['clerk'] }} @layer theme, base, clerk, components, utilities; @import 'tailwindcss'; ``` Then, you can use Tailwind's classes to style the elements of the Clerk component. The following example shows how to use Tailwind classes to style the primary button in a `` component: ```tsx {{ mark: [4] }} ``` #### Use CSS modules to style Clerk components CSS modules are a great way to scope your CSS to a specific component. Create your module file and add the CSS you want to apply, as shown in the following example for the `` component: ```css {{ filename: 'styles/SignIn.module.css' }} .primaryColor { background-color: bisque; color: black; } ``` Then you can apply this by importing the file and using the classes whenever required: ```tsx {{ filename: 'app/layout.tsx', mark: [[9, 15]] }} import styles from '../styles/SignIn.module.css' import { ClerkProvider, SignIn } from '@clerk/nextjs' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( ) } ``` ```tsx {{ filename: 'app.tsx', mark: [[8, 14]] }} import styles from '../styles/SignIn.module.css' import { ClerkProvider, SignIn } from '@clerk/nextjs' import type { AppProps } from 'next/app' function MyApp({ pageProps }: AppProps) { return ( ) } export default MyApp ``` ### Use inline CSS objects to style Clerk components You can style the elements of a Clerk component with inline CSS objects. The following example shows how to style the primary button in a `` component with an inline CSS object: ```tsx {{ filename: 'app/layout.tsx', mark: [[9, 22]] }} import styles from '../styles/SignIn.module.css' import { ClerkProvider, SignIn } from '@clerk/nextjs' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( ) } ``` ```tsx {{ filename: 'app.tsx', mark: [[7, 20]] }} import { ClerkProvider, SignIn } from '@clerk/nextjs' import type { AppProps } from 'next/app' function MyApp({ pageProps }: AppProps) { return ( ) } export default MyApp ``` ## Next steps Here are a few resources you can utilize to customize your Clerk components further: * [Localization](/docs/guides/customizing-clerk/localization) * Learn how to localize your Clerk components. *** * [prebuilt themes](/docs/guides/customizing-clerk/appearance-prop/themes) * Explore the prebuilt themes that you can use to quickly style your Clerk components. *** * [Customize layouts](/docs/guides/customizing-clerk/appearance-prop/layout) * Learn how to change the layout and links of your Clerk components. --- title: Themes description: Clerk currently offers six prebuilt themes for you to customize the overall appearance of your Clerk app. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/appearance-prop/themes sourceFile: /docs/guides/customizing-clerk/appearance-prop/themes.mdx --- Clerk currently offers six prebuilt themes: * [The default theme](#default-theme) * [The "shadcn" theme](#shadcn-theme) * [The "Dark" theme](#dark-theme) * [The "Shades of Purple" theme](#shades-of-purple-theme) * [The "Neobrutalism" theme](#neobrutalism-theme) * [The "Simple" theme](#simple-theme) ## Default theme Applied by default when no other theme is provided.
![A sign-in form with a light theme](/docs/images/themes/default.png){{ style: { maxWidth: '400px', width: '100%' } }}
## "shadcn" theme > \[!IMPORTANT] > This theme is compatible with Tailwind CSS v4 usage. If you need support for Tailwind CSS v3, pass the shadcn variables manually to your ``'s [`variables`](/docs/guides/customizing-clerk/appearance-prop/variables) object. When using the [shadcn/ui](https://ui.shadcn.com/) library, you can use the `shadcn` theme to apply the shadcn/ui styles to your Clerk components. This will adapt to both light and dark mode automatically. > \[!IMPORTANT] > It's recommended to also import the `shadcn.css` file within your `global.css` file. Tailwind scans source files as plain text to detect which classes to generate - classes that only exist in external configurations won't be included in the final CSS. > > ```css > @import 'tailwindcss'; > @import '@clerk/themes/shadcn.css'; > ```
![A sign-in form with a shadcn theme in light mode](/docs/images/themes/shadcn_light_mode.png){{ style: { maxWidth: '400px', width: '100%' } }}
![A sign-in form with a shadcn theme in dark mode](/docs/images/themes/shadcn_dark_mode.png){{ style: { maxWidth: '400px', width: '100%' } }}
## "Dark" theme
![A sign-in form with a dark theme](/docs/images/themes/dark.png){{ style: { maxWidth: '400px', width: '100%' } }}
## "Shades of purple" theme
![A sign-in form with a purple and yellow theme](/docs/images/themes/shades_of_purple.png){{ style: { maxWidth: '400px', width: '100%' } }}
## "Neobrutalism" theme
![A sign-in form with a neobrutalist red theme](/docs/images/themes/neobrutalism.png){{ style: { maxWidth: '400px', width: '100%' } }}
## "Simple" theme This theme is a stripped down "Default" theme that removes some more advanced styling techniques, making it easier to apply your own custom styles. To use the simple theme, set `theme` to `simple`: ```tsx {{ mark: ['simple'] }} ```
![A sign-in form with a simple theme](/docs/images/themes/simple.png){{ style: { maxWidth: '400px', width: '100%' } }}
## Usage 1. To get started, install the `@clerk/themes` package. ```npm npm install @clerk/themes ``` 2. To use a theme, import it from `@clerk/themes` and pass it to the `appearance` prop of a Clerk component. ### Apply a theme to all Clerk components To apply a theme to all Clerk components, pass the `appearance` prop to the \ component. The `appearance` prop accepts the property `theme`, which can be set to a theme. In the following example, the "Dark" theme is applied to all Clerk components. ```tsx {{ filename: '/src/app/layout.tsx', mark: [2, [7, 9]] }} import { ClerkProvider } from '@clerk/nextjs' import { dark } from '@clerk/themes' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ```tsx {{ filename: '_app.tsx', mark: [2, 8, 9, 10] }} import { ClerkProvider } from '@clerk/nextjs' import { dark } from '@clerk/themes' import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return ( ) } export default MyApp ``` ```tsx {{ filename: 'app.tsx', mark: [3, [14, 16]] }} import React from 'react' import './App.css' import { dark } from '@clerk/themes' import { ClerkProvider } from '@clerk/clerk-react' if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) { throw new Error('Missing Publishable Key') } const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY function App() { return (
Hello from clerk
) } export default App ```
```js {{ filename: 'astro.config.mjs', mark: [2, [7, 9]] }} import clerk from '@clerk/astro' import { dark } from '@clerk/themes' export default defineConfig({ integrations: [ clerk({ appearance: { theme: dark, }, }), ], }) ``` ```tsx {{ filename: 'app/root.tsx', mark: [3, [36, 38]] }} // Import ClerkApp import { ClerkApp } from '@clerk/remix' import { dark } from '@clerk/themes' import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' export const meta: MetaFunction = () => ({ charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }) export const loader: LoaderFunction = (args) => rootAuthLoader(args) function App() { return ( ) } export default ClerkApp(App, { appearance: { theme: dark, }, }) ``` ```ts {{ filename: 'src/main.ts', mark: [4, [8, 10]] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' import { dark } from '@clerk/themes' const app = createApp(App) app.use(clerkPlugin, { appearance: { theme: dark, }, }) app.mount('#app') ``` ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 8]] }} import { dark } from '@clerk/themes' export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { appearance: { theme: dark, }, }, }) ```
### Apply multiple themes You can also stack themes by passing an array of themes to the `theme` property of the `appearance` prop. The themes will be applied in the order they are listed. If styles overlap, the last defined theme will take precedence. In the following example, the "Dark" theme is applied first, then the "Neobrutalism" theme is applied on top of it. ```tsx {{ filename: '/src/app/layout.tsx', mark: [2, [7, 9]] }} import { ClerkProvider } from '@clerk/nextjs' import { dark, neobrutalism } from '@clerk/themes' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ```tsx {{ filename: '_app.tsx', mark: [2, [8, 10]] }} import { ClerkProvider, SignIn } from '@clerk/nextjs' import { dark, neobrutalism } from '@clerk/themes' import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return ( ) } export default MyApp ``` ```tsx {{ filename: 'app.tsx', mark: [3, [14, 16]] }} import React from 'react' import './App.css' import { dark, neobrutalism } from '@clerk/themes' import { ClerkProvider } from '@clerk/clerk-react' if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) { throw new Error('Missing Publishable Key') } const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY function App() { return (
Hello from clerk
) } export default App ```
```js {{ filename: 'astro.config.mjs', mark: [2, [7, 9]] }} import clerk from '@clerk/astro' import { dark, neobrutalism } from '@clerk/themes' export default defineConfig({ integrations: [ clerk({ appearance: { theme: [dark, neobrutalism], }, }), ], }) ``` ```tsx {{ filename: 'app/root.tsx', mark: [3, [36, 38]] }} // Import ClerkApp import { ClerkApp } from '@clerk/remix' import { dark, neobrutalism } from '@clerk/themes' import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' export const meta: MetaFunction = () => ({ charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }) export const loader: LoaderFunction = (args) => rootAuthLoader(args) function App() { return ( ) } export default ClerkApp(App, { appearance: { theme: [dark, neobrutalism], }, }) ``` ```ts {{ filename: 'src/main.ts', mark: [4, [8, 10]] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' import { dark, neobrutalism } from '@clerk/themes' const app = createApp(App) app.use(clerkPlugin, { appearance: { theme: [dark, neobrutalism], }, }) app.mount('#app') ``` ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 8]] }} import { dark, neobrutalism } from '@clerk/themes' export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { appearance: { theme: [dark, neobrutalism], }, }, }) ```
### Apply a theme to all instances of a Clerk component You can apply a theme to all instances of a Clerk component by passing the component to the `appearance` prop of the ``. The `appearance` prop accepts the name of the Clerk component you want to style as a key. In the following example, the "Neobrutalism" theme is applied to all instances of the \ component. ```tsx {{ filename: '/src/app/layout.tsx', mark: [2, [7, 10]] }} import { ClerkProvider } from '@clerk/nextjs' import { dark, neobrutalism } from '@clerk/themes' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ```tsx {{ filename: '_app.tsx', mark: [2, [8, 11]] }} import { ClerkProvider, SignIn } from '@clerk/nextjs' import { dark } from '@clerk/themes' import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return ( ) } export default MyApp ``` ```tsx {{ filename: 'app.tsx', mark: [3, [14, 17]] }} import React from 'react' import './App.css' import { dark } from '@clerk/themes' import { ClerkProvider } from '@clerk/clerk-react' if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) { throw new Error('Missing Publishable Key') } const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY function App() { return (
Hello from clerk
) } export default App ```
```js {{ filename: 'astro.config.mjs', mark: [2, [7, 10]] }} import clerk from '@clerk/astro' import { dark } from '@clerk/themes' export default defineConfig({ integrations: [ clerk({ appearance: { theme: dark, signIn: { theme: neobrutalism }, }, }), ], }) ``` ```tsx {{ filename: 'app/root.tsx', mark: [3, [36, 39]] }} // Import ClerkApp import { ClerkApp } from '@clerk/remix' import { dark } from '@clerk/themes' import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' export const meta: MetaFunction = () => ({ charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }) export const loader: LoaderFunction = (args) => rootAuthLoader(args) function App() { return ( ) } export default ClerkApp(App, { appearance: { theme: dark, signIn: { theme: neobrutalism }, }, }) ``` ```ts {{ filename: 'src/main.ts', mark: [4, [8, 11]] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' import { dark, neobrutalism } from '@clerk/themes' const app = createApp(App) app.use(clerkPlugin, { appearance: { theme: dark, signIn: { theme: neobrutalism }, }, }) app.mount('#app') ``` ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 9]] }} import { dark, neobrutalism } from '@clerk/themes' export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { appearance: { theme: dark, signIn: { theme: neobrutalism }, }, }, }) ```
### Apply a theme to a single Clerk component To apply a theme to a single Clerk component, pass the `appearance` prop to the component. The `appearance` prop accepts the property `theme`, which can be set to a theme. ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx', mark: [2, [7, 9]] }} import { SignIn } from '@clerk/nextjs' import { dark } from '@clerk/themes' export default function Page() { return ( ) } ``` ```tsx {{ filename: '/pages/sign-in/[[...index]].tsx', mark: [2, [6, 8]] }} import { SignIn } from '@clerk/nextjs' import { dark } from '@clerk/themes' const SignInPage = () => ( ) export default SignInPage ``` ```tsx {{ filename: '/src/sign-in/[[...index]].tsx', mark: [2, [6, 8]] }} import { SignIn } from '@clerk/clerk-react' import { dark } from '@clerk/themes' const SignInPage = () => ( ) export default SignInPage ``` ```astro {{ filename: 'pages/sign-in.astro', mark: [3, [9, 11]] }} --- import { SignIn } from '@clerk/astro/components' import { dark } from '@clerk/themes' --- ``` ```tsx {{ filename: 'app/routes/sign-in/$.tsx', mark: [2, [9, 11]] }} import { SignIn } from '@clerk/remix' import { dark } from '@clerk/themes' export default function SignInPage() { return (

Sign In route

) } ```
```vue {{ filename: 'src/pages/sign-in.vue' }} ``` ```vue {{ filename: 'pages/sign-in.vue' }} ```
## Customize a theme using variables You can customize a theme by passing an object of variables to the `variables` property of the `appearance` prop. The `variables` property is used to adjust the general styles of the component's base theme, like colors, backgrounds, typography. In the following example, the primary color of the themes are customized. > \[!IMPORTANT] > For a list of all of the variables you can customize, and for more examples on how to use the `variables` property, see the [Variables](/docs/guides/customizing-clerk/appearance-prop/variables) docs. ```tsx {{ filename: '/src/app/layout.tsx', mark: [2, [7, 14]] }} import { ClerkProvider } from '@clerk/nextjs' import { dark, neobrutalism, shadesOfPurple } from '@clerk/themes' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ```tsx {{ filename: '_app.tsx', mark: [2, [8, 15]] }} import { ClerkProvider } from '@clerk/nextjs' import { dark, neobrutalism, shadesOfPurple } from '@clerk/themes' import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return ( ) } export default MyApp ``` ```tsx {{ filename: 'app.tsx', mark: [3, [14, 21]] }} import React from 'react' import './App.css' import { dark, neobrutalism, shadesOfPurple } from '@clerk/themes' import { ClerkProvider } from '@clerk/clerk-react' if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) { throw new Error('Missing Publishable Key') } const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY function App() { return (
Hello from clerk
) } export default App ```
```js {{ filename: 'astro.config.mjs', mark: [2, [7, 14]] }} import clerk from '@clerk/astro' import { dark, neobrutalism, shadesOfPurple } from '@clerk/themes' export default defineConfig({ integrations: [ clerk({ appearance: { theme: [dark, neobrutalism], variables: { colorPrimary: 'blue' }, signIn: { theme: [shadesOfPurple], variables: { colorPrimary: 'blue' }, }, }, }), ], }) ``` ```tsx {{ filename: 'app/root.tsx', mark: [3, [36, 43]] }} // Import ClerkApp import { ClerkApp } from '@clerk/remix' import { dark, neobrutalism, shadesOfPurple } from '@clerk/themes' import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' export const meta: MetaFunction = () => ({ charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }) export const loader: LoaderFunction = (args) => rootAuthLoader(args) function App() { return ( ) } export default ClerkApp(App, { appearance: { theme: [dark, neobrutalism], variables: { colorPrimary: 'blue' }, signIn: { theme: [shadesOfPurple], variables: { colorPrimary: 'blue' }, }, }, }) ``` ```ts {{ filename: 'src/main.ts', mark: [4, [8, 15]] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' import { dark, neobrutalism, shadesOfPurple } from '@clerk/themes' const app = createApp(App) app.use(clerkPlugin, { appearance: { theme: [dark, neobrutalism], variables: { colorPrimary: 'blue' }, signIn: { theme: [shadesOfPurple], variables: { colorPrimary: 'blue' }, }, }, }) app.mount('#app') ``` ```ts {{ filename: 'nuxt.config.ts', mark: [1, [6, 13]] }} import { dark, neobrutalism, shadesOfPurple } from '@clerk/themes' export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { appearance: { theme: [dark, neobrutalism], variables: { colorPrimary: 'blue' }, signIn: { theme: [shadesOfPurple], variables: { colorPrimary: 'blue' }, }, }, }, }) ```
--- title: "`Variables` prop" description: Utilize Clerk's variables property in order to adjust the general styles of the component's base theme, like colors, backgrounds, typography. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/appearance-prop/variables sourceFile: /docs/guides/customizing-clerk/appearance-prop/variables.mdx --- {/* JS file: https://github.com/clerk/javascript/blob/main/packages/types/src/appearance.ts#L399 */} The `variables` property is used to adjust the general styles of the component's base theme, like colors, backgrounds, and typography. ## Properties * `colorPrimary` * `string` The primary color used throughout the components. CSS variable: `--clerk-color-primary` *** * `colorDanger` * `string` The color used for error states. CSS variable: `--clerk-color-danger` *** * `colorSuccess` * `string` The color used for success states. CSS variable: `--clerk-color-success` *** * `colorWarning` * `string` The color used for warning states. CSS variable: `--clerk-color-warning` *** * `colorNeutral` * `string` The color that will be used for all to generate the neutral shades the components use. This option applies to borders, backgrounds for hovered elements, hovered dropdown options. CSS variable: `--clerk-color-neutral` *** * `colorForeground` * `string` The color used for text. CSS variable: `--clerk-color-foreground` *** * `colorPrimaryForeground` * `string` The color used for text on the primary background. CSS variable: `--clerk-color-primary-foreground` *** * `colorMutedForeground` * `string` The color used for secondary text. CSS variable: `--clerk-color-muted-foreground` *** * `colorMuted` * `string` The color used for muted backgrounds. CSS variable: `--clerk-color-muted` *** * `colorBackground` * `string` The background color for the card container. CSS variable: `--clerk-color-background` *** * `colorInputForeground` * `string` The color used for text in input fields. CSS variable: `--clerk-color-input-foreground` *** * `colorInput` * `string` The background color used for input fields. CSS variable: `--clerk-color-input` *** * `colorShimmer` * `string` The color of the avatar shimmer. CSS variable: `--clerk-color-shimmer` *** * `colorRing` * `string` The color of the ring when an interactive element is focused. CSS variable: `--clerk-color-ring` *** * `colorShadow` * `string` The base shadow color used in the components. CSS variable: `--clerk-color-shadow` *** * `colorBorder` * `string` The base border color used in the components. CSS variable: `--clerk-color-border` *** * `colorModalBackdrop` * `string` The background color of the modal backdrop. CSS variable: `--clerk-color-modal-backdrop` *** * `fontFamily` * `string` The font family used throughout the components. By default, it is set to `inherit`. CSS variable: `--clerk-font-family` *** * `fontFamilyButtons` * `string` The font family used for buttons. By default, it is set to `inherit`. CSS variable: `--clerk-font-family-buttons` *** * `fontSize` * `string` | `{xs: string, sm: string, md: string, lg: string, xl: string}` The font size used throughout the components. By default, this is set to `0.8125rem`. CSS variable: `--clerk-font-size` *** * `fontWeight` * `{normal: number, medium: number, semibold: number, bold: number}` The font weight used throughout the components. By default, this is set to `{normal: 400, medium: 500, semibold: 600, bold: 700}`. CSS variable: `--clerk-font-weight` *** * `borderRadius` * `string` The border radius used throughout the components. By default, this is set to `0.375rem`. CSS variable: `--clerk-border-radius` *** * `spacing` * `string` The spacing unit used throughout the components. By default, this is set to `1rem`. CSS variable: `--clerk-spacing` ### Deprecated properties {{ toc: false }} The following properties are deprecated as of 2025-07-15 and will be removed in the next major version of Clerk. * `colorText` (use `colorForeground` instead) * `colorTextOnPrimaryBackground` (use `colorPrimaryForeground` instead) * `colorTextSecondary` (use `colorMutedForeground` instead) * `spacingUnit` (use `spacing` instead) * `colorInputText` (use `colorInputForeground` instead) * `colorInputBackground` (use `colorInput` instead) ## Usage You can customize Clerk components by passing an object of variables to the `variables` property of the [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) prop. > \[!NOTE browser-compatibility-considerations] > **Browser Compatibility Considerations** > > Clerk's theming system uses modern CSS features like [`color-mix()`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix) and [relative color syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_colors/Relative_colors) to automatically generate color variations from your base colors. These features require: > > * **`color-mix()`**: Chrome 111+, Firefox 113+, Safari 16.2+ > * **Relative color syntax**: Chrome 119+, Firefox 120+, Safari 16.4+ > > For broader browser support, when using the `variables` prop, **use direct color values** (e.g. `colorPrimary: '#6c47ff'`) instead of CSS variables or modern color functions. ### Apply `variables` to all Clerk components To customize all Clerk components, pass the `variables` property to the `appearance` prop of the \ component. In the following example, the primary color is set to blue and the text color is set to black. Because these styles are applied to the ``, which wraps the entire application, these styles will be applied to all Clerk components that use the primary color and text color. ```tsx {{ filename: '/src/app/layout.tsx', mark: [[6, 11]] }} import { ClerkProvider } from '@clerk/nextjs' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ```tsx {{ filename: '_app.tsx', mark: [[7, 12]] }} import { ClerkProvider } from '@clerk/nextjs' import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return ( ) } export default MyApp ``` ```tsx {{ filename: 'app.tsx', mark: [[13, 18]] }} import React from 'react' import './App.css' import { ClerkProvider } from '@clerk/clerk-react' if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) { throw new Error('Missing Publishable Key') } const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY function App() { return (
Hello from clerk
) } export default App ```
```tsx {{ filename: 'app/root.tsx', mark: [[35, 40]] }} // Import ClerkApp import { ClerkApp } from '@clerk/remix' import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' export const meta: MetaFunction = () => ({ charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }) export const loader: LoaderFunction = (args) => rootAuthLoader(args) function App() { return ( ) } export default ClerkApp(App, { appearance: { variables: { colorPrimary: '#0000ff', // blue colorForeground: '#000000', // black }, }, }) ``` ```js {{ filename: 'astro.config.mjs', mark: [[6, 11]] }} import clerk from '@clerk/astro' export default defineConfig({ integrations: [ clerk({ appearance: { variables: { colorPrimary: '#0000ff', // blue colorForeground: '#000000', // black }, }, }), ], }) ``` ```ts {{ filename: 'src/main.ts', mark: [[7, 12]] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const app = createApp(App) app.use(clerkPlugin, { appearance: { variables: { colorPrimary: '#0000ff', // blue colorForeground: '#000000', // black }, }, }) app.mount('#app') ``` ```ts {{ filename: 'nuxt.config.ts', mark: [[4, 9]] }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { appearance: { variables: { colorPrimary: '#0000ff', // blue colorForeground: '#000000', // black }, }, }, }) ```
### Apply `variables` to all instances of a Clerk component You can customize all instances of a Clerk component by passing the component to the `appearance` prop of the ``. The `appearance` prop accepts the name of the Clerk component you want to style as a key. In the following example, the primary color is set to blue and the text color is set to black for all instances of the \ component. ```tsx {{ filename: '/src/app/layout.tsx', mark: [[6, 13]] }} import { ClerkProvider } from '@clerk/nextjs' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ```tsx {{ filename: '_app.tsx', mark: [[7, 14]] }} import { ClerkProvider } from '@clerk/nextjs' import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return ( ) } export default MyApp ``` ```tsx {{ filename: 'app.tsx', mark: [[13, 20]] }} import React from 'react' import './App.css' import { ClerkProvider } from '@clerk/clerk-react' if (!process.env.REACT_APP_CLERK_PUBLISHABLE_KEY) { throw new Error('Missing Publishable Key') } const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY function App() { return (
Hello from clerk
) } export default App ```
```tsx {{ filename: 'app/root.tsx', mark: [[35, 42]] }} // Import ClerkApp import { ClerkApp } from '@clerk/remix' import type { MetaFunction, LoaderFunction } from '@remix-run/node' import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react' import { rootAuthLoader } from '@clerk/remix/ssr.server' export const meta: MetaFunction = () => ({ charset: 'utf-8', title: 'New Remix App', viewport: 'width=device-width,initial-scale=1', }) export const loader: LoaderFunction = (args) => rootAuthLoader(args) function App() { return ( ) } export default ClerkApp(App, { appearance: { signIn: { variables: { colorPrimary: '#0000ff', // blue colorForeground: '#000000', // black }, }, }, }) ``` ```js {{ filename: 'astro.config.mjs', mark: [[6, 13]] }} import clerk from '@clerk/astro' export default defineConfig({ integrations: [ clerk({ appearance: { signIn: { variables: { colorPrimary: '#0000ff', // blue colorForeground: '#000000', // black }, }, }, }), ], }) ``` ```ts {{ filename: 'src/main.ts', mark: [[7, 14]] }} import { createApp } from 'vue' import App from './App.vue' import { clerkPlugin } from '@clerk/vue' const app = createApp(App) app.use(clerkPlugin, { appearance: { signIn: { variables: { colorPrimary: '#0000ff', // blue colorForeground: '#000000', // black }, }, }, }) app.mount('#app') ``` ```ts {{ filename: 'nuxt.config.ts', mark: [[4, 11]] }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { appearance: { signIn: { variables: { colorPrimary: '#0000ff', // blue colorForeground: '#000000', // black }, }, }, }, }) ```
### Apply `variables` to a single Clerk component To customize a single Clerk component, pass the `variables` property to the `appearance` prop of the Clerk component. The following example shows how to customize the \ component by setting the primary color to blue and the text color to black. ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx', mark: [[6, 11]] }} import { SignIn } from '@clerk/nextjs' export default function Page() { return ( ) } ``` ```tsx {{ filename: '/pages/sign-in/[[...index]].tsx', mark: [[5, 10]] }} import { SignIn } from '@clerk/nextjs' const SignInPage = () => ( ) export default SignInPage ``` ```tsx {{ filename: '/src/sign-in/[[...index]].tsx', mark: [[5, 10]] }} import { SignIn } from '@clerk/clerk-react' const SignInPage = () => ( ) export default SignInPage ``` ```tsx {{ filename: 'app/routes/sign-in/$.tsx', mark: [[8, 13]] }} import { SignIn } from '@clerk/remix' export default function SignInPage() { return (

Sign In route

) } ```
```astro {{ filename: 'pages/sign-in.astro', mark: [[7, 10]] }} --- import { SignIn } from '@clerk/astro/components' --- ``` ```vue {{ filename: 'src/pages/sign-in.vue', mark: [6] }} ``` ```vue {{ filename: 'pages/sign-in.vue', mark: [6] }} ```
### Using CSS variables > \[!WARNING] > Please consider this approach with browser compatibility in mind, as it may not work in older browsers. See [Browser Compatibility Considerations](#browser-compatibility-considerations) for details. You can also use CSS variables to customize the appearance of Clerk components. This approach is particularly useful when: * You have a pre-defined design system with CSS custom properties * You want to support automatic dark/light mode switching * You need to dynamically update colors based on user preferences * You're integrating Clerk into an existing application with established CSS variables The following example demonstrates how to use CSS variables to customize the appearance of Clerk components, but for maximum browser compatibility, it's recommended to use direct color values instead. ```css {{ filename: '/src/app/global.css' }} :root { --brand-primary: oklch(49.1% 0.27 292.581); } @media (prefers-color-scheme: dark) { :root { --brand-primary: oklch(54.1% 0.281 293.009); } } ``` ```tsx {{ filename: '/src/app/layout.tsx', mark: [9] }} import { ClerkProvider } from '@clerk/nextjs' import './global.css' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ### Clerk CSS variables Clerk exposes native CSS variables if you would prefer to define variables directly in your application's stylesheet. All variables exposed through the `appearance` object are also exposed as CSS variables; see the [properties](#properties) section for a list of the available variables. The Clerk CSS variables are prefixed with `clerk-` and are in kebab-case: ```css :root { --clerk-color-primary: #0000ff; /* colorPrimary */ --clerk-color-foreground: #000000; /* colorForeground */ } ``` --- title: Add custom pages and links to the `` component description: Learn how to add custom pages and include external links within the navigation sidenav of the component. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/adding-items/organization-profile sourceFile: /docs/guides/customizing-clerk/adding-items/organization-profile.mdx --- The \ component supports the addition of custom pages and external links to the component's sidenav. ## Before you start To access the `` component, the user must select the \ component and then select the **Manage Organization** option. The `` will open as a modal by default. You can also render the component as a dedicated page. This guide includes examples for both use cases. On the code examples, you can select one of the following two tabs to see the implementation for your preferred use case: * `` tab: By default, the `` sets `organizationProfileMode='modal'`. If you are using the default settings, then you should select this tab. * `Dedicated page` tab: If you do not want the `` to open as a modal, then you should select this tab. For these examples, you need to set `organizationProfileMode='navigation'` and `organizationProfileUrl='/organization-profile'` on the `` component. ## Add a custom page To add a custom page to the `` component, use the `` component or the `` component, depending on your use case. ### Props `` and `` accept the following props, all of which are **required**: * `label` * `string` The name that will be displayed in the navigation sidenav for the custom page. *** * `labelIcon` * `React.ReactElement` An icon displayed next to the label in the navigation sidenav. *** * `url` * `string` The path segment that will be used to navigate to the custom page. For example, if the `` component is rendered at `/organization`, then the custom page will be accessed at `/organization/{url}` when using [path routing](/docs/guides/how-clerk-works/routing). *** * `children` * `React.ReactElement` The content to be rendered inside the custom page. ### Example The following example demonstrates two ways that you can render content in a custom page: as a component or as a direct child. ", "Dedicated page"]}> ```tsx {{ filename: 'app/components/Header.tsx' }} 'use client' import { OrganizationSwitcher } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const CustomPage = () => { return (

Custom page

This is the content of the custom page.

) } const Header = () => (
{/* You can pass the content as a component */} } > {/* You can also pass the content as direct children */} } url="terms" >

Custom Terms Page

This is the content of the custom terms page.

) export default Header ``` ```tsx {{ filename: 'app/organization-profile/[[...organization-profile]]/page.tsx' }} 'use client' import { OrganizationProfile } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const CustomPage = () => { return (

Custom page

This is the content of the custom page.

) } const OrganizationProfilePage = () => ( {/* You can pass the content as a component */} } url="custom-page"> {/* You can also pass the content as direct children */} } url="terms">

Custom Terms Page

This is the content of the custom terms page.

) export default OrganizationProfilePage ```
To add custom pages to the `` component using the JavaScript SDK, pass the `customPages` property to the `mountOrganizationProfile()` or `openOrganizationProfile()` method, as shown in the following example: ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const orgProfileDiv = document.getElementById('organization-profile') clerk.openOrganizationProfile(orgProfileDiv, { customPages: [ { url: 'custom-page', label: 'Custom Page', mountIcon: (el) => { el.innerHTML = '👋' }, unmountIcon: (el) => { el.innerHTML = '' }, mount: (el) => { el.innerHTML = `

Custom Page

This is the content of the custom page.

` }, unmount: (el) => { el.innerHTML = '' }, }, { url: '/other-page', label: 'Other Page', mountIcon: (el) => { el.innerHTML = '🌐' }, unmountIcon: (el) => { el.innerHTML = '' }, }, ], }) ```
", "Dedicated page"]}> ```vue {{ filename: 'App.vue' }} ``` ```vue {{ filename: 'pages/organization-profile.vue' }} ```
## Add a custom link To add an external link to the `` navigation sidenav, use the `` component or the `` component, depending on your use case. ### Props `` and `` accept the following props, all of which are **required**: * `label` * `string` The name that will be displayed in the navigation sidenav for the link. *** * `labelIcon` * `React.ReactElement` An icon displayed next to the label in the navigation sidenav. *** * `url` * `string` The full URL or path that will be used to navigate to the external link. For path segments, if the `` component is rendered at `/organization`, then the external link will be accessed at `/organization/{url}` when using [path routing](/docs/guides/how-clerk-works/routing). ### Example The following example adds a custom link to the `` sidenav that navigates to the homepage. ", "Dedicated page"]}> ```tsx {{ filename: 'app/components/Header.tsx' }} 'use client' import { OrganizationSwitcher } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const Header = () => (
} />
) export default Header ``` ```tsx {{ filename: 'app/organization-profile/[[...organization-profile]]/page.tsx' }} 'use client' import { OrganizationProfile } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const OrganizationProfilePage = () => ( } url="/" /> ) export default OrganizationProfilePage ```
", "Dedicated page"]}> ```vue {{ filename: 'App.vue' }} ``` ```vue {{ filename: 'pages/organization-profile.vue' }} ```
## Reordering default routes The `` component includes two default menu items: `Members` and `General`, in that order. You can reorder these default items by setting the `label` prop to `'members'` or `'general'`. This will target the existing default item and allow you to rearrange it. Note that when reordering default routes, the first item in the navigation sidenav cannot be a custom link. The following example adds a custom page as the first item in the sidenav, followed by a custom link to the homepage, and then the default members and general pages. ", "Dedicated Page"]}> ```tsx {{ filename: 'app/components/Header.tsx' }} 'use client' import { OrganizationSwitcher } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const CustomPage = () => { return (

Custom page

This is the content of the custom page.

) } const Header = () => (
} > } />
) export default Header ``` ```tsx {{ filename: 'app/organization-profile/[[...organization-profile]]/page.tsx' }} 'use client' import { OrganizationProfile } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const CustomPage = () => { return (

Custom page

This is the content of the custom page.

) } const OrganizationProfilePage = () => ( }> } /> ) export default OrganizationProfilePage ```
", "Dedicated page"]}> ```vue {{ filename: 'App.vue' }} ``` ```vue {{ filename: 'pages/organization-profile.vue' }} ```
--- title: Add custom items and links to the `` component description: Learn how to add custom items and include external links within the menu. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/adding-items/user-button sourceFile: /docs/guides/customizing-clerk/adding-items/user-button.mdx --- The \ component supports *custom* menu items, allowing the incorporation of app-specific settings or additional functionality. There are two types of custom menu items available: * [``](#user-button-action) - A menu item that triggers an action when clicked. * [``](#user-button-link) - A menu item that navigates to a page when clicked. You can also [reorder default items](#reorder-default-items) and [conditionally render menu items](#conditionally-render-menu-items). ## `` `` allows you to add actions to the `` component, like opening a chat or triggering a modal. ### Props `` accepts the following props: * `label` * `string` The name that will be displayed in the menu of the user button. *** * `labelIcon` * `React.ReactElement` An icon displayed next to the label in the menu. *** * `open?` * `string` The path segment that will be used to open the user profile modal to a specific page. *** * `onClick?` * `void` A function to be called when the menu item is clicked. ### Examples #### Add an action The following example adds an "Open chat" action to the `` component. When a user selects the ``, there will be an "Open chat" menu item. ```tsx {{ filename: '/app/page.tsx' }} 'use client' import { UserButton } from '@clerk/nextjs' const DotIcon = () => { return ( ) } export default function Home() { return (
} onClick={() => alert('init chat')} />
) } ```
In Astro components, props are converted to strings, so you can't use an `onClick` handler to handle click events. Instead, you can set an arbitrary prop, set up a custom event listener that will check for the value passed to that prop, and then execute a desired action based on that value. For example, `clickIdentifier` is the arbitrary prop being used to identify the click event. Two `` components are added to the menu, each with a different `clickIdentifier` prop. When the menu item is clicked, the custom event listener will check for the value passed to the `clickIdentifier` prop, either `"open_chat"` or `"open_cart"`, and then execute an action based on that value. ```astro {{ filename: 'pages/index.astro' }} --- import { UserButton } from '@clerk/astro/components' ---
```
To add custom menu items to the `` component using the JavaScript SDK, pass the `customMenuItems` property to the `mountUserButton()` method, as shown in the following example: ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerk = new Clerk('{{pub_key}}') await clerk.load() document.getElementById('app').innerHTML = `
` const userButtonDiv = document.getElementById('user-button') clerk.mountUserButton(userButtonDiv, { customMenuItems: [ { label: 'Help modal', onClick: () => { alert('Open modal') // your custom event }, mountIcon: (el) => { el.innerHTML = '👤' }, unmountIcon: (el) => {}, }, ], }) ```
```vue {{ filename: 'App.vue' }} ```
#### Add an action and a custom page The following example adds an "Open chat" action to the `` component, as well as a [custom page](/docs/guides/customizing-clerk/adding-items/user-profile) titled "Help". When a user selects the ``, there will be "Open chat" and "Help" menu items. ```tsx {{ filename: '/app/page.tsx' }} 'use client' import { UserButton } from '@clerk/nextjs' const DotIcon = () => { return ( ) } export default function Home() { return (
} open="help" /> } url="help">

Help Page

This is the custom help page

) } ```
In the following example, the `` component is used to add a "Help" menu item to the `` component. The `open` prop is set to `"help"` to open the `/help` page when the menu item is selected. The `` component is used to render the `/help` page, and because its configured as a user profile page, the `` modal will be opened with the custom "Help" menu item. [Read more about custom pages](/docs/guides/customizing-clerk/adding-items/user-profile). ```astro {{ filename: 'pages/index.astro' }} --- import { UserButton } from '@clerk/astro/components' ---

Help Page

This is the custom help page

```
```vue {{ filename: 'App.vue' }} ```
## `` `` allows you to add links to the `` component, like custom pages or external URLs. ### Props `` accept the following props, all of which are **required**: * `label` * `string` The name that will be displayed in the menu of the user button. *** * `labelIcon` * `React.ReactElement` An icon displayed next to the label in the menu. *** * `href` * `string` The path segment that will be used to navigate to the custom page. ### Example The following example adds a "Create organization" link to the `` component. When a user selects the ``, there will be a "Create organization" menu item. ```tsx {{ filename: '/app/page.tsx' }} 'use client' import { UserButton } from '@clerk/nextjs' const DotIcon = () => { return ( ) } export default function Home() { return (
} href="/create-organization" />
) } ```
```astro {{ filename: 'pages/index.astro' }} --- import { UserButton } from '@clerk/astro/components' ---
```
To add custom menu items to the `` component using the JavaScript SDK, pass the `customMenuItems` property to the `mountUserButton()` method, as shown in the following example: ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' // Initialize Clerk with your Clerk Publishable Key const clerk = new Clerk('{{pub_key}}') await clerk.load() document.getElementById('app').innerHTML = `
` const userButtonDiv = document.getElementById('user-button') clerk.mountUserButton(userButtonDiv, { customMenuItems: [ { label: 'User page', href: '/user', mountIcon: (el) => { el.innerHTML = '👤' }, unmountIcon: (el) => {}, }, ], }) ```
```vue {{ filename: 'App.vue' }} ```
## Reorder default items The `` component includes two default menu items: `Manage account` and `Sign out`, in that order. You can reorder these default items by setting the `label` prop to `'manageAccount'` or `'signOut'`. This will target the existing default item and allow you to rearrange it. In the following example, the "Sign out" menu item is moved to the top of the menu, a custom "Create organization" link is added as the second menu item, and the "Manage account" menu item is moved to the bottom of the menu. ```tsx {{ filename: '/app/page.tsx' }} 'use client' import { UserButton } from '@clerk/nextjs' const DotIcon = () => { return ( ) } export default function Home() { return (
} href="/create-organization" />
) } ```
```astro {{ filename: 'pages/index.astro' }} --- import { UserButton } from '@clerk/astro/components' ---
```
```vue {{ filename: 'App.vue' }} ```
## Conditionally render menu items To conditionally render menu items based on a user's Role or Custom Permissions, you can use the has() helper function. In the following example, the "Create organization" menu item will only render if the current user has the `org:app:admin` permission. ```tsx {{ filename: '/app/page.tsx' }} 'use client' import { UserButton, useAuth } from '@clerk/nextjs' const DotIcon = () => { return ( ) } export default function Home() { const { has, isLoaded } = useAuth() if (!isLoaded) { return Loading... } const isAdmin = has({ permission: 'org:app:admin' }) return (
{isAdmin && ( } href="/create-organization" /> )}
) } ```
```astro {{ filename: 'pages/index.astro' }} --- import { UserButton } from '@clerk/astro/components' const { has } = Astro.locals.auth() const isAdmin = has({ permission: 'org:app:admin' }) ---
{ isAdmin && ( ) }
```
```vue {{ filename: 'App.vue' }} ```
--- title: Add custom pages and links to the `` component description: Learn how to add custom pages and include external links within the navigation sidenav of the component. lastUpdated: 2025-11-21T23:40:13.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/adding-items/user-profile sourceFile: /docs/guides/customizing-clerk/adding-items/user-profile.mdx --- The \ component supports the addition of custom pages and external links to the component's sidenav. It only accepts the following components as children: * `` or `` to add a [custom page](#add-a-custom-page). * `` or `` to add a [custom link](#add-a-custom-link). ## Before you start To access the `` component, the user must select the \ component and then select the **Manage account** menu item. The `` will open as a modal by default. You can also render the component as a dedicated page. This guide includes examples for both use cases. On the code examples, you can select one of the following two tabs to see the implementation for your preferred use case: * `` tab: By default, the `` sets `userProfileMode='modal'`. If you are using the default settings, then you should select this tab. * `Dedicated page` tab: If you do not want the `` to open as a modal, then you should select this tab. For these examples, you need to set `userProfileMode='navigation'` and `userProfileUrl='/user-profile'` on the `` component. ## Add a custom page To add a custom page to the `` component, use the `` component or the `` component, depending on your use case. ### Props `` and `` accept the following props, all of which are **required**: * `label` * `string` The name that will be displayed in the navigation sidenav for the custom page. *** * `labelIcon` * `React.ReactElement` An icon displayed next to the label in the navigation sidenav. *** * `url` * `string` The path segment that will be used to navigate to the custom page. For example, if the `` component is rendered at `/user`, then the custom page will be accessed at `/user/{url}` when using [path routing](/docs/guides/how-clerk-works/routing). *** * `children` * `React.ReactElement` The content to be rendered inside the custom page. ### Example The following example demonstrates two ways that you can render content in a custom page: as a component or as a direct child. ", "Dedicated page"]}> ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { UserButton } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const CustomPage = () => { return (

Custom page

This is the content of the custom page.

) } export default function Home() { return (
{/* You can pass the content as a component */} }> {/* You can also pass the content as direct children */} } url="terms">

Custom Terms Page

This is the content of the custom terms page.

) } ``` ```tsx {{ filename: 'app/user-profile/[[...user-profile]]/page.tsx' }} 'use client' import { UserProfile } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const CustomPage = () => { return (

Custom page

This is the content of the custom page.

) } const UserProfilePage = () => ( {/* You can pass the content as a component */} } url="custom-page"> {/* You can also pass the content as direct children */} } url="terms">

Custom Terms Page

This is the content of the custom terms page.

) export default UserProfilePage ```
To add custom pages to the `` component using the JavaScript SDK, pass the `customPages` property to the `mountUserProfile()` method, as shown in the following example: ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() document.getElementById('app').innerHTML = `
` const userProfileDiv = document.getElementById('user-profile') clerk.mountUserProfile(userProfileDiv, { customPages: [ { url: 'custom-page', label: 'Custom Page', mountIcon: (el) => { el.innerHTML = '👋' }, unmountIcon: (el) => { el.innerHTML = '' }, mount: (el) => { el.innerHTML = `

Custom Page

This is the content of the custom page.

` }, unmount: (el) => { el.innerHTML = '' }, }, { url: '/other-page', label: 'Other Page', mountIcon: (el) => { el.innerHTML = '🌐' }, unmountIcon: (el) => { el.innerHTML = '' }, }, ], }) ```
", "Dedicated page"]}> ```astro {{ filename: 'pages/index.astro' }} --- import { UserButton } from '@clerk/astro/components' ---

Custom page

This is the content of the custom page.

``` ```astro {{ filename: 'pages/user-profile.astro' }} --- import { UserProfile } from '@clerk/astro/components' ---

Custom page

This is the content of the custom page.

```
", "Dedicated page"]}> ```vue {{ filename: 'App.vue' }} ``` ```vue {{ filename: 'pages/user-profile.vue' }} ```
## Add a custom link To add a custom link to the `` component, use the `` component or the `` component, depending on your use case. ### Props `` and `` accept the following props, all of which are **required**: * `label` * `string` The name that will be displayed in the navigation sidenav for the link. *** * `labelIcon` * `React.ReactElement` An icon displayed next to the label in the navigation sidenav. *** * `url` * `string` The path segment that will be used to navigate to the custom page. For example, if the `` component is rendered at `/user`, then the custom link will be navigate to `/user/{url}` when using [path routing](/docs/guides/how-clerk-works/routing). ### Example The following example adds a custom link to the `` sidenav that navigates to the homepage. ", "Dedicated page"]}> ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { UserButton } from '@clerk/nextjs' const DotIcon = () => { return ( ) } export default function Home() { return (
} />
) } ``` ```tsx {{ filename: 'app/user-profile/[[...user-profile]]/page.tsx' }} 'use client' import { UserProfile } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const UserProfilePage = () => ( } url="/" /> ) export default UserProfilePage ```
", "Dedicated page"]}> ```astro {{ filename: 'pages/index.astro' }} --- import { UserButton } from '@clerk/astro/components' ---
``` ```astro {{ filename: 'pages/user-profile.astro' }} --- import { UserProfile } from '@clerk/astro/components' --- ```
", "Dedicated page"]}> ```vue {{ filename: 'App.vue' }} ``` ```vue {{ filename: 'pages/user-profile.vue' }} ```
## Reorder default routes The `` component includes two default menu items: `Account` and `Security`, in that order. You can reorder these default items by setting the `label` prop to `'account'` or `'security'`. This will target the existing default item and allow you to rearrange it. Note that when reordering default routes, the first item in the navigation sidenav cannot be a custom link. The following example adds a custom page as the first item in the sidenav, followed by a custom link to the homepage, and then the default account and security pages. ", "Dedicated page"]}> ```tsx {{ filename: 'app/page.tsx' }} 'use client' import { UserButton } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const CustomPage = () => { return (

Custom page

This is the content of the custom page.

) } export default function Home() { return (
}> } />
) } ```
```tsx {{ filename: 'app/user-profile/[[...user-profile]]/page.tsx' }} 'use client' import { UserProfile } from '@clerk/nextjs' const DotIcon = () => { return ( ) } const CustomPage = () => { return (

Custom page

This is the content of the custom page.

) } const UserProfilePage = () => ( }> } /> ) export default UserProfilePage ```
", "Dedicated page"]}> ```astro {{ filename: 'pages/index.astro' }} --- import { UserButton } from '@clerk/astro/components' ---

Custom page

This is the content of the custom page.

```
```astro {{ filename: 'pages/user-profile.astro' }} --- import { UserProfile } from '@clerk/astro/components' ---

Custom page

This is the content of the custom page.

```
", "Dedicated page"]}> ```vue {{ filename: 'App.vue' }} ``` ```vue {{ filename: 'pages/user-profile.vue' }} ```
--- title: Clerk Elements (beta) description: Learn how to use Clerk Elements to build custom UIs on top of the Clerk APIs without having to manage the underlying logic. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/elements/overview sourceFile: /docs/guides/customizing-clerk/elements/overview.mdx --- > \[!WARNING] > Clerk Elements is currently in beta with support for Next.js App Router. It is **not yet recommended for production use**. > > If you have any feedback, contact [beta-elements@clerk.dev](mailto:beta-elements@clerk.dev) or head over to the [GitHub Discussion](https://github.com/orgs/clerk/discussions/3315). Clerk Elements is a library of unstyled, composable components that can be used to build custom UIs on top of the Clerk APIs without having to manage the underlying logic. ![Clerk Elements](/docs/images/elements/elements-hero-light.webp){{ dark: '/docs/images/elements/elements-hero-dark.webp' }} ## Why use Clerk Elements? You should use Clerk Elements if you want a deeper level of control and customization of the styles and layout of your UI while using the Clerk APIs. For example, if [the appearance prop](/docs/guides/customizing-clerk/appearance-prop/overview) does not meet your needs, Clerk Elements might be for you. That said, you can also use Clerk Elements alongside the prebuilt components. * **Component-first** - Make it as easy to build custom UIs with Clerk as it is with Clerk's drop-in prebuilt components. Clerk Elements handles the underlying business logic for you and provides a curated library of components without sacrificing on best practices or features. * **Unstyled, with a little bit of magic** - Use the web platform and best-in-class components for building great authentication flows. Baked-in to the components are little bits of magic, like the fully accessible segmented one-time-passcode (OTP) input, and instant password validation during sign up. ### Integrate Clerk Elements into your workflow Clerk Elements can be integrated into your existing application and workflows. For example, you may want to use Clerk Elements with: * **Tailwind CSS** – If you use Tailwind CSS, you can pass a `className` prop to most elements that Clerk Elements renders. See [the styling guide](/docs/guides/customizing-clerk/elements/guides/styling#tailwind-css) to learn more. * **Existing styles or component library** – If you have an existing component library that you want to use to build your authentication UIs, Clerk Elements supports composition via an `asChild` prop. Read [the styling guide](/docs/guides/customizing-clerk/elements/guides/styling#with-existing-components-via-as-child) to learn more. * **With prebuilt components** - Continue using prebuilt components while customizing the flows you care most about. ## Getting started Clerk Elements currently only works with Next.js App Router and [Clerk Core 2](/changelog/2024-04-19){{ target: '_blank' }}. As it gets closer to a stable release, support for additional frameworks will be added. If your Next.js application is already using Clerk, make sure to [upgrade to Core 2](/docs/guides/development/upgrading/upgrade-guides/core-2/nextjs). If you're starting from scratch, follow the Next.js quickstart before proceeding. To get started, install the Clerk Elements package: ```npm npm install @clerk/elements ``` > \[!IMPORTANT] > If your project uses TypeScript, make sure that your [`moduleResolution`](https://www.typescriptlang.org/tsconfig/#moduleResolution) in `tsconfig.json` is set to `bundler`. Otherwise, you might run into issues with resolving TypeScript types from Clerk Elements. Once you have your project set up, you can start building custom UIs with Clerk Elements using Clerk's guides and examples. For example, to use Clerk Elements to build a custom sign-in flow, you can explore: * [Build a sign-in flow](/docs/guides/customizing-clerk/elements/guides/sign-in) * [Sign-in examples](/docs/guides/customizing-clerk/elements/examples/sign-in) * [Sign-in components](/docs/guides/customizing-clerk/elements/reference/sign-in) > \[!NOTE] > With the beta release, only sign-up and sign-in flows are supported. Support for building the rest of the prebuilt components with Elements is actively being worked on. --- title: Common components description: Reference documentation for common Clerk Elements components. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/customizing-clerk/elements/reference/common sourceFile: /docs/guides/customizing-clerk/elements/reference/common.mdx --- Clerk Elements provides a set of common components that are used across all flows. It's recommended to import them all under the `Clerk` namespace to make discovery easier and reduce naming conflicts with other common components throughout your application. The code snippets on this page assume you have imported the components this way. ```tsx {{ filename: 'Anatomy' }} import * as Clerk from '@clerk/elements/common' ``` Unless otherwise mentioned, all components accept a `className` prop. ## `` Renders a social connection button based on the provided `name`. Throws an error in development if the provided social connection is not enabled in your instance. See [Social connections (OAuth)](/docs/guides/configure/auth-strategies/social-connections/overview) to learn how to enable them in the Clerk Dashboard. By default, `` will be rendered as an unstyled ` Email Code ) } ``` Notice how the Clerk Elements components are wrapping the rendered `` and `

or

Continue registration
Verify your email Use the verification link sent to your email address
Email address
{ return (
{value} {status === 'cursor' && (
)}
) }} />
( )} >
)}
) } ``` ## Sign in ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx', collapsible: true }} 'use client' import * as Clerk from '@clerk/elements/common' import * as SignIn from '@clerk/elements/sign-in' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Icons } from '@/components/ui/icons' export default function SignInPage() { return (
{(isGlobalLoading) => ( <> Sign in to Acme Co Welcome back! Please sign in to continue

or

Use another method Facing issues? You can use any of these methods to sign in.
Enter your password

Welcome back

Check your email Enter the verification code sent to your email

Welcome back

Email verification code
{ return (
{value}
) }} />
( )} >
)}
) } ``` ## OTP input The following example demonstrates how to make a one-time password (OTP) input with Clerk Elements. This example will only work if placed within a `Step` in a sign-up or sign-in authentication flow, as shown in [the sign-in](#sign-in) and [sign-up](#sign-up) examples. ```tsx {{ title: 'OTP Input', collapsible: true }} { return (
{value} {status === 'cursor' && (
)}
) }} /> ``` --- title: Bot protection description: Protect your sign-ups from bots. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/bot-protection sourceFile: /docs/guides/secure/bot-protection.mdx --- To protect your sign-ups from bots, Clerk leverages data from our CDN to determine whether a user attempting to sign up might be a bot or not. ## Enable bot sign-up protection 1. In the Clerk Dashboard, navigate to the [**Attack protection**](https://dashboard.clerk.com/~/user-authentication/attack-protection) page. 2. Enable the **Bot sign-up protection** toggle. * When enabled, users suspected of being a bot will be shown an interactive challenge (like clicking a checkbox) to verify they are human. The CAPTCHA widget will only be shown if the client is suspected to be a bot. > \[!WARNING] > If you currently have the **Invisible** CAPTCHA type selected, it's highly recommended to switch to the **Smart** option, as the **Invisible** option is deprecated and will be removed in a future update. ## Limitations * Clerk uses [Cloudflare](https://developers.cloudflare.com/waf/reference/cloudflare-challenges/#mobile-device-emulation) for bot detection, which isn't supported in non-browser environments (e.g. Expo, Chrome Extension). If you're using any of these SDKs, disable bot protection from the Clerk Dashboard. * If you're building a custom sign-up flow using the Clerk API instead of using Clerk components, and you have enabled **Bot sign-up protection**, then you need to ensure you have added a DOM node to render the CAPTCHA widget. Refer to the [Add bot protection to your custom sign-up flow](/docs/guides/development/custom-flows/authentication/bot-sign-up-protection) guide for more information. --- title: Authorize users description: Learn how to verify and validate user Roles and Permissions within Clerk to maintain secure access control. We provide a collection of utility functions and components that allow developers to perform authorization checks. metadata: title: Verifying user permissions with Clerk lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/secure/authorization-checks sourceFile: /docs/guides/secure/authorization-checks.mdx --- It's best practice to always verify whether or not a user is **authorized** to access sensitive information, important content, or exclusive features. **Authorization** is the process of determining the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions. Clerk provides two main features that can be used to implement authorization checks: * [Organizations](/docs/guides/organizations/overview) * Users can be assigned [Roles and Permissions](/docs/guides/organizations/roles-and-permissions#permissions) * Useful for Role-based and Permission-based access control * [Billing](/docs/guides/billing/overview) * Users can subscribe to Plans and Features * Useful for Subscription-based and Feature-based access control You can use either options independently or combine them together depending on your application's needs. There are a few methods to perform authorization checks: * The has() helper **(recommended)**: returns `false` if the user is unauthorized. * Benefits: it offers flexibility and control over the response; if a user is not authorized, you can choose how your app responds. * Limitations: when checking for Permissions, it only checks for custom Permissions. To check for system Permissions, you have to verify the user's Role instead, which isn't as flexible. * The \ component: prevents content from rendering if the user is unauthorized. * Benefits: it can be used both client-side and server-side (in Server Components). * Limitations: this component only **visually hides** its children when the current user is not authorized. The contents of its children remain accessible via the browser's source code even if the user fails the authorization check. Do not use this component to hide sensitive information that should be completely inaccessible to unauthorized users. For truly sensitive data, it's recommended to use `has()` to perform authorization checks on the server before sending the data to the client. - The auth.protect() helper: throws a `404` error if the user is unauthorized. * Benefits: checks if the user is **both** authenticated **and** authorized. First, for the authentication check, if the user is not authenticated, the helper will redirect the user to the sign-in page if used on page, or will throw a `404` if used in a Route Handler. Then, for the authorization check, if the user is not authorized, the helper will throw a `404` error. * Limitations: doesn't offer control over the response, and can only be used on the server-side. This guide will show you how to implement authorization checks in order to protect actions, content, or entire routes based on the user's **Permissions**, but the same concepts can be applied to Roles, Features, and Plans. When calling the `has()` helper, you would simply replace the `permission` parameter with the appropriate access control type, such as `role`, `feature`, or `plan`. ## Important considerations * When doing authorization checks, it's recommended to use Permission-based over Role-based, and Feature-based over Plan-based authorization, as these approaches are more granular, flexible, and more secure. * Note: Using `has()` **on the server-side** to check Permissions works only with **Custom Permissions**, as [System Permissions](/docs/guides/organizations/roles-and-permissions#system-permissions) aren't included in the session token claims. To check System Permissions, verify the user's Role instead. * Checking for a Role or Permission depends on the user having an Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Without an Active Organization, the authorization checks will likely always evaluate to false by default. * If you would like to perform Role-based authorization checks **without** using Clerk's Organizations feature, see the Role Based Access Control (RBAC) guide. * If you have both Organizations and Billing enabled, a Permission check will only work if the Feature part of the Permission key (`org::`) **is a Feature included in the Organization's active Plan**. For example, say you want to check if an Organization member has the Custom Permission `org:teams:manage`, where `teams` is the Feature. Before performing the authorization check, you need to ensure that the user's Organization is subscribed to a Plan that has the `teams` Feature. If not, the authorization check will always return `false`, *even if the user has the Custom Permission*. - Be cautious when doing authorization checks in layouts, as these don't re-render on navigation, meaning the user session won't be checked on every route change. [Read more in the Next.js docs](https://nextjs.org/docs/app/building-your-application/authentication#layouts-and-auth-checks). ### Use `has()` for authorization checks The has() helper returns `false` if the user does not have the correct access control. If they aren't authorized, you can choose how your app responds. It can be used to perform authorization checks in pages, route handlers, and Server Actions (Next.js only) to protect them from unauthorized access. > \[!WARNING] > Using `has()` **on the server-side** to check Permissions works only with **Custom Permissions**, as [System Permissions](/docs/guides/organizations/roles-and-permissions#system-permissions) aren't included in the session token claims. To check System Permissions, verify the user's Role instead. The following example demonstrates how to perform authorization checks in a page in order to protect the content from unauthorized access. It uses `has()` to check if the user has the `org:team_settings:manage` Permission. If they aren't authorized, `null` is returned and the page isn't rendered. This example is written for Next.js App Router, but can be adapted to other frameworks by using the appropriate method for accessing the `Auth` object. ```tsx {{ filename: 'app/page.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function Page() { // Use `auth()` to access the `has()` helper // For other frameworks, use the appropriate method for accessing the `Auth` object const { has } = await auth() // Check if the user is authorized const canManage = has({ permission: 'org:team_settings:manage' }) // If has() returns false, the user does not have the correct permissions // You can choose how your app responds. This example returns null. if (!canManage) return null return

Team Settings

} ```
The following example demonstrates how to perform authorization checks in a route handler in order to protect it from unauthorized access. It * uses the `isAuthenticated` returned from the Auth object to check if the user is signed in. If the user is not **authenticated**, the Route Handler will return a `401` error. * uses `has()` to check if the user has the correct permission. If the user is not **authorized**, `has()` will return false, causing the Route Handler to return a `403` error. This example is written for Next.js App Router, but can be adapted to other frameworks by using the appropriate method for accessing the Auth object. ```tsx {{ filename: 'app/api/get-teams/route.tsx' }} import { auth } from '@clerk/nextjs/server' export const GET = async () => { // Use `auth()` to access the `has()` helper and the `userId` // For other frameworks, use the appropriate method for accessing the `Auth` object const { isAuthenticated, userId, has } = await auth() // Check if the user is authenticated if (!isAuthenticated) { return Response.json({ error: 'User is not signed in' }, { status: 401 }) } // Check if the user is authorized const canRead = has({ permission: 'org:team_settings:read' }) // If has() returns false, the user does not have the correct permissions // You can choose how your app responds. This example returns a 403 error. if (!canRead) return Response.json({ error: 'User does not have the correct permissions' }, { status: 403 }) // If the user is both authenticated and authorized, move forward with your logic return users.getTeams(userId) } ``` The following example demonstrates how to perform authorization checks in a Server Action in order to protect the action from unauthorized access. It * uses the `isAuthenticated` returned from the Auth object to check if the user is signed in. If the user is not **authenticated**, the Server Action will return a `401` error. * uses `has()` to check if the user has the correct permission. If the user is not **authorized**, `has()` will return false, causing the Server Action to return a `403` error. ```tsx {{ filename: 'app/components/ExampleServerComponent.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function ExampleServerComponent() { async function myServerAction(formData: FormData) { 'use server' // Use `auth()` to access the `has()` helper and the `userId` const { isAuthenticated, has, userId } = await auth() // Check if the user is authenticated if (!isAuthenticated) { return Response.json({ error: 'User is not signed in' }, { status: 401 }) } // Check if the user is authorized const canManage = has({ permission: 'org:team_settings:manage' }) // If has() returns false, the user does not have the correct permissions // You can choose how your app responds. This example returns a 403 error. if (!canManage) return Response.json({ error: 'User does not have the correct permissions' }, { status: 403 }) // If the user is both authenticated and authorized, move forward with your logic return users.getTeams(userId) } return (
{/* Add UI for managing team settings */}
) } ```
### Use `` for authorization checks The \ component prevents content from rendering if the user does not have the correct access control. If they aren't authorized, you can pass a fallback UI to the `fallback` prop. Under the hood, it uses the has() helper so it can only check for custom permissions. It can be used both client-side and server-side (in Server Components). The following example uses the `` component to only render the content for users with the `org:team_settings:manage` permission. If they aren't authorized, `` will render the fallback UI that's passed to the `fallback` prop. ```tsx {{ filename: 'app/page.tsx' }} export default function Page() { return ( You do not have the permissions to manage team settings.

} >
{/* Add UI for managing team settings */}
) } ``` ### Use `auth.protect()` for authorization checks > \[!WARNING] > auth.protect() is only available for App Router, and only works on the server-side. The following example demonstrates how to use auth.protect() to protect a page from unauthenticated and unauthorized access. * If the user is not authenticated, `auth.protect()` will redirect the user to the sign-in route. * If the user is authenticated but is not authorized (as in, does not have the `org:team_settings:read` permission), `auth.protect()` will throw a `404` error. * If the user is both authenticated and authorized, `auth.protect()` will return the user's `userId`. ```tsx {{ filename: 'app/dashboard/settings/page.tsx' }} import { auth } from '@clerk/nextjs/server' export default async function Page() { const { userId } = await auth.protect({ permission: 'org:team_settings:read' }) return

{userId} is authorized to access this page.

} ```
The following example demonstrates how to use auth.protect() to protect a route handler from unauthenticated and unauthorized access. * If the user is not authenticated **nor** authorized (as in, does not have the `org:team_settings:manage` permission), `auth.protect()` will throw a `404` error. * If the user is both authenticated and authorized, `auth.protect()` will return the user's `userId`. ```tsx {{ filename: 'app/api/create-team/route.tsx' }} import { auth } from '@clerk/nextjs/server' export const GET = async () => { const { userId } = await auth.protect({ permission: 'org:team_settings:manage', }) return Response.json({ userId }) } ```
## Authorization checks in JavaScript If you are not using React-based frameworks, you can use the Clerk JavaScript SDK to perform authorization checks. The following example demonstrates how to use the checkAuthorization() method to check if a user is authorized. ```tsx {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(clerkPubKey) await clerk.load() // Check if the user is authenticated if (clerk.isSignedIn) { // Check if the user is authorized const canManageSettings = clerk.session.checkAuthorization({ permission: 'org:team_settings:manage', }) } ``` ## Add custom types In order to enhance typesafety in your project, you can define a global `ClerkAuthorization` interface, which defines the acceptable values for custom access control types. > \[!NOTE] > By default, Roles and Permissions types, such as `OrganizationCustomRoleKey` and `OrganizationCustomPermissionKey`, are assigned `string`. However, if a `ClerkAuthorization` type is defined, it will be utilized instead. The following example demonstrates how to define a global `ClerkAuthorization` interface with the default Roles that Clerk provides. ```tsx {{ filename: 'types/globals.d.ts' }} export {} declare global { interface ClerkAuthorization { permission: '' role: 'org:admin' | 'org:member' } } ``` Because Clerk supports custom access control types, you can modify `ClerkAuthorization` to align with the custom access control types configured in your Clerk application. See the following example, where the default Clerk Roles `org:admin` and `org:member` are replaced with custom Roles `org:super_admin`, `org:teacher`, and `org:student`, and custom Permissions are also added. ```tsx {{ filename: 'types/globals.d.ts' }} export {} declare global { interface ClerkAuthorization { permission: 'org:quiz:create' | 'org:quiz:grade' | 'org:quiz:read' | 'org:quiz:fill' role: 'org:super_admin' | 'org:teacher' | 'org:student' } } ``` --- title: Add reverification for sensitive actions description: Learn how to implement Clerk's reverification feature to protect sensitive actions in your application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/reverification sourceFile: /docs/guides/secure/reverification.mdx --- > \[!WARNING] > > Depending on the SDK you're using, this feature requires `@clerk/nextjs@6.12.7` or later, `@clerk/clerk-react@5.25.1` or later, `@clerk/clerk-js@5.57.1` or later and `@clerk/clerk-sdk-ruby@3.3.0` or later. Reverification allows you to prompt a user to verify their credentials before performing sensitive actions, even if they're already authenticated. For example, in a banking application, transferring money is considered a "sensitive action." Reverification can be used to confirm the user's identity. Clerk's prebuilt components handle reverification for certain [sensitive actions](#sensitive-actions-that-require-reverification), out of the box. However, this guide will show you how to implement reverification for sensitive actions that are unique to your application. ## Sensitive actions that require reverification The following table shows the sensitive actions that require reverification along with the required strategy and timeframe for each action. When using Clerk's prebuilt components, reverification is automatically handled for these actions. | Action | Strategy | Timeframe | | - | - | - | | Update username | Strongest available | 10m | | Set/update password | Strongest available | 10m | | Add/remove email address | Strongest available | 10m | | Add/remove phone number | Strongest available | 10m | | Add/remove Web3 Wallet | Strongest available | 10m | | Add/remove passkey | Strongest available | 10m | | Set primary identification | Strongest available | 10m | | Connect/remove external account | Strongest available | 10m | | Add/remove MFA (TOTP, phone number, backup codes) | Strongest available | 10m | | Revoke session | Strongest available | 10m | | Delete account | Strongest available | 10m | ## Caveats Before enabling this feature, consider the following: 1. **Available factors for reverification**: Not all authentication factors are supported for reverification. Users can only reverify their credentials using the following factors: * First factors: password, email code, phone code * Second factors: phone code, authenticator app, backup code 2. **Graceful downgrade of verification level**: If you request a `second_factor` or `multi_factor` level of verification but the user lacks a second factor available, the utilities automatically downgrade the requested level to `first_factor`. 3. **Eligibility for sensitive actions**: Users without any of the above factors cannot reverify. This can be an issue for apps that don't require email addresses to sign up or have disabled email codes in favor of email links. ## How to require reverification The simplest way to require reverification for a sensitive action is to use the useReverification() hook. This hook will automatically check if the user has verified their credentials within 10 minutes and if not, displays a modal that prompts the user to verify their credentials. See the reference doc for more information and comprehensive examples. However, you may have sensitive actions on the server side that you want to require reverification for, such as in a Server Action or Route Handler. In this case, you can use the `auth.has()` helper to check if the user has verified their credentials within a specific time period. This only does the check on the server side, so you still need to handle reverification on the client side in order for your users to be able to verify their credentials. See the examples below for more information. ### Handle reverification server-side To handle reverification server-side, use the auth.has() helper to check if the user has verified their credentials within a specific time period. Pass a configuration to set the time period you would like. You can pass one of the following configurations: `strict_mfa`, `strict`, `moderate`, and `lax`. See the reference doc for details on each configuration. If the user hasn't verified their credentials within that time period, return either `reverificationError` or `reverificationErrorResponse`, depending on the framework you're using. Use the following tabs to see examples for different frameworks. The following example uses the has() helper to check if the user has verified their credentials within a specific time period. The `strict` configuration sets the time period to 10 minutes. If the user hasn't verified their credentials within 10 minutes, the `reverificationError` utility is used to return an error. ```ts {{ filename: 'app/actions.ts' }} 'use server' import { auth, reverificationError } from '@clerk/nextjs/server' export const myAction = async () => { const { has } = await auth.protect() // Check if the user has *not* verified their credentials within the past 10 minutes const shouldUserRevalidate = !has({ reverification: 'strict' }) // If the user hasn't reverified, return an error with the matching configuration (e.g. `strict`) if (shouldUserRevalidate) { return reverificationError('strict') } // If the user has verified credentials, return a successful response return { success: true } } ``` The following example uses the has() helper to check if the user has verified their credentials within a specific time period. The `strict` configuration sets the time period to 10 minutes. If the user hasn't verified their credentials within 10 minutes, the `reverificationErrorResponse` utility is used to return an error. ```tsx {{ filename: 'app/api/reverification-example/route.ts' }} import { auth, reverificationErrorResponse } from '@clerk/nextjs/server' export const POST = async (req: Request) => { const { has } = await auth() // Check if the user has *not* verified their credentials within the past 10 minutes. const shouldUserRevalidate = !has({ reverification: 'strict' }) // If the user hasn't reverified, return an error with the matching configuration (e.g., `strict`) if (shouldUserRevalidate) { return reverificationErrorResponse('strict') } // If the user has verified credentials, return a successful response return new Response({ success: true }) } ``` The following example uses the `clerk_user_needs_reverification` helper to check if the user has verified their credentials within a specific time period. The `moderate` configuration sets the time period to 1 hour. If the user hasn't verified their credentials within 1 hour, the `clerk_render_reverification` utility is used to return a `403 forbidden` error that the client reads to initiate the reverification flow. Once the user completes the reverification on the client-side, they can access the `foo` action, which returns a success response. ```ruby {{ filename: 'app/controllers/home_controller.rb' }} class HomeController < ApplicationController before_action :require_reverification, only: :foo def foo render json: { success: "true" } end private # will halt the request and respond with a JSON that Clerk.js # will read and kickstart a reverification flow def require_reverification clerk_render_reverification(Clerk::StepUp::PRESETS[:moderate]) if clerk_user_needs_reverification?(Clerk::StepUp::PRESETS[:moderate]) end end ``` > \[!WARNING] > `reverificationErrorResponse` and `reverificationError` requires `@clerk/shared@2.17.0` or later, and `@clerk/clerk-js@5.35.0` or later. * For a JavaScript or Typescript framework that supports the [Fetch API `Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response), use the `reverificationErrorResponse` to trigger reverification. For example: ```typescript {{ filename: 'src/api/reverification-example.ts' }} import type { APIRoute } from 'astro' import { reverificationErrorResponse } from '@clerk/shared/authorization-errors' export const GET: APIRoute = async ({ locals }) => { const { has } = locals.auth() // Check if the user has *not* verified their credentials within the past 10 minutes const shouldUserRevalidate = !has({ reverification: 'strict' }) // If the user hasn't reverified, return an error with the matching configuration (e.g. `strict`) if (shouldUserRevalidate) { return reverificationErrorResponse('strict') } return new Response('success', { status: 200 }) } ``` * For a JavaScript or Typescript framework that provides its own utilities to handle responses, use `reverificationError`. For example: ```typescript {{ filename: 'src/api/hello.ts' }} import { Hono } from 'hono' const app = new Hono() // POST request route app.post('/api/hello', async (c) => { return c.json(reverificationError('strict')) }) ``` * Alternatively, if you're not using JavaScript or TypeScript, you can create a custom helper that returns the following JSON response (it's recommended to use a `403 Forbidden` status code in your response): ```json { "clerk_error": { "type": "forbidden", "reason": "reverification-error" } } ``` ### Handle reverification client-side After setting up reverification on the server-side, you must handle reverification on the client-side so that your users can verify their credentials. The following example demonstrates how to use the useReverification() hook to detect authorization errors and automatically display a modal that allows the user to verify their identity. Upon successful verification, the previously failed request is automatically retried. ```tsx {{ filename: 'app/perform-action/page.tsx' }} 'use client' import { useReverification } from '@clerk/nextjs' import { myAction } from '../actions' export default function Page() { const performAction = useReverification(myAction) const handleClick = async () => { const myData = await performAction() // If `myData` is null, the user cancelled the reverification process // You can choose how your app responds. This example returns null. if (!myData) return } return } ``` ```tsx {{ filename: 'app/transfer/page.tsx' }} 'use client' import { useReverification } from '@clerk/nextjs' export default function Page({ amount_in_cents }: { amount_in_cents: number }) { const transferMoney = useReverification( async () => await fetch('/api/reverification-example', { method: 'POST', body: JSON.stringify({ amount_in_cents }), }), ) return } ``` ```tsx {{ filename: '/src/components/TransferButton.js' }} import { useReverification } from '@clerk/clerk-react' export function TransferButton({ amount_in_cents }: { amount_in_cents: number }) { const transferMoney = useReverification(() => fetch('/api/reverification-example', { method: 'POST', body: JSON.stringify({ amount_in_cents }), }), ) return } ``` --- title: Restrictions description: Learn how to manage user access to your application by configuring Clerk's access restrictions. search: rank: 1 keywords: - allowlist - blocklist - restricted - restricted mode - waitlist lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/restricting-access sourceFile: /docs/guides/secure/restricting-access.mdx --- Clerk provides restriction options that give you enhanced control over who can access your application. These options enable you to limit sign-ups, sign-ins, or prevent accounts with specific identifiers, such as email addresses, phone numbers, and even entire domains, from accessing your application. ## Sign-up modes Clerk supports multiple sign-up modes, giving you flexibility in managing user access to your application. To configure sign-up modes: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, you can enable one of the following options: * **[Public](#public)** * **[Restricted](#restricted)** * **[Waitlist](#waitlist)** ### Public In **Public** mode, the sign-up process is open to anyone. This mode is ideal for applications that want broad user access. ### Restricted In **Restricted** mode, user access is controlled by the application admin(s). Users can be added to the application through [invitations](/docs/guides/users/inviting), [enterprise connections](/docs/guides/configure/auth-strategies/enterprise-connections/overview) or [manual user creation](/docs/guides/users/managing). This mode is ideal for applications that are in private beta or internal tools. Additional features available in **Restricted** mode: * The \ component will keep the prompt to sign up hidden by default. This is to avoid confusion for users who don't have access. * The \ is accessible only to users who have been invited and have a valid invitation link. Users who don't have access will see a message indicating that they need an invitation to sign up. ### Waitlist ![\ component](/docs/images/ui-components/waitlist.svg) > \[!NOTE] > If you're using Next.js, the`` component is available in `@clerk/nextjs@6.2.0` and above. In **Waitlist** mode, users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. Additional features available in **Waitlist** mode: * The \ component will only be accessible to users who have been approved from the waitlist. * The \ is accessible only to users who have been invited and have a valid invitation link. Users who don't have access will see a message indicating that they need an invitation to sign up. * The \ component provides a form where users can submit their details to join the waitlist. Once approved by admins, users will receive an email with access instructions. * If you're using the `` component, you must provide the `waitlistUrl` prop either in the \ or \ component to ensure proper functionality. #### Manage waitlist entries To manage a user on your waitlist: 1. In the Clerk Dashboard, navigate to the [**Waitlist**](https://dashboard.clerk.com/~/waitlist) page. 2. On the right-side of the user's row, select the menu icon (...). 3. Select **Invite** to invite the user to your application. Select **Deny** to deny the user access to your application. ## Allowlist > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By adding specific identifiers to the allowlist, *only* users with those identifiers will be able to sign up or sign in to your application, while others will be blocked. This is useful for internal tools, where you want to allow only users with your company domain to have access to the application. After creating an account, users cannot change their identifier to bypass the allowlist, making this feature a secure way to control who can access your application. For example, if you add `clerk.dev` as an allowed email domain, any user with a `@clerk.dev` email address can sign up for your application. Email addresses from different domains will not be able to sign up. To enable this feature: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. In the **Allowlist** section, toggle on **Enable allowlist**. > \[!CAUTION] > Enabling the Allowlist without adding any identifier exceptions blocks *all* sign-ins and sign-ups. ## Blocklist > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. By adding specific identifiers to the blocklist, you can prevent users with those identifiers from signing up. This helps protect your application from attacks, such as scripts creating multiple spam accounts. For example, adding `clerk.dev` to the blocked email domains list prevents anyone with an email address ending in `@clerk.dev` from signing up. You can also block email addresses from all subdomains by using `*@*.clerk.dev`. This prevents sign-ups from email addresses such as `@subdomain.clerk.dev` or `@subdomain2.clerk.dev`, and deeper subdomains like `@subdomain.subdomain2.clerk.dev`. To enable this feature: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. In the **Blocklist** section, toggle on **Enable blocklist**. > \[!WARNING] > In the case that you have enabled the allowlist and the blocklist and have added the same identifier in both, the allowlist takes precedence. For additional security, adding an individual email address to the blocklist will also block any attempts to sign up or sign in with the email address modified to contain a subaddress. Subaddresses are identified by the presence of any of the following characters in the local part of the email address: `+`, `#`, `=`. For example, if you add `john.doe@clerk.dev` as a blocked email address, it means that anybody with `john.doe@clerk.dev` email address will not be able to sign up for your application, including `john.doe+anything@clerk.dev` and any other subaddress. ## Block email subaddresses **Block email subaddresses** allows you to block all email addresses that contain the characters `+`, `=` or `#` from signing up or being added to existing accounts. For example, an email address like `user+sub@clerk.com` will be blocked. > \[!NOTE] > Existing accounts with email subaddresses will not be affected by this restriction, and will still be allowed to sign in. > > This feature is designed to prevent malicious sign-in attempts. The first email containing a subaddress will be allowed, but any subsequent sign-ins using additional subaddresses will be blocked. To enable this feature: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. In the **Restrictions** section, toggle on **Block email subaddresses**. ### Block sign-ups that use disposable email addresses **Block disposable email addresses** allows you to block all email addresses that are *known to be disposable* from signing up for your application. This is useful to prevent spam accounts from signing up. To enable this feature: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. In the **Restrictions** section, toggle on **Block sign-ups that use disposable email addresses**. --- title: Password protection and rules description: Clerk refers to the National Institute of Standards and Technology (NIST) guidelines to determine the character rules for passwords. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/password-protection-and-rules sourceFile: /docs/guides/secure/password-protection-and-rules.mdx --- ## Password rules Clerk refers to the National Institute of Standards and Technology (NIST) guidelines to determine the character rules for passwords: > \[!NOTE] > Verifiers SHALL require subscriber-chosen memorized secrets to be at least 8 characters in length. Verifiers SHOULD permit subscriber-chosen memorized secrets at least 64 characters in length. All printing ASCII [RFC 20](https://datatracker.ietf.org/doc/html/rfc20) characters as well as the space character SHOULD be acceptable in memorized secrets. Unicode [ISO/IEC 10646](https://en.wikipedia.org/wiki/Universal_Coded_Character_Set) characters SHOULD be accepted as well. To make allowances for likely mistyping, verifiers MAY replace multiple consecutive space characters with a single space character prior to verification, provided that the result is at least 8 characters in length. Truncation of the secret SHALL NOT be performed. For purposes of the above length requirements, each Unicode code point SHALL be counted as a single character. [NIST Special Publication 800-63B](https://pages.nist.gov/800-63-3/sp800-63b.html#sec5) While these rules might seem lax independently, NIST's additional compromised password protection guidelines do more to prevent the use of unsafe passwords. Also, bear in mind, that passwords are not a requirement for using Clerk. Applications can be configured to use a passwordless strategy that relies on your users being sent one-time passwords instead. ## Reject compromised passwords Clerk refers to the National Institute of Standards and Technology (NIST) guidelines to determine its handling of compromised passwords: When processing requests to establish and change memorized secrets, verifiers SHALL compare the prospective secrets against a list that contains values known to be commonly-used, expected, or compromised. [NIST Special Publication 800-63B](https://pages.nist.gov/800-63-3/sp800-63b.html#sec5) Specifically, Clerk contracts with [HaveIBeenPwned](https://haveibeenpwned.com/) to compare prospective passwords against its corpus of over 10 billion compromised credentials. When the user provides the correct password, if it has been found in online breach data, they will be prompted to reset their password. This is useful for blocking passwords in the case that: * The password has recently been added to the compromised password database * The user was able to set a compromised password because protection was off at the time * The user was migrated to Clerk along with their existing password digest > \[!NOTE] > Password reset for compromised passwords uses the same flow as "forgot password". The user will need to authenticate first via an OTP code sent to their email or phone and only then they will be able to set a new — more secure — password. To configure this feature: 1. In the Clerk Dashboard, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page. 2. Select the **Password** tab and on the right side, select **Update password requirements**. You can enable or disable **Reject compromised passwords**. ## Password strength Clerk uses [zxcvbn-ts](https://zxcvbn-ts.github.io/zxcvbn/) for estimating the strength of passwords and leverages the [Open Web Application Security Project (OWASP) guidelines](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) to determine its handling of password strength: > \[!NOTE] > OWASP recommends using a password strength estimation library like zxcvbn to evaluate the strength of passwords. This can help identify weak passwords and prevent their use. For users that set an average/weak password that complies with your organization's policies but could be stronger - Clerk also provides a gentle recommendation to use a stronger password. > \[!NOTE] > OWASP recommends providing feedback to users on the strength of their password and offering suggestions for improvement. This can help users create stronger passwords and improve the overall security of the application. --- title: Legal compliance description: Learn how to configure your legal compliance settings in the Clerk Dashboard. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/legal-compliance sourceFile: /docs/guides/secure/legal-compliance.mdx --- Clerk provides a legal compliance setting that allows you to require users to agree to your terms of service or privacy policy before they can sign up to your application. After enabling the setting, there will be a checkbox to accept the terms in your \ component or [Account Portal sign-up page](/docs/guides/customizing-clerk/account-portal#sign-up). To configure the setting: 1. In the Clerk Dashboard, navigate to the [**Legal**](https://dashboard.clerk.com/~/compliance/legal) page. 2. Enable or disable **Require express consent to legal documents**. --- title: Brute force attacks and locking user accounts description: User information is a prime target for malicious activity. Clerk protects your users against brute force attacks by locking out accounts with too many sign-in attempts until a set period of time has passed. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/user-lockout sourceFile: /docs/guides/secure/user-lockout.mdx --- User accounts are a vector for malicious attacks for many reasons, from impersonation to collecting personally identifiable information (PII). One method is a **"brute force"** attack, where a script will attempt many different passwords to sign into an account. One line of defense against these attacks is to temporarily deny attempts to sign into accounts that attempt too many failed sign-ins in a short period of time. Locking out sign-in attempts disrupts the attack and makes the account a less attractive target. ## How Clerk protects against brute force attacks **Account lockout** is a Clerk feature that enables you to protect your users from brute-force attacks on static credentials. If enabled on your instance, Clerk will automatically track users' failed verification attempts when they try to authenticate via password on backup code. ### How account lockout works By default, Clerk applications will lock user accounts after 100 failed sign-in attempts and require a one hour cool down period before anyone can attempt to sign into that account again. (While 100 attempts may seem like a lot to a human, it is very easy to reach this maximum for a bot!) If the maximum allowed attempts are reached, the user will be locked out from signing in again until the lockout duration lapses. Lockout can also be [configured to never expire](#customize-max-sign-in-attempts-and-lockout-duration), in which case the user will not be able to sign in unless an admin unlocks them. An admin can [unlock a user before the expiry of the lockout period via the Clerk Dashboard](#unlock-user-accounts) or [programmatically](#unlock-a-user-programmatically). Clerk measures the following actions as part of account lockout: * Password attempts * Password resets * Backup code requests * Email & Phone codes * TOTP attempts ## What a locked out user sees When a user exceeds the maximum sign-in attempts, the Clerk \ component will inform them of how long they have been locked out for and to contact support for more information. ![The Clerk component sign-in form with a red alert stating 'Your account is locked. You will be able to try again in 59 minutes. For more information, contact support.'](/docs/images/security/userlock_login.png) > \[!NOTE] > Currently, users cannot unlock their own account or submit a request to the admin to be unlocked ("self-service unlock"). This is an upcoming feature, so see the [changelog](https://clerk.com/changelog){{ target: '_blank' }} periodically to find out when it is available. Until then, you can [lock and unlock user accounts programmatically](#unlock-a-user-programmatically). ## Customize max sign-in attempts and lockout duration You can customize the number of times a sign-in can be attempted before the account is locked, and how long lockouts last. To configure this feature, in the Clerk Dashboard, navigate to the [**Attack protection**](https://dashboard.clerk.com/~/user-authentication/attack-protection) page. Here, you can enable or disable **Account lockout**, or configure the following settings: * The **Maximum attempt limit** setting controls the number of failed sign-in attempts before a user is locked out. To change this setting, enter a new number of failed attempts allowed. (The default is 100 attempts.) * **Lockout duration** controls the amount of time a user is locked out from their account after reaching the **Maximum attempt limit**. * The **Time limit** setting allows you to set an amount of time until the user account is unlocked. To change this setting, select the unit of time (minutes/hours/days/years) and enter the number of units you want lockouts to last. * The **Indefinite Lockout** setting locks a user account until it's manually unlocked in the Clerk Dashboard. ## Unlock user accounts There are two ways to unlock a user's account: * Through the Clerk Dashboard * Programmatically ### Unlock a user through the Clerk Dashboard Users with admin roles can override lockouts through the Clerk Dashboard. 1. In the top in the Clerk Dashboard, select [**Users**](https://dashboard.clerk.com/~/users). 2. Locate the locked user by looking for a "locked" badge next to their username/email. 3. On the right of that user's row, open the menu by selecting the three dots icon. 4. Select **Unlock** to unlock the user account. Alternatively, you can unlock a user's account on their profile page. 1. In the top in the Clerk Dashboard, select [**Users**](https://dashboard.clerk.com/~/users). 2. Locate the locked user by looking for a "locked" badge next to their username/email. 3. Select the user's row to be taken to their profile page. 4. Scroll to the **Unlock user** section, and select **Unlock user**. ### Unlock a user programmatically You can programmatically unlock a user using the [`UnlockUser`](/docs/reference/backend-api/tag/users/post/users/\{user_id}/unlock){{ target: '_blank' }} Backend API endpoint. ### Use cases #### Display an unlock button Your custom sign-in page could expose a button or link that allows the user to request an unlock token when they are locked out of their account. * Your app should be able to generate a random unlock token and associate it with the user. * The unlock token can be sent to the user via email or SMS. * After successful entry of the unlock token, your app's backend can issue an unlock request to the Clerk Backend API. #### Send an unlock request to an admin If your app supports users submitting admin requests, it could expose a way of requesting an admin unlock. * A request for unlock could arrive in your app's admin dashboard. * If an admin reviews the request and decides to grant access back to the user, they can request an unlock from your app's backend, which should in turn call the Clerk Backend API. ## Lock a user programmatically If you'd like to manually lock a user from signing in, you can use the [`LockUser`](/docs/reference/backend-api/tag/users/post/users/\{user_id}/lock){{ target: '_blank' }} Backend API endpoint. Keep in mind that Clerk will still lock the user based on failed verification attempts. --- title: Force multi-factor authentication (MFA) for all users description: Learn how to force multi-factor authentication (MFA) for all users in your Clerk application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/force-mfa sourceFile: /docs/guides/secure/force-mfa.mdx --- By default, Clerk does not enforce [multi-factor authentication (MFA)](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#multi-factor-authentication) for all users. This guide demonstrates how to force MFA for all users by using `clerkMiddleware()` to intercept all requests and check whether a user has MFA enabled. If the user does not have MFA enabled, `clerkMiddleware()` redirects them to the `/mfa` page where they can set up MFA. ## Enable MFA in the Clerk Dashboard If you haven't already, enable MFA for your users. 1. In the Clerk Dashboard, navigate to the [**Multi-factor**](https://dashboard.clerk.com/~/user-authentication/multi-factor) page. 2. Toggle on the MFA strategies you would like to enable. ## Customize the session token to include the `two_factor_enabled` property Every `User` object has a `two_factor_enabled` property that indicates whether the user has MFA enabled. Store this property in the session token so that you can check it in your `clerkMiddleware()`. 1. In the Clerk Dashboard, navigate to the [**Sessions**](https://dashboard.clerk.com/~/sessions) page. 2. Under **Customize session token**, in the **Claims** editor, enter the following JSON and select **Save**. The key can be any string, but the value must be the `user.two_factor_enabled` property, as shown in the following example. If you have already customized your session token, you may need to merge this with what you currently have. ```json { "isMfa": "{{user.two_factor_enabled}}" } ``` ## Update `clerkMiddleware()` Update your `clerkMiddleware()` to check if the user has MFA enabled. > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. ```tsx {{ filename: 'proxy.ts', collapsible: true }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' const isMFARoute = createRouteMatcher(['/account/manage-mfa/add(.*)']) const isSignInRoute = createRouteMatcher(['/sign-in(.*)']) export default clerkMiddleware(async (auth, req) => { const { userId, sessionClaims } = await auth() // Redirect to homepage if the user is signed in and on the sign-in page if (userId !== null && isSignInRoute(req)) { return NextResponse.redirect(new URL('/', req.url)) } // Redirect to MFA setup page if MFA is not enabled if (userId !== null && !isMFARoute(req)) { if (sessionClaims.isMfa === undefined) { console.error('You need to add the `isMfa` claim to your session token.') } if (sessionClaims.isMfa === false) { return NextResponse.redirect(new URL('/account/manage-mfa/add', req.url)) } } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ```tsx {{ filename: 'src/middleware.ts', collapsible: true }} import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server' const isMFARoute = createRouteMatcher(['/account/manage-mfa/add(.*)']) const isSignInRoute = createRouteMatcher(['/sign-in(.*)']) export const onRequest = clerkMiddleware((auth, context) => { const { userId, sessionClaims } = auth() // Redirect to homepage if the user is signed in and on the sign-in page if (userId !== null && isSignInRoute(context.request)) { return Response.redirect(new URL('/', context.request.url)) } // Redirect to MFA setup page if MFA is not enabled if (userId !== null && !isMFARoute(context.request)) { if (sessionClaims.isMfa === undefined) { console.error('You need to add the `isMfa` claim to your session token.') } if (sessionClaims.isMfa === false) { return Response.redirect(new URL('/account/manage-mfa/add', context.request.url)) } } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` By default, the Nuxt SDK automatically adds the `clerkMiddleware()` helper to your Nuxt application. To manually configure the middleware, in your `nuxt.config.ts` file, under the `clerk` property, set `skipServerMiddleware: true`. ```tsx {{ filename: 'nuxt.config.ts', mark: [[3, 5]] }} export default defineNuxtConfig({ modules: ['@clerk/nuxt'], clerk: { skipServerMiddleware: true, }, }) ``` Then, in your `server/middleware/clerk.ts` file, add the following code: ```tsx {{ filename: 'server/middleware/clerk.ts', collapsible: true }} import { clerkMiddleware } from '@clerk/nuxt/server' export default clerkMiddleware(async (event) => { const isMFARoute = event.path.startsWith('/account/manage-mfa/add') const isSignInRoute = event.path.startsWith('/sign-in') const { userId, sessionClaims } = event.context.auth() // Redirect to homepage if the user is signed in and on the sign-in page if (userId !== null && isSignInRoute) { throw createError({ statusMessage: 'You are already signed in.', }) } // Redirect to MFA setup page if MFA is not enabled if (userId !== null && !isMFARoute) { if (sessionClaims.isMfa === undefined) { throw createError({ statusMessage: 'You need to add the `isMfa` claim to your session token.', }) } if (sessionClaims.isMfa === false) { throw createError({ statusMessage: 'You need to enable MFA for your account.', }) } } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ## Build your MFA setup page Follow the [custom flow guide](/docs/guides/development/custom-flows/account-updates/manage-totp-based-mfa) to build the `/account/manage-mfa/add` page. --- title: Session options description: Clerk provides session management options for fine-tuning user visits to your application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/session-options sourceFile: /docs/guides/secure/session-options.mdx --- Clerk provides session management options for fine-tuning user visits to your application, including options for session lifetime, multi-session handling, and session token customization. ## Session lifetime Depending on the business domain of an application, there might be different requirements for how long users should remain signed in. Criteria to base this decision upon typically revolve around user activity on the application and how long it has been since the user first signed in. Ultimately, picking the ideal session lifetime is a trade-off between security and user experience. Longer sessions are generally better for UX but worse for security; and vice-versa. Fortunately, with Clerk, you have the ability to fully control the lifetime of your users' sessions. There are two settings for doing so and you can set them via your instance settings in the [Clerk Dashboard](https://dashboard.clerk.com/): Inactivity timeout and Maximum lifetime. > \[!NOTE] > Note that either one or both must be enabled at all times. For security reasons, you are not allowed to disable both settings. ### Inactivity timeout > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. Inactivity timeout is the duration after which a session will expire and the user will have to sign in again, if they haven't been active on your site. A user is considered inactive when the application is closed, or when the app stops refreshing the token. By default, this setting is disabled. You can enable it and configure a custom inactivity timeout by following these steps: 1. In the Clerk Dashboard, navigate to the [**Sessions**](https://dashboard.clerk.com/~/sessions) page. 2. Toggle on **Inactivity timeout**. 3. Set your desired duration. > \[!NOTE] > You should be aware of [browser limitations](#browser-limitations-on-cookies), which may cause users to be signed out before the configured inactivity timeout. ### Maximum lifetime Maximum lifetime is the duration after which a session will expire and the user will have to sign in again, regardless of their activity on your site. By default, this setting is enabled with a default value of 7 days for all newly created instances. Setting a custom maximum lifetime requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but it's available in development mode so that you can try out what works for you. To find this setting and change the value: 1. In the Clerk Dashboard, navigate to the [**Sessions**](https://dashboard.clerk.com/~/sessions) page. 2. Toggle on **Maximum lifetime**. 3. Set your desired duration. > \[!NOTE] > You should be aware of [browser limitations](#browser-limitations-on-cookies), which may cause users to be signed out before the configured maximum lifetime. ## Browser limitations on cookies Regardless of how [session lifetimes](#session-lifetime) are configured, there are certain browser limitations & behaviors which may clear Clerk's session cookie. This will cause users to be signed out, even if your session lifetimes are set to a longer duration. As a result, it is impossible to achieve a setup where your users are never signed out. ### User behaviors In the event that a user manually clears their cookies, Clerk's session cookie will be lost. Similarly, if a user signs in via an incognito window and they then close all incognito windows, Clerk's session cookie will be lost. Both of these scenarios will cause the user to have to sign in again. ### Google Chrome Cookies set in Google Chrome have a `Max-Age` upper limit of [400 days](https://developer.chrome.com/blog/cookie-max-age-expires). Users who are using Google Chrome will be signed out within 400 days, even if session lifetime is set to a longer duration. There is no workaround for this. This is per the [HTTP Working Group Specification](https://httpwg.org/http-extensions/draft-ietf-httpbis-rfc6265bis.html#section-5.5) which is likely to get implemented by other browsers in the near future. ## Multi-session applications A multi-session application is an application that allows multiple accounts to be signed in from the same browser at the same time. The user can switch from one account to another seamlessly. Each account is independent from the rest and has access to different resources. To enable multi-session in your application, you need to configure it in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**Sessions**](https://dashboard.clerk.com/~/sessions) page. 2. Toggle on **Multi-session handling**. 3. Select **Save**. ### Add multi-session support to your app There are two main ways to add the multi-session feature to your application: * Use the \ component if you want to use a prebuilt UI. * [Build a custom flow](/docs/guides/development/custom-flows/authentication/multi-session-applications) if you want to rebuild the existing Clerk flow using the Clerk API. It's highly recommended to wrap your application with the following `` component. The fragment's `key` is set to the session ID. Every time the session ID changes, the `key` changes, forcing React to recreate the entire component tree under the fragment and guaranteeing a full rerendering cycle. ```tsx function MultisessionAppSupport({ children }: { children: React.ReactNode }) { const { session } = useSession() return {children} } ``` The following example demonstrates adding multi-session support to a Next.js App Router application. It requires creating the `` as a client component, and then using it in the `app/layout.tsx` file to wrap the entire application. This ensures the `layout.tsx` remains a server component. ```tsx {{ filename: 'app/layout.tsx' }} import React from 'react' import { ClerkProvider } from '@clerk/nextjs' import { MultisessionAppSupport } from './components/MultisessionAppSupport' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ```tsx {{ filename: 'app/components/MultisessionAppSupport.tsx' }} 'use client' import React from 'react' import { useSession } from '@clerk/nextjs' export default function MultisessionAppSupport({ children }: { children: React.ReactNode }) { const { session } = useSession() return {children} } ``` ### Sign out behavior By default, signing out from a currently active account in a multi-session app will navigate to the sign-in page's `/choose` route. If a sign-in URL is not set, signing out will navigate to Clerk's Account Portal `/sign-in/choose` page, allowing the user to choose which account to switch into. If a sign-in URL is set, either through the signInUrl prop on `` or the [`CLERK_SIGN_IN_URL` environment variable](/docs/guides/development/clerk-environment-variables#sign-in-and-sign-up-redirects), signing out will navigate to that URL's `/choose` route. For example, if `signInUrl` or `CLERK_SIGN_IN_URL` is set to `https://example.com/sign-in`, signing out of a multi-session app will navigate to `https://example.com/sign-in/choose`. To redirect to a custom route, pass the afterMultiSessionSingleSignOutUrl property to ``. ## Customize session token Session tokens are JWTs that contain a set of [default claims](/docs/guides/sessions/session-tokens) required by Clerk. You can customize these tokens by providing additional claims of your own. To learn how to customize session tokens, see the [dedicated guide](/docs/guides/sessions/customize-session-tokens). --- title: Features description: Grant access to your privileged content and data using features. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/secure/features sourceFile: /docs/guides/secure/features.mdx --- Features are specific capabilities or functionalities in your application that you want to control access to. They are used in authorization checksAuthorization checks are checks you perform in your code to determine the access rights and privileges of a user, ensuring they have the necessary permissions to perform specific actions or access certain content. Learn more about [authorization checks](/docs/guides/secure/authorization-checks).. Features can be used in two ways: * With Clerk's [Organizations](/docs/guides/organizations/overview) feature to create Custom Permissions. Custom Permissions are always tied to a Feature, and are formatted as `org::`. For example, you could create a Feature called **invoices** and then create a new Permission called **create invoices**. The Custom Permission's key would be `org:invoices:create`. Learn more about [Custom Permissions](/docs/guides/organizations/roles-and-permissions). * With Clerk's Billing feature to create Features specific to a Subscription Plan. See the [Billing docs](/docs/guides/billing/overview) for more information. To manage your Features, navigate to the [**Features**](https://dashboard.clerk.com/~/features) page in the Clerk Dashboard. --- title: Set up a waitlist in your Next.js app description: Learn how to add a waitlist to your Next.js application. sdk: nextjs sdkScoped: "true" canonical: /docs/guides/secure/waitlist lastUpdated: 2025-11-21T23:37:11.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/guides/secure/waitlist.mdx --- In [**Waitlist** mode](/docs/guides/secure/restricting-access#waitlist), users can register their interest in your app by joining a waitlist. This mode is ideal for apps in early development stages or those wanting to generate interest before launch. This guide shows you how to get Clerk integrated and how to add a waitlist to your Next.js application. ## Install `@clerk/nextjs` The [Clerk Next.js SDK](/docs/reference/nextjs/overview) gives you access to prebuilt components, React hooks, and helpers to make user authentication easier. Run the following command to install the SDK: ```npm npm install @clerk/nextjs ``` ## Set your Clerk API keys Add the following keys to your `.env` file. These keys can always be retrieved from the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys){{ track: 'exp_create_account_nextjs_quickstart' }} page. 2. In the **Quick Copy** section, copy your Clerk Publishable and Secret Keys. 3. Paste your keys into your `.env` file. The final result should resemble the following: ```env {{ filename: '.env' }} NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} ``` ## Enable Waitlist mode To enable **Waitlist** mode, follow these steps: 1. In the Clerk Dashboard, navigate to the [**Restrictions**](https://dashboard.clerk.com/~/user-authentication/restrictions) page. 2. Under the **Sign-up modes** section, enable **Waitlist**. To manage users on your waitlist: 1. In the Clerk Dashboard, navigate to the [**Waitlist**](https://dashboard.clerk.com/~/waitlist) page. 2. On the right-side of a user's row, select the menu icon (...). 3. Select **Invite** to invite the user to your application. Select **Deny** to deny the user access to your application. ## Add the `` component The \ component renders a form that allows users to join for early access to your app. The following example includes a basic implementation of the `` component hosted on the `/` route (the home page). You can use this as a starting point for your own implementation. ```jsx {{ filename: 'app/page.tsx' }} import { Waitlist } from '@clerk/nextjs' export default function Page() { return } ``` ## Add `` to your app The \ component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with `` to make authentication globally accessible. See the reference docs for other configuration options. To use the `` component in your app, you must provide the `waitlistUrl` prop, which points to the URL of your waitlist page. ```tsx {{ filename: 'app/layout.tsx', mark: [6] }} import { ClerkProvider } from '@clerk/nextjs' import './globals.css' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` ## Add sign-in functionality To allow users to sign in once they've been approved from the waitlist, you must: * [Add `clerkMiddleware()` to your app.](#add-clerk-middleware-to-your-app) * [Add a sign-in page.](#add-a-sign-in-page) ### Add `clerkMiddleware()` to your app > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. [`clerkMiddleware()`](/docs/reference/nextjs/clerk-middleware) grants you access to user authentication state throughout your app, on any route or page. It also allows you to protect specific routes from unauthenticated users. To add `clerkMiddleware()` to your app, follow these steps: 1. Create a `proxy.ts` file. * If you're using the `/src` directory, create `proxy.ts` in the `/src` directory. * If you're not using the `/src` directory, create `proxy.ts` in the root directory alongside `.env`. 2. In your `proxy.ts` file, export the `clerkMiddleware()` helper: ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware } from '@clerk/nextjs/server' export default clerkMiddleware() export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` 3. By default, `clerkMiddleware()` will not protect any routes. All routes are public and you must opt-in to protection for routes. See the [`clerkMiddleware()` reference](/docs/reference/nextjs/clerk-middleware) to learn how to require authentication for specific routes. ### Add a sign-in page The following example demonstrates how to render the `` component. ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx' }} import { SignIn } from '@clerk/nextjs' export default function Page() { return } ``` Update your environment variables to point to your custom sign-in page. For more information on building a custom sign-in-or-up page, see the dedicated guide. ```env {{ filename: '.env' }} NEXT_PUBLIC_CLERK_SIGN_IN_URL="/sign-in" ``` --- title: Implement basic Role Based Access Control (RBAC) with metadata description: Learn how to leverage Clerk's publicMetadata to implement your own basic Role Based Access Controls. sdk: nextjs sdkScoped: "true" canonical: /docs/guides/secure/basic-rbac lastUpdated: 2025-11-21T22:00:50.000Z availableSdks: nextjs notAvailableSdks: react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: nextjs sourceFile: /docs/guides/secure/basic-rbac.mdx --- To control which users can access certain parts of your app, you can use the [Roles](/docs/guides/organizations/roles-and-permissions#roles) feature. Although Clerk offers Roles as part of the [Organizations](/docs/guides/organizations/overview) feature set, not every app implements Organizations. **This guide covers a workaround to set up a basic Role Based Access Control (RBAC) system for products that don't use Clerk's Organizations or Roles.** This guide assumes that you're using Next.js App Router, but the concepts can be adapted to Next.js Pages Router and Remix. ## Configure the session token Clerk provides [user metadata](/docs/guides/users/extending), which can be used to store information, and in this case, it can be used to store a user's Role. Since `publicMetadata` can only be read but not modified in the browser, it is the safest and most appropriate choice for storing information. To build a basic RBAC system, you first need to make `publicMetadata` available to the application directly from the session token. By attaching `publicMetadata` to the user's session, you can access the data without needing to make a network request each time. 1. In the Clerk Dashboard, navigate to the [**Sessions**](https://dashboard.clerk.com/~/sessions) page. 2. Under **Customize session token**, in the **Claims** editor, enter the following JSON and select **Save**. If you have already customized your session token, you may need to merge this with what you currently have. ```json { "metadata": "{{user.public_metadata}}" } ``` ## Create a global TypeScript definition 1. In your application's root folder, create a `types/` directory. 2. Inside this directory, create a `globals.d.ts` file with the following code. This file will provide auto-completion and prevent TypeScript errors when working with Roles. For this guide, only the `admin` and `moderator` roles will be defined. ```ts {{ filename: 'types/globals.d.ts' }} export {} // Create a type for the Roles export type Roles = 'admin' | 'moderator' declare global { interface CustomJwtSessionClaims { metadata: { role?: Roles } } } ``` ## Set the admin Role for your user Later in the guide, you will add a basic admin tool to change a user's Role. For now, manually add the `admin` Role to your own user account. 1. In the Clerk Dashboard, navigate to the [**Users**](https://dashboard.clerk.com/~/users) page. 2. Select your own user account. 3. Scroll down to the **User metadata** section and next to the **Public** option, select **Edit**. 4. Add the following JSON and select **Save**. ```json { "role": "admin" } ``` ## Create a reusable function to check Roles Create a helper function to simplify checking Roles. 1. In your application's root directory, create a `utils/` folder. 2. Inside this directory, create a `roles.ts` file with the following code. The `checkRole()` helper uses the [`auth()`](/docs/reference/nextjs/app-router/auth) helper to access the user's session claims. From the session claims, it accesses the `metadata` object to check the user's Role. The `checkRole()` helper accepts a Role of type `Roles`, which you created in the [Create a global TypeScript definition](#create-a-global-type-script-definition) step. It returns `true` if the user has that Role or `false` if they do not. ```ts {{ filename: 'utils/roles.ts' }} import { Roles } from '@/types/globals' import { auth } from '@clerk/nextjs/server' export const checkRole = async (role: Roles) => { const { sessionClaims } = await auth() return sessionClaims?.metadata.role === role } ``` > \[!NOTE] > You can customize the behavior of the `checkRole()` helper function to suit your needs. For example, you could modify it to return the Roles a user has or create a `protectByRole()` function that handles Role-based redirects. ## Create the admin dashboard Now, it's time to create an admin dashboard. The first step is to create the `/admin` route. 1. In your `app/` directory, create an `admin/` folder. 2. In the `admin/` folder, create a `page.tsx` file with the following placeholder code. ```tsx {{ filename: 'app/admin/page.tsx' }} export default function AdminDashboard() { return

This is the protected admin dashboard restricted to users with the `admin` Role.

} ``` ## Protect the admin dashboard To protect the `/admin` route, choose **one** of the two following methods: 1. **Middleware**: Apply Role-based access control globally at the route level. This method restricts access to all routes matching `/admin` before the request reaches the actual page. 2. **Page-level Role check**: Apply Role-based access control directly in the `/admin` page component. This method protects this specific page. To protect other pages in the admin dashboard, apply this protection to each route. > \[!IMPORTANT] > You only need to follow **one** of the following methods to secure your `/admin` route. ### Option 1: Protect the `/admin` route using middleware > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. 1. In your app's root directory, create a `proxy.ts` file with the following code. The `createRouteMatcher()` function identifies routes starting with `/admin`. `clerkMiddleware()` intercepts requests to the `/admin` route, and checks the user's Role in their `metadata` to verify that they have the `admin` Role. If they don't, it redirects them to the home page. ```tsx {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' const isAdminRoute = createRouteMatcher(['/admin(.*)']) export default clerkMiddleware(async (auth, req) => { // Protect all routes starting with `/admin` if (isAdminRoute(req) && (await auth()).sessionClaims?.metadata?.role !== 'admin') { const url = new URL('/', req.url) return NextResponse.redirect(url) } }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ### Option 2: Protect the `/admin` route at the page-level 1. Add the following code to the `app/admin/page.tsx` file. The `checkRole()` function checks if the user has the `admin` Role. If they don't, it redirects them to the home page. ```tsx {{ filename: 'app/admin/page.tsx' }} import { checkRole } from '@/utils/roles' import { redirect } from 'next/navigation' export default async function AdminDashboard() { // Protect the page from users who are not admins const isAdmin = await checkRole('admin') if (!isAdmin) { redirect('/') } return

This is the protected admin dashboard restricted to users with the `admin` Role.

} ``` ## Create server actions for managing a user's Role 1. In your `app/admin/` directory, create an `_actions.ts` file with the following code. The `setRole()` action checks that the current user has the `admin` Role before updating the specified user's Role using Clerk's JS Backend SDK. The `removeRole()` action removes the Role from the specified user. ```ts {{ filename: 'app/admin/_actions.ts' }} 'use server' import { checkRole } from '@/utils/roles' import { clerkClient } from '@clerk/nextjs/server' export async function setRole(formData: FormData) { const client = await clerkClient() // Check that the user trying to set the Role is an admin if (!checkRole('admin')) { return { message: 'Not Authorized' } } try { const res = await client.users.updateUserMetadata(formData.get('id') as string, { publicMetadata: { role: formData.get('role') }, }) return { message: res.publicMetadata } } catch (err) { return { message: err } } } export async function removeRole(formData: FormData) { const client = await clerkClient() try { const res = await client.users.updateUserMetadata(formData.get('id') as string, { publicMetadata: { role: null }, }) return { message: res.publicMetadata } } catch (err) { return { message: err } } } ``` ## Create a component for searching for users 1. In your `app/admin/` directory, create a `SearchUsers.tsx` file with the following code. The `` component includes a form for searching for users. When submitted, it appends the search term to the URL as a search parameter. Your `/admin` route will then perform a query based on the updated URL. ```tsx {{ filename: 'app/admin/SearchUsers.tsx' }} 'use client' import { usePathname, useRouter } from 'next/navigation' export const SearchUsers = () => { const router = useRouter() const pathname = usePathname() return (
{ e.preventDefault() const form = e.currentTarget const formData = new FormData(form) const queryTerm = formData.get('search') as string router.push(pathname + '?search=' + queryTerm) }} >
) } ``` ## Refactor the admin dashboard With the server action and the search form set up, it's time to refactor the `app/admin/page.tsx`. 1. Replace the code in your `app/admin/page.tsx` file with the following code. It checks whether a search parameter has been appended to the URL by the search form. If a search parameter is present, it queries for users matching the entered term. If one or more users are found, the component displays a list of users, showing their first and last names, primary email address, and current Role. Each user has `Make Admin` and `Make Moderator` buttons, which include hidden inputs for the user ID and Role. These buttons use the `setRole()` server action to update the user's Role. ```tsx {{ filename: 'app/admin/page.tsx' }} import { redirect } from 'next/navigation' import { checkRole } from '@/utils/roles' import { SearchUsers } from './SearchUsers' import { clerkClient } from '@clerk/nextjs/server' import { removeRole, setRole } from './_actions' export default async function AdminDashboard(params: { searchParams: Promise<{ search?: string }> }) { if (!checkRole('admin')) { redirect('/') } const query = (await params.searchParams).search const client = await clerkClient() const users = query ? (await client.users.getUserList({ query })).data : [] return ( <>

This is the protected admin dashboard restricted to users with the `admin` Role.

{users.map((user) => { return (
{user.firstName} {user.lastName}
{ user.emailAddresses.find((email) => email.id === user.primaryEmailAddressId) ?.emailAddress }
{user.publicMetadata.role as string}
) })} ) } ``` ## Finished 🎉 The foundation of a custom RBAC (Role-Based Access Control) system is now set up. Roles are attached directly to the user's session, allowing your application to access them without the need for additional network requests. The `checkRole()` helper function simplifies Role checks and reduces code complexity. The final component is the admin dashboard, which enables admins to efficiently search for users and manage Roles.
--- title: Protect pages in your Nuxt app with Clerk description: Learn how to protect the pages in your Clerk + Nuxt application. sdk: nuxt sdkScoped: "true" canonical: /docs/guides/secure/protect-pages lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: nuxt notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,vue,ruby,js-backend activeSdk: nuxt sourceFile: /docs/guides/secure/protect-pages.mdx --- This guide demonstrates how to protect pages in your Nuxt application. > \[!TIP] > To learn how to protect API routes, see the [dedicated guide](/docs/reference/nuxt/clerk-middleware#protect-api-routes). ## Protect a single page The `useAuth()` composable provides access to the current user's authentication state and methods to manage the active session. It also includes the `isSignedIn` property to check if the active user is signed in, which is helpful for protecting a page. In the following example, the `isLoaded` property checks if Clerk has finished initializing and the `isSignedIn` property checks if the user is signed in in order to protect the page. ```vue {{ filename: 'app/pages/protected-page.vue' }} ``` ## Protect multiple pages The `createRouteMatcher()` is a Clerk helper function that allows you to protect multiple routes in your Nuxt application. It accepts an array of route patterns and checks if the route the user is trying to visit matches one of the patterns passed to it. The `createRouteMatcher()` helper returns a function that, when called with the `to` route object from Nuxt's [`defineNuxtRouteMiddleware()`](https://nuxt.com/docs/4.x/api/utils/define-nuxt-route-middleware), will return `true` if the user is trying to access a route that matches one of the patterns provided. ### Example In your `middleware/` directory, create a file named `auth.global.ts` with the following code. This middleware: * Uses the `isSignedIn` property returned by the useAuth() composable to check if the user is signed in. * Uses the `createRouteMatcher()` helper to check if the user is trying to access a protected route. If they are but they aren't signed in, they are redirected to the sign-in page. ```ts {{ filename: 'app/middleware/auth.global.ts' }} // Define the routes you want to protect with `createRouteMatcher()` const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)']) export default defineNuxtRouteMiddleware((to) => { // Use the `useAuth()` composable to access the `isSignedIn` property const { isSignedIn } = useAuth() // Check if the user is not signed in and is trying to access a protected route // If so, redirect them to the sign-in page if (!isSignedIn.value && isProtectedRoute(to)) { return navigateTo('/sign-in') } }) ``` --- title: XSS leak protection description: Learn how Clerk prevents and mitigates XSS attacks. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/best-practices/xss-leak-protection sourceFile: /docs/guides/secure/best-practices/xss-leak-protection.mdx --- Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS vulnerabilities are incredibly serious and we recommend you reference the [OWASP® Foundation's Cross Site Scripting (XSS) Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html) to learn how you can prevent an attack. Prevention is just one aspect of an effective security model. To prepare for the worst case scenario where an attack is successful, you should ensure your application is configured to minimize the attack's surface area. Clerk works to minimize the surface area by using `HttpOnly` cookies for authenticated requests to our [Frontend API](/docs/reference/frontend-api){{ target: '_blank' }}, so that credentials cannot be leaked during XSS attacks. ## What is a `HttpOnly` cookie? `HttpOnly` is a flag on the [`Set-Cookie`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) header that is issued by a server to set a cookie in the browser. By default, cookies can be accessed via `document.cookie` in JavaScript. When the `HttpOnly` flag is set on a cookie, the cookie is only accessible server-side through HTTP requests. The cookie cannot be accessed by client-side JavaScript code, including attempts to read it via `document.cookie`. This provides an important security boundary between client and server-side cookie access. ## How do `HttpOnly` cookies minimize XSS attacks? During an XSS attack, malicious JavaScript can execute in users' browsers. If session tokens are stored in JavaScript-accessible locations like `localStorage` or non-HttpOnly cookies, the attacker can steal these tokens and impersonate users even after the XSS vulnerability is fixed. If this happens, it is recommended you invalidate existing tokens and force users to sign in again. By using `HttpOnly` cookies, Clerk ensures session tokens cannot be accessed by JavaScript, protecting them from XSS attacks. For maximum security, avoid storing session tokens in JavaScript-accessible locations like: * Cookies without the `HttpOnly` flag * [Window.localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) * [Window.sessionStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage) * [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) ## Why is the `__session` cookie on my application domain not `HttpOnly`? The `__session` cookie contains the session token and it is dropped by Clerk to your application's root domain (e.g. `example.com`). It is not `HttpOnly` because it needs to be accessible by Clerk's client-side SDKs. However, for this reason, the token contained in this cookie is short-lived (1 minute lifetime), so as to mitigate any potential XSS attacks. Read more about the `__session` and `__client` cookies in the [guide on how Clerk works](/docs/guides/how-clerk-works/overview#clerks-cookies-and-tokens-in-detail). --- title: Unauthorized sign-in description: Notify users of unauthorized sign-ins to their accounts lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/best-practices/unauthorized-sign-in sourceFile: /docs/guides/secure/best-practices/unauthorized-sign-in.mdx --- Clerk detects sign-in attempts from unrecognized devices to protect users from unauthorized access to their accounts. This security feature helps identify potentially malicious sign-in activity. ## Email notification for unauthorized access When a sign-in attempt is made from an unfamiliar device, Clerk notifies the account owner by email with details about the newly created session. The email notification varies depending on the instance's configuration and the application's billing plan. By default, the email includes information about the unauthorized sign-in attempt, such as device type, operating system, IP address, location, and the sign-in method used. If you've set a support email for your app, Clerk will add instructions for the user to contact the app administrator. For supported instances, the email might also include a button that allows users to sign out from the unrecognized device. Selecting this button immediately revokes the session. To customize the unauthorized sign-in email notification: 1. In the Clerk Dashboard, navigate to the [**Emails**](https://dashboard.clerk.com/~/customization/email) page. 2. Select **Sign in from new device**. You'll be redirected to the template settings page. 3. Edit the email template. 4. Select **Apply changes**. ## Revoke sessions for unauthorized sign-ins > \[!WARNING] > This feature requires a [paid plan](/pricing){{ target: '_blank' }} for production use, but all features are free to use in development mode so that you can try out what works for you. See the [pricing](/pricing){{ target: '_blank' }} page for more information. For apps that support this feature, users can immediately revoke unauthorized sign-ins directly from the email notification. With a single click, the suspicious session is revoked and the user is redirected to a confirmation page. The confirmation page depends on the instance configuration: * [Account Portal](/docs/guides/customizing-clerk/account-portal) enabled: The user is redirected to the [unauthorized sign-in](/docs/guides/customizing-clerk/account-portal#unauthorized-sign-in) page, where content can be customized based on the app's theme. * Account Portal disabled: The user sees a plain text confirmation of the successful session revocation. In either case, after revoking the session, users must sign in again unless they have an active session on their device. To customize the URL path of the unauthorized sign-in page: 1. In the Clerk Dashboard, navigate to the [**Paths**](https://dashboard.clerk.com/~/paths) page. 2. Under **Application paths**, enter the **Unauthorized sign in URL** path. 3. Select **Save**. --- title: Protect email link sign-ins and sign-ups description: Learn how to protect email link sign-ins and sign-ups. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/best-practices/protect-email-links sourceFile: /docs/guides/secure/best-practices/protect-email-links.mdx --- Clerk provides an additional setting to improve security for email link sign-ins and sign-ups. When this setting is enabled, only email links opened on the same device and browser that a sign-in or sign-up was initiated on will successfully authenticate the user. Enabling this protection means that the following scenario cannot happen: 1. A malicious actor knows the email of a user and requests an email link to sign-in or sign-up. 2. The user opens the email and visits the link, or the user's email provider follows links in emails for phishing or spam protection. 3. The malicious actor is able to gain access to the user's account because the email link has been opened successfully. Disabling this protection means that your users are vulnerable to the scenario above, but they will be able to sign-in or sign-up with email link across devices and browsers. For example, initiating an email link sign in on a laptop and then opening the email link on a phone to sign in successfully. With same device and browser protection on, users will see the following warning if an email link for sign-in or sign-up was opened on a different device or browser: ![Error message displayed if email link is opened in a different device or browser if email link same device/browser protection is enabled](/docs/images/security/email-link_require-same-client.webp) To configure this security setting, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page in the Clerk Dashboard and ensure that under the **Sign-in with email** section, the **Email verification link** option is enabled. --- title: Fixation protection description: Session fixation is an attack that permits an attacker to hijack a valid user session. The attack explores a limitation in the way the web application manages the session ID, more specifically the vulnerable web application. When authenticating a user, it doesn’t assign a new session ID, making it possible to use an existent session ID. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/best-practices/fixation-protection sourceFile: /docs/guides/secure/best-practices/fixation-protection.mdx --- Session fixation is a security vulnerability that allows an attacker to hijack a valid user session. This vulnerability arises when web applications reuse existing session IDs instead of generating new ones during the authentication process. By exploiting this flaw, attackers can potentially gain unauthorized access to a user's account and perform malicious actions on their behalf. See the [OWASP Session Fixation](https://owasp.org/www-community/attacks/Session_fixation) page for specific examples of how this attack works. ## How does Clerk protect against session fixation? Clerk resets the session token each time a user signs in or out of a browser. When the session is reset, the old session token is invalidated and can no longer be used for authentication. --- title: CSRF protection description: CSRF is an attack that tricks the victim into submitting a malicious request. It inherits the identity and privileges of the victim to perform an undesired function on the victim’s behalf. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/best-practices/csrf-protection sourceFile: /docs/guides/secure/best-practices/csrf-protection.mdx --- Cross Site Request Forgery (CSRF) is an attack that deceives a victim into submitting a malicious request. The attack inherits the victim's identity and privileges to perform an undesired action on the their behalf. For most sites, browser requests automatically include credentials associated with the site, such as the user's session cookie, IP address, Windows domain credentials, and more. Therefore, if the user is currently authenticated, the site cannot distinguish between a forged request initiated by the attacker and a legitimate request from the user. [The OWASP® Foundation, Cross Site Request Forgery (CSRF)](https://owasp.org/www-community/attacks/csrf) Most CSRF attacks can be protected against by properly configuring the way session tokens are stored. Clerk handles the necessary configuration on your behalf by configuring cookies with the `SameSite` flag. ## What does a CSRF attack look like? Imagine an attacker made a malicious website at `foo.com` that contained the following code: ```html ``` Notice the query string `?action=delete&id=123`. If a user logged into `example.com` loads this page, and `example.com` is configured to execute actions from the query string for authorized users, an attacker could potentially delete the user's account on `example.com` without their knowledge. The user would simply see a webpage with a broken image, which could be easily hidden using CSS. ## How does `SameSite` help prevent CSRF attacks? Fortunately, [the `SameSite` flag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value), which can be added to the `Set-Cookie` header, can prevent CSRF attacks. In the previous example, if the developers of `example.com` set the `SameSite` flag on their session cookies to `Strict` or `Lax`, the browser would not send the cookie with requests to `foo.com`. Therefore, the attack would fail as the user would not be authenticated and the backend would presumably block the delete action. Let's break down what each of the values of `SameSite` do: * `Strict`: The cookie will only be sent with HTTP requests initiated from the same site. While this may seem like the most secure option, it results in users being signed out if they navigate to the site from an external link. Since the cookie is omitted in cross-site requests, this leads to a poor user experience and is generally not recommended when using cookies for authentication. * `Lax`: The cookie will be sent with HTTP requests initiated from the same site, and with direct navigations from a cross-site origin, but not with requests to load resources such as images or frames. This setting still protects against CSRF attacks without the poor user experience issues of `Strict`, where users are signed out when navigating from external links. `Lax` is the default setting in modern browsers and is recommended for most use cases. * `None`: The browser will send cookies for both same-site and cross-site requests. While this setting allows for more flexibility in certain scenarios, it also increases the risk of CSRF attacks and therefore is not recommended. Clerk sets the `SameSite` flag for all of its session cookies to `Lax`, which is the default in modern browsers. ## Do I need to take additional steps to prevent CSRF attacks? You do not, but it is still possible to accidentally make your application vulnerable to XSS attacks. Because Clerk uses the `Lax` setting, it is critical to remember that navigation alone should never trigger a mutation in your backend. Otherwise, the user can be tricked into clicking a link that takes an action they did not intend. --- title: Configure Clerk Content-Security-Policy headers description: Learn how to configure your Content Security Policy to work with the Clerk APIs. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/secure/best-practices/csp-headers sourceFile: /docs/guides/secure/best-practices/csp-headers.mdx --- [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) (CSP) headers secure your document by preventing resources from being loaded from unexpected sources. This protects your apps from [XSS](/docs/guides/secure/best-practices/xss-leak-protection) attacks and data injections. For Clerk to work correctly in your application, the following CSP directives are required: 1. `script-src` - This value should include the host application's FAPI hostname, such as `https://clerk.your-domain.com`, as well as cloudflare's bot protection host, `https://challenges.cloudflare.com`. 2. `connect-src` - This value should include the host application's FAPI hostname, such as `https://clerk.your-domain.com`. 3. `img-src` - This value should be `https://img.clerk.com`. 4. `worker-src` - Use the `'self'` value to indicate that workers can be loaded from first-party scripts. The `blob:` schema value also needs to be included. 5. `style-src` - This value should include `'unsafe-inline'` due to Clerk's usage of runtime CSS-in-JS for styling. 6. `frame-src` - This value should include cloudflare's bot protection host, `https://challenges.cloudflare.com`. There are two ways to configure your CSP headers: 1. [**Automatic CSP configuration**](#automatic-csp-configuration) - **This is available for the Next.js SDK only.** Clerk provides built-in support for automatically injecting CSP headers through middleware. This simplifies the process of setting up a secure CSP that works correctly with Clerk. 2. [**Manual CSP configuration**](#manual-csp-configuration) ## Automatic CSP configuration > \[!WARNING] > Automatic CSP configuration is available only for `@clerk/nextjs >=6.14.0`. Clerk provides built-in support for automatically injecting CSP headers by adding the `contentSecurityPolicy` option to your `clerkMiddleware()`. There are two modes available depending on how strict you want your CSP to be: * [`default` configuration](#default-configuration) * [`strict` configuration](#strict-configuration) ### `default` configuration The `default` configuration will apply the following CSP directives: * `connect-src` - `'self' https://clerk-telemetry.com https://*.clerk-telemetry.com https://api.stripe.com https://maps.googleapis.com https://{{fapi_url}}` * `default-src` - `'self'` * `form-action` - `'self'` * `frame-src` - `'self' https://challenges.cloudflare.com https://*.js.stripe.com https://js.stripe.com https://hooks.stripe.com` * `img-src` - `'self' https://img.clerk.com` * `script-src` - `'self' 'unsafe-inline' https http https://*.js.stripe.com https://js.stripe.com https://maps.googleapis.com` * `style-src` - `'self' 'unsafe-inline'` * `worker-src` - `'self' blob:` > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. ```ts {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)']) export default clerkMiddleware( async (auth, request) => { if (!isPublicRoute(request)) { await auth.protect() } }, { contentSecurityPolicy: {}, }, ) ``` ### `strict` configuration When using the `strict` configuration, Clerk will: 1. Automatically generate a unique nonce for each request. 2. Configure the CSP header with appropriate directives. 3. Make the nonce available to your application through the `x-nonce` header. The middleware will handle passing the nonce to the `` automatically, so you don't need to manually set the `nonce` prop when using server components. ```ts {{ filename: 'proxy.ts' }} import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server' const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)']) export default clerkMiddleware( async (auth, request) => { if (!isPublicRoute(request)) { await auth.protect() } }, { contentSecurityPolicy: { strict: true, }, }, ) ``` > \[!IMPORTANT] > You must pass the dynamic prop to `` for `strict` CSP configuration to work correctly. This is because the nonce value is generated on the server and passed to the client, which requires dynamic rendering. ```tsx {{ filename: 'app/layout.tsx' }} import { ClerkProvider } from '@clerk/nextjs' export default function Layout({ children }) { return ( // When using clerkMiddleware with `strict` configuration, // the nonce is automatically provided. // No need to manually set the `nonce` prop on `` {children} ) } ``` If you need to apply the nonce to custom scripts, you can access it through the headers: ```tsx {{ filename: 'pages/index.tsx' }} import { headers } from 'next/headers' export default function Page() { const nonce = headers().get('x-nonce') return (
`. If you are using Next.js, any scripts loaded through next will automatically have the nonce value injected. With the above middleware, the nonce value is made accessible via the `x-nonce` request header. An example is provided below on how to access this value within a Next.js page. ```tsx {{ filename: 'pages/index.tsx' }} import { headers } from 'next/headers' export default function Page() { const nonce = headers().get('x-nonce') return

{nonce}

} ``` If you're using one of Clerk's React-based SDKs, in order for Clerk to load correctly, the nonce value must also be passed to the `` component. This can be done by passing the nonce value as a `nonce` prop to the `` component. For example: > \[!IMPORTANT] > You must pass the dynamic prop to `` for `strict-dynamic` CSPs to work correctly. This is because the nonce value is generated on the server and passed to the client, which requires dynamic rendering. ```tsx {{ filename: 'app/layout.tsx' }} import { ClerkProvider } from '@clerk/nextjs' import { headers } from 'next/headers' export default function Layout({ children }) { return ( // Note: since this is server-rendered, you don't _need_ to pass the nonce, see note below {children} ) } ``` If you are using Next.js and your layout file is rendered on the server (as is the case with the example above), Clerk's SDK will automatically read the `nonce` from the request and pass it into ``. **If you are rendering the provider on the client**, you will need to explicitly pass the `nonce` value to the client and into ``. --- title: Customize your session token description: Learn how to customize the session token that is generated for you by Clerk. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/sessions/customize-session-tokens sourceFile: /docs/guides/sessions/customize-session-tokens.mdx --- Session tokens are JWTs generated by Clerk on behalf of your instance, and convey an authenticated user session to your backend. By default, session tokens contain claims that are required for Clerk to function. You can learn more about these "default claims" in the [session tokens](/docs/guides/sessions/session-tokens) documentation. This guide will show you how to customize a session token to include additional claims that you may need in your application. > \[!CAUTION] > Clerk stores the session token in a cookie, and most browsers cap cookie size at [**4KB**](https://datatracker.ietf.org/doc/html/rfc2109#section-6.3). After accounting for the size of Clerk's default claims, the cookie can support **up to 1.2KB** of custom claims. Exceeding this limit will cause the cookie to not be set, which will break your app as Clerk depends on cookies to work properly. [Learn more](/docs/guides/sessions/session-tokens#size-limitations). ## Add custom claims to your session token 1. In the Clerk Dashboard, navigate to the [**Sessions**](https://dashboard.clerk.com/~/sessions) page. 2. Under **Customize session token**, in the **Claims** editor, you can add any claim to your session token that you need and select **Save**. The following example adds the `fullName` and `primaryEmail` claims to the session token. ![Clerk Dashboard showing the custom claim modal](/docs/images/custom-session-token/example.png) ## Use the custom claims in your application The Auth object includes a `sessionClaims` property that contains the custom claims you added to your session token. **Accessing the `Auth` object differs depending on the SDK you're using. See the reference doc for more information.** The following example demonstrates how to access the `fullName` and `primaryEmail` claims that were added to the session token in the last step. For Next.js, the `Auth` object is accessed using the `auth()` helper in App Router apps and the `getAuth()` function in Pages Router apps. Learn more about using these helpers. ```tsx {{ filename: 'app/api/example/route.tsx' }} import { auth } from '@clerk/nextjs/server' import { NextResponse } from 'next/server' export async function GET() { // Use `auth()` to access the user's session claims const { isAuthenticated, sessionClaims } = await auth() if (!isAuthenticated) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } const fullName = sessionClaims.fullName const primaryEmail = sessionClaims.primaryEmail return NextResponse.json({ fullName, primaryEmail }) } ``` ```tsx {{ filename: 'pages/api/example.ts' }} import { getAuth } from '@clerk/nextjs/server' import type { NextApiRequest, NextApiResponse } from 'next' export default async function handler(req: NextApiRequest, res: NextApiResponse) { // Use `getAuth()` to access the user's session claims const { isAuthenticated, sessionClaims } = getAuth(req) if (!isAuthenticated) { return res.status(401).json({ error: 'Unauthorized' }) } const fullName = sessionClaims.fullName const primaryEmail = sessionClaims.primaryEmail return res.status(200).json({ fullName, primaryEmail }) } ``` For Astro, the `Auth` object is accessed using the `locals.auth()` function. Learn more about using `locals.auth()`. ```tsx {{ filename: 'src/api/example.ts' }} import type { APIRoute } from 'astro' export const GET: APIRoute = async ({ locals }) => { // Use `locals.auth()` to access the user's session claims const { isAuthenticated, sessionClaims } = await locals.auth() if (!isAuthenticated) { return new Response('Unauthorized', { status: 401 }) } const fullName = sessionClaims.fullName const primaryEmail = sessionClaims.primaryEmail return new Response(JSON.stringify({ fullName, primaryEmail })) } ``` For Express, the `Auth` object is accessed using the `getAuth()` function. Learn more about using `getAuth()`. ```js import { clerkMiddleware, getAuth, requireAuth } from '@clerk/express' import express from 'express' const app = express() const PORT = 3000 // Apply `clerkMiddleware()` to all routes app.use(clerkMiddleware()) const getSessionClaims = (req, res, next) => { // Use `getAuth()` to access the user's session claims const { isAuthenticated, sessionClaims } = getAuth(req) if (!isAuthenticated) { return res.status(401).json({ error: 'Unauthorized' }) } const fullName = sessionClaims.fullName const primaryEmail = sessionClaims.primaryEmail return res.status(200).json({ fullName, primaryEmail }) } app.get('/profile', requireAuth(), getSessionClaims) app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`) }) ``` For Go, the session claims are accessed using the [`SessionClaimsFromContext()`](https://pkg.go.dev/github.com/clerk/clerk-sdk-go/v2#SessionClaimsFromContext) function. ```go {{ filename: 'main.go' }} package main import ( "context" "fmt" "net/http" "github.com/clerk/clerk-sdk-go/v2" clerkhttp "github.com/clerk/clerk-sdk-go/v2/http" "github.com/clerk/clerk-sdk-go/v2/user" ) type CustomSessionClaims struct { FullName string `json:"fullName"` PrimaryEmail string `json:"primaryEmail"` } func customClaimsConstructor(ctx context.Context) any { return &CustomSessionClaims{} } func WithCustomClaimsConstructor(params *clerkHttp.AuthorizationParams) error { params.VerifyParams.CustomClaimsConstructor = customClaimsConstructor return nil } func main() { clerk.SetKey("{{secret}}") mux := http.NewServeMux() protectedHandler := http.HandlerFunc(protectedRoute) mux.Handle( "/protected", clerkhttp.WithHeaderAuthorization(WithCustomClaimsConstructor)(protectedHandler), ) http.ListenAndServe(":3000", mux) } func protectedRoute(w http.ResponseWriter, r *http.Request) { // Protect the route by checking if the session claims are present claims, ok := clerk.SessionClaimsFromContext(r.Context()) if !ok { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } // Access the custom claims customClaims, ok := claims.Custom.(*CustomSessionClaims) if !ok { // Handle the error how you see fit } else { fmt.Fprintf(w, `{"full_name": "%s", "primary_email": "%s"}`, customClaims.FullName, customClaims.PrimaryEmail) } } ``` For React Router, the `Auth` object is accessed using the `getAuth()` function. Learn more about using `getAuth()`. ```tsx {{ filename: 'app/routes/profile.tsx' }} import { redirect } from 'react-router' 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, sessionClaims } = await getAuth(args) if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } const fullName = sessionClaims.fullName const primaryEmail = sessionClaims.primaryEmail return { fullName: JSON.stringify(fullName), primaryEmail: JSON.stringify(primaryEmail), } } export default function Profile({ loaderData }: Route.ComponentProps) { return (

Welcome {loaderData.fullName}

Your email is {loaderData.primaryEmail}

) } ```
For Tanstack React Start, the `Auth` object is accessed using the `getAuth()` function. Learn more about using `getAuth()`. ```ts {{ filename: 'src/routes/api/example.ts' }} import { auth } from '@clerk/tanstack-react-start/server' import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { GET: async () => { // Use `auth()` to access the user's session claims const { isAuthenticated, sessionClaims } = await auth if (!isAuthenticated) { return json({ error: 'Unauthorized' }, { status: 401 }) } const fullName = sessionClaims.fullName const primaryEmail = sessionClaims.primaryEmail return json({ fullName, primaryEmail }) }, }, }, }) ```
## Add global TypeScript type for custom session claims To get auto-complete and prevent TypeScript errors when working with custom session claims, you can define a global type. 1. In your application's root folder, add a `types` directory. 2. Inside of the `types` directory, add a `globals.d.ts` file. 3. Create the `CustomJwtSessionClaims` interface and declare it globally. 4. Add the custom claims to the `CustomJwtSessionClaims` interface. The following example demonstrates how to add the `fullName` and `primaryEmail` claims to the `CustomJwtSessionClaims` interface. ```tsx {{ filename: 'types/globals.d.ts' }} export {} declare global { interface CustomJwtSessionClaims { fullName?: string primaryEmail?: string } } ```
--- title: Force a session token refresh description: Learn how to force a refresh of a user's session token in your Clerk application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/sessions/force-token-refresh sourceFile: /docs/guides/sessions/force-token-refresh.mdx --- A user's session token is a short-lived JWT that Clerk [refreshes every 60 seconds](/docs/guides/how-clerk-works/overview#token-refresh-mechanism). However, there are some cases where you might want to force a refresh. For example, if you're retrieving information from the session token that has been updated but the token hasn't refreshed yet, the information is still old and you'll need to force the token to refresh. There are two recommended approaches to force a user's session token to refresh: * [`getToken({ skipCache: true })`](#get-token-skip-cache-true) * [`user.reload()`](#user-reload) Both perform a network request, but `getToken({ skipCache: true })` will only get a new token, while `user.reload()` will both get a new token and a new `User` object. ## `getToken({ skipCache: true })` The `getToken()` method retrieves the current user's session token. If `skipCache` is set to `true`, it will force a new token to be minted. The `skipCache` property is only available on the client-side. To access `getToken()` from the client-side, use the useSession() or useAuth() hooks. ### Example Say you're building a user profile page and want to allow the user to set their birthday, but Clerk doesn't collect birthdays. To store information about a user that Clerk doesn't collect, you can use [metadata](/docs/guides/users/extending), which will get stored on the user's `User` object. When using metadata, it's recommended to [store it in the user's session token](/docs/guides/sessions/customize-session-tokens) to avoid making an API request to Clerk's Backend API when retrieving it, as API requests are slower and are subject to rate limits. However, when retrieving the user's metadata from the session token, because the session token refreshes every 60 seconds, the metadata may not be up to date if the token hasn't refreshed yet. In this case, you'd want to force a session token refresh after updating the metadata to ensure that when the metadata is retrieved, it is the latest version. **This example requires that the user's birthday has been configured to be stored in the session token** like: ```json { "birthday": "{{user.public_metadata.birthday}}" } ``` To do so, follow the [guide on customizing your session token](/docs/guides/sessions/customize-session-tokens). The `/update-user-metadata` API route uses Clerk's updateUserMetadata() method from the JS Backend SDK to update the user's birthday metadata. ```ts {{ filename: 'app/api/update-user-metadata/route.ts', collapsible: true }} import { auth, clerkClient } from '@clerk/nextjs/server' import { NextRequest, NextResponse } from 'next/server' export async function POST(req: NextRequest) { // Use `req.json()` to parse the request body const { birthday } = await req.json() // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await auth() // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ error: 'Unauthorized' }, { status: 401 }) } // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const client = await clerkClient() // Use the JS Backend SDK's `updateUserMetadata()` method to update the user's birthday await client.users.updateUserMetadata(userId, { publicMetadata: { birthday, }, }) return NextResponse.json({ success: true }, { status: 200 }) } ``` The `/user-profile` page allows the user to update their birthday. It retrieves the user's birthday from the session token's claims under the `birthday` key. To update the user's birthday, it calls the `/update-user-metadata` API route, which handles the metadata update, and then forces a session token refresh using `getToken({ skipCache: true })`. ```tsx {{ filename: 'app/user-profile/page.tsx', collapsible: true }} 'use client' import { useState, useEffect } from 'react' import { useAuth } from '@clerk/nextjs' export default function Page() { // Use `useAuth()` to access the authentication context, // including the user's session claims const { isLoaded, isSignedIn, sessionClaims, getToken } = useAuth() const [birthday, setBirthday] = useState('') const [status, setStatus] = useState<'loading' | 'success' | 'error' | null>(null) const [error, setError] = useState(null) // Update state once the user's data loads useEffect(() => { // Retrieve the user's birthday from the session token's claims under the `birthday` key setBirthday((sessionClaims?.birthday as string) || '') }, [sessionClaims]) async function updateUserBirthday(birthday: string) { try { const response = await fetch('/api/update-user-metadata', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ birthday }), }) const result = await response.json() if (!response.ok) { throw new Error(result.error || 'Failed to update birthday') } // Force token refresh // so that the token is updated with the new birthday metadata await getToken({ skipCache: true }) return { success: true } } catch (err: any) { return { error: err.message || 'Failed to update birthday' } } } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setStatus('loading') setError(null) // Check if the birthday has been modified if (birthday === (sessionClaims?.birthday || '')) { setError('Please enter a new birthday to update') setStatus('error') return } try { const result = await updateUserBirthday(birthday) if (result.error) { setError(result.error) setStatus('error') } else { setStatus('success') } } catch (err: any) { setError(err.message || 'Failed to update birthday') setStatus('error') } } // Check if Clerk has loaded if (!isLoaded) return
Loading...
// Check if the user is authenticated if (!isSignedIn) return
Sign in to view your profile
return (

Update Your Birthday

setBirthday(e.target.value)} />
{status === 'success' &&

Birthday updated successfully!

} {status === 'error' &&

{error}

}
) } ```
## `user.reload()` The `user.reload()` method refreshes the current user's `User` object and their session token. It can be accessed from the useUser() hook. You only need to call `user.reload()` if you've updated the `User` object outside of the `user.update()` method or Clerk hooks; for example, if you made changes through an API endpoint. --- title: Session tokens description: Learn about session tokens and how to validate them in your backend. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/sessions/session-tokens sourceFile: /docs/guides/sessions/session-tokens.mdx --- When a user is authenticated in your application, Clerk generates a short-lived session token that you can use to authenticate requests to your backend. This token is a JSON Web Token (JWT) that contains information about the user and their session. Read more about Clerk session tokens and how they work in [the guide on how Clerk works](/docs/guides/how-clerk-works/overview). ## Default claims > \[!IMPORTANT] > You are reading about version 2 of Clerk's session token claims. To read about version 1, select the respective tab above. Every generated token has default claims that cannot be overridden by templates. Clerk's default claims include: | Claim | Abbreviation expanded | Description | Example | | - | - | - | - | | `azp` | authorized party | The `Origin` header that was included in the original Frontend API request made from the user. Most commonly, it will be the URL of the application. This claim could be omitted if, for privacy-related reasons, `Origin` is empty or null. | `https://example.com` | | `exp` | expiration time | The time after which the token will expire, as a Unix timestamp. Determined using the **Token lifetime** JWT template setting in the [Clerk Dashboard](https://dashboard.clerk.com/~/jwt-templates). See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4) for more information. | `1713158400` | | `fva` | factor verification age | Each item represents the minutes that have passed since the last time a first or second factor, respectively, was verified. | `[7, -1]` which means it has been 7 minutes since the first factor was verified, and there either is not a second factor or the second factor has never been verified. | | `iat` | issued at | The time at which the token was issued as a Unix timestamp. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6) for more information. | `1713158400` | | `iss` | issuer | The Frontend API URL of your instance. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1) for more information. | `https://clerk.your-site.com` for a production instance, `https://your-site.clerk.accounts.dev` for a development instance | | `jti` | JWT ID | The unique identifier for the token. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7) for more information. | `1234567890` | | `nbf` | not before | The time before which the token is considered invalid, as a Unix timestamp. Determined using the **Allowed Clock Skew** JWT template setting in the [Clerk Dashboard](https://dashboard.clerk.com/~/jwt-templates). See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5) for more information. | `1713158400` | | `sid` | session ID | The ID of the current session. | `sess_123` | | `sub` | subject | The ID of the current user of the session. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2) for more information. | `user_123` | | `v` | version | The version number of the session token. | `2` | | `pla` | plan | The Plan that is active. The value is in the format `scope:planslug`, where `scope` can be `u` or `o` representing user or Organization-level Plans, respectively. The `u:` prefix is used if no Organization is active, and the `o:` prefix appears if an Organization is active. | `u:free`,`o:pro` | | `fea` | features | A list of enabled Features and their scope. The scope can either be `o` for Organization-level Features if there is an Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization., or `u` for user-level Features or if there is no active Organization. | `o:dashboard,o:impersonation` | | `sts` | session status | The status of the current session | `pending` | ### Organization claim The **`o` claim**, or Organization claim, is only included if the user is part of an [Organization](/docs/guides/organizations/overview) and that Organization is activeA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Its value is an object that contains the following properties: | Claim | Abbreviation expanded | Description | Example | | | - | - | - | - | - | | `id` | ID | The ID of the Organization. | `org_123` | | | `slg` | slug | The slug of the Organization. | `org-slug` | | | `rol` | role | The Role of the user in the Organization, without the `org:` prefix. | `admin` | | | `per` | permissions | The names of the Permissions the user has in the Organization. | `read,manage` | | | `fpm` | feature-permission map | feature-permission map | The mapping of Features with Permissions. [Learn how this value is constructed](#decode-o-fpm-manually). | `3,2` | > \[!WARNING] > The Organization claims above are intentionally designed to be as compact as possible to keep JWT tokens small. > As a result, they can be difficult to decode manually. We strongly recommend using one of our SDKs that support API version [2025-04-10](/docs/guides/development/upgrading/versioning#2025-04-10) to handle decoding reliably. #### Decode `o.fpm` manually For those that need to decode the `o.fpm` claim manually, here is how the claim value is computed. The `o.fpm` value is a list of comma-separated integers where the position of the integer corresponds to a Feature in the same position in the `fea` claim. So, the first Feature in the `fea` claim corresponds to the first integer in the `o.fpm` claim, and so on. Each integer, when converted to binary, represents a bitmask where each bit's position corresponds to a Permission in the `o.per` list, where `0` = `not-allowed` and `1` = `allowed`. The first bit position in the bitmask is the rightmost, least significant bit. It corresponds to the first Permission in the `o.per` list, which is the leftmost element. This results in a sort of "reverse" mapping, seen in the example below. #### Example Consider a user with an Active Organization has Role `admin`. This Role has the following Feature-Permission mapping: `dashboard:read`, `dashboard:manage`, `teams:read`. Therefore, the user's claims are as follows: * `fea` claim has value `o:dashboard,o:teams` * `o.per` claim has value `manage,read` * `o.fpm` claim has value `3,2` Now, let's manually decode the `o.fpm` claim. The first integer `3` represents the Feature-Permission mapping for the `dashboard` Feature, since it's the first Feature in the `fea` claim. Then, converting `3` to binary, you get `11`, which means both Permissions are allowed (`dashboard:read` and `dashboard:manage`). The second integer `2` represents the Feature-Permission mapping for the `teams` Feature, since it's the second Feature in the `fea` claim. Then, converting `2` to binary, you get `10`, which means the *second* Permission is allowed (`teams:read`). This is because **you read bitmask from right to left**, so the first bit, `0`, corresponds to the first Permission in the `o.per` list (`manage`) and the second bit, `1`, corresponds to the second Permission in the `o.per` list (`read`). ### Actor claim The **`act` (actor) claim** is only included if the user is [impersonating](/docs/guides/users/impersonation) another user. It's value is an object that contains the following properties: | Claim | Abbreviation expanded | Description | Example | | - | - | - | - | | `iss` | issuer | The referrer of the token. | `https://dashboard.clerk.com` | | `sid` | session ID | The session ID of the impersonated session. | `sess_456` | | `sub` | subject | The ID of the impersonator. | `user_456` | > \[!IMPORTANT] > Version 1 was deprecated on April 14, 2025. To upgrade to version 2, go to the [**Updates**](https://dashboard.clerk.com/~/updates) page in the Clerk Dashboard. Every generated token has default claims that cannot be overridden by templates. Clerk's default claims include: | Claim | Abbreviation expanded | Description | Example | | - | - | - | - | | `azp` | authorized party | The `Origin` header that was included in the original Frontend API request made from the user. Most commonly, it will be the URL of the application. This claim could be omitted if, for privacy-related reasons, `Origin` is empty or null. | `https://example.com` | | `exp` | expiration time | The time after which the token will expire, as a Unix timestamp. Determined using the **Token lifetime** JWT template setting in the [Clerk Dashboard](https://dashboard.clerk.com/~/jwt-templates). See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4) for more information. | `1713158400` | | `fva` | factor verification age | Each item represents the minutes that have passed since the last time a first or second factor, respectively, was verified. | `[7, -1]` which means it has been 7 minutes since the first factor was verified, and there either is not a second factor or the second factor has never been verified. | | `iat` | issued at | The time at which the token was issued as a Unix timestamp. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6) for more information. | `1713158400` | | `iss` | issuer | The Frontend API URL of your instance. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1) for more information. | `https://clerk.your-site.com` for a production instance, `https://your-site.clerk.accounts.dev` for a development instance | | `nbf` | not before | The time before which the token is considered invalid, as a Unix timestamp. Determined using the **Allowed Clock Skew** JWT template setting in the [Clerk Dashboard](https://dashboard.clerk.com/~/jwt-templates). See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5) for more information. | `1713158400` | | `sid` | session ID | The ID of the current session. | `sess_123` | | `sub` | subject | The ID of the current user of the session. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2) for more information. | `user_123` | The following claims are only included if the user is part of an Organization and that Organization is activeA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.: | Claim | Abbreviation expanded | Description | Example | | - | - | - | - | | `org_id` | Organization ID | The ID of the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. that the user belongs to. | `org_123` | | `org_permissions` | Organization Permissions | The Permissions of the user in the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. System Permissions are not included in the session token. | `["org:admin:example_permission", "org:member:example_permission"]` | | `org_slug` | Organization Slug | The slug of the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. that the user belongs to. | `org-slug` | | `org_role` | Organization Role | The role of the user in the currently Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. | `org:admin` | The **`act` (actor) claim** is only included if the user is [impersonating](/docs/guides/users/impersonation) another user. It's value is an object that contains the following properties: | Claim | Abbreviation expanded | Description | Example | | - | - | - | - | | `iss` | issuer | The referrer of the token. | `https://dashboard.clerk.com` | | `sid` | session ID | The session ID of the impersonated session. | `sess_456` | | `sub` | subject | The ID of the impersonator. | `user_456` | If you would like to add custom claims to your session token, you can [customize it](/docs/guides/sessions/customize-session-tokens). You can also create custom tokens using a [JWT template](/docs/guides/sessions/jwt-templates). ## Size limitations Clerk stores the session token in a cookie, and [**most browsers limit cookie size to 4KB**](https://datatracker.ietf.org/doc/html/rfc2109#section-6.3). Exceeding this limit will cause the cookie to not be set, which will break your app as Clerk depends on cookies to work properly. A session token with the [default session claims](#default-claims) won't run into this issue, as this configuration produces a cookie significantly smaller than 4kb. However, this limitation becomes relevant when implementing a [custom session token](/docs/guides/sessions/customize-session-tokens). In this case, it's recommended to move particularly large claims out of the token and fetch these using a separate API call from your backend. Claims to monitor for size limits: * `user.organizations` * `user.public_metadata` * `user.unsafe_metadata` * `org.public_metadata` * `org_membership.public_metadata` If you add any of these custom claims in your token, use caution to ensure the stored data doesn't exceed the size limit. It's highly recommended to [store the extra data in your own database](/docs/guides/development/webhooks/syncing#storing-extra-user-data) instead of storing it in metadata in the session token. If this isn't an option, you can [move particularly large claims like these out of the token](#example) and fetch them using a separate API call from your backend. > \[!NOTE] > If your application encounters this issue, the Clerk Dashboard will display a warning: **"Some users are exceeding cookie size limits"**. To resolve this, update your [custom session token](/docs/guides/sessions/customize-session-tokens). ### Example It's recommended to keep the total size of custom claims in the session token under 1.2KB. The following example shows how to move particularly large claims out of the session token and fetch them using a separate API call from your backend. The limitations of this approach are that if you make this call to Clerk's Backend API frequently, you risk hitting [rate limits](/docs/guides/how-clerk-works/system-limits) and it's also slower than making a database query. We highly recommend [storing the extra data in your own database](/docs/guides/development/webhooks/syncing#storing-extra-user-data) instead of storing it in metadata in the session token. For example, if you were storing several fields in `user.public_metadata`, like this: ```js {{ prettier: false }} // user.public_metadata { onboardingComplete: true, birthday: '2000-01-01', country: 'Canada', bio: 'This is a bio -- imagine it is 6kb of written info', } ``` Instead of storing all of that data in the session token, and possibly exceeding the 1.2KB limit, like this: ```json // Custom claims in the session token { "metadata": "{{user.public_metadata}}" } ``` You could store only the necessary data in the session token - for example, just the `onboardingComplete` field - like this: ```json // Custom claims in the session token { "onboardingComplete": "{{user.public_metadata.onboardingComplete}}" } ``` Then, when you need to access the other metadata fields, you can fetch them using a separate API call from your backend. The following example uses the getUser() method to access the current user's Backend `User` object, which includes the `publicMetadata` field. **If your SDK isn't listed, you can use the comments in the example to help you adapt it to your SDK.** ```tsx {{ filename: 'app/api/example/route.ts' }} import { auth, clerkClient } from '@clerk/nextjs/server' export async function GET() { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await auth() // Protect the route by checking if the user is signed in if (!isAuthenticated) { return new NextResponse('Unauthorized', { status: 401 }) } // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const client = await clerkClient() // Use the`getUser()` method to get the Backend User object const user = await client.users.getUser(userId) // Return the Backend User object return NextResponse.json({ user: user }, { status: 200 }) } ``` ```tsx {{ filename: 'pages/api/auth.ts' }} import { getAuth, clerkClient } from '@clerk/nextjs/server' import type { NextApiRequest, NextApiResponse } from 'next' export default async function handler(req: NextApiRequest, res: NextApiResponse) { // Use `getAuth()` to access `isAuthenticated` and the user's ID const { isAuthenticated, userId } = getAuth(req) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return res.status(401).json({ error: 'Unauthorized' }) } // Initialize the JS Backend SDK const client = await clerkClient() // Get the user's full Backend User object const user = await client.users.getUser(userId) return res.status(200).json({ user }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import { clerkClient } from '@clerk/astro/server' export async function GET(context) { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = context.locals.auth() // Protect the route by checking if the user is signed in if (!isAuthenticated) { return new Response('Unauthorized', { status: 401 }) } // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart // Use the `getUser()` method to get the Backend User object const user = await clerkClient(context).users.getUser(userId) // Return the Backend User object return new Response(JSON.stringify({ user })) } ``` ```js {{ filename: 'index.js' }} import { createClerkClient, getAuth } from '@clerk/express' import express from 'express' const app = express() const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) app.get('/user', async (req, res) => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = getAuth(req) // Protect the route by checking if the user is signed in if (!isAuthenticated) { res.status(401).json({ error: 'User not authenticated' }) } // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart // Use the `getUser()` method to get the Backend User object const user = await clerkClient.users.getUser(userId) // Return the Backend User object res.json(user) }) ``` ```tsx {{ filename: 'app/routes/profile.tsx' }} import { redirect } from 'react-router' import { clerkClient, getAuth } from '@clerk/react-router/server' import type { Route } from './+types/profile' export async function loader(args: Route.LoaderArgs) { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await getAuth(args) // Protect the route by checking if the user is signed in if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart // Use the `getUser()` method to get the Backend User object const user = await clerkClient(args).users.getUser(userId) // Return the Backend User object return { user: JSON.stringify(user), } } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { json } from '@tanstack/react-start' import { createFileRoute } from '@tanstack/react-router' import { auth, clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { GET: async () => { // The `Auth` object gives you access to properties like `isAuthenticated` and `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { isAuthenticated, userId } = await auth() if (!isAuthenticated) { return new Response('User not authenticated', { status: 404, }) } // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart // Use the `getUser()` method to get the Backend User object const user = await clerkClient().users.getUser(userId) // Return the Backend User object return json({ user }) }, }, }, }) ``` ## Validate session tokens If you're using the middleware provided by our Clerk SDKs, validating session tokens is handled automatically in every request. If you're not using the middleware, you can still use the respective helpers provided by the SDKs to validate the tokens. To learn how to manually verify a session token, refer to the [dedicated guide](/docs/guides/sessions/manual-jwt-verification). --- title: Manual JWT verification description: Learn how to manually verify Clerk-generated session tokens (JWTs). lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/sessions/manual-jwt-verification sourceFile: /docs/guides/sessions/manual-jwt-verification.mdx --- Your Clerk-generated [session tokens](/docs/guides/sessions/session-tokens) are essentially JWTs which are signed using your instance's private key and can be verified using your instance's public key. Depending on your architecture, these tokens will be in your backend requests either via a cookie named `__session` or via the Authorization header. For every request, you must validate the token to ensure it hasn't expired or been tampered with (i.e., it's authentic and secure). If these validations succeed, then the user is authenticated to your application and should be considered signed in. The `authenticateRequest()` method from the JS Backend SDK handles these validations for you. Alternatively, you can manually verify the token without using the SDK. See the following sections for more information. ## Use `authenticateRequest()` to verify a session token The authenticateRequest() method from the JS Backend SDK accepts the `request` object and authenticates the session token in it. The following example uses the `authenticateRequest()` method to verify the session token. *It also performs networkless authentication* by passing `jwtKey`. This verifies if the user is signed into the application. `authenticateRequest()` requires `publishableKey` to be set. If you are importing `clerkClient` from a higher-level SDK, such as Next.js, then `clerkClient` infers the `publishableKey` from your [environment variables](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys). ```tsx {{ filename: 'app/api/example/route.ts' }} import { clerkClient } from '@clerk/nextjs/server' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const client = await clerkClient() export async function GET(req: Request) { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await client.authenticateRequest(req, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` ```tsx {{ filename: 'src/api/example.ts' }} import { clerkClient } from '@clerk/astro/server' import type { APIRoute } from 'astro' export const GET: APIRoute = async (context) => { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await clerkClient(context).authenticateRequest(context.request, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` ```js {{ filename: 'index.js' }} import { createClerkClient } from '@clerk/express' import express from 'express' const app = express() const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) app.get('/user', async (req, res) => { const { isAuthenticated } = await clerkClient.authenticateRequest(req, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) if (!isAuthenticated) { res.status(401).json({ error: 'User not authenticated' }) } // Add logic to perform protected actions // Return the Backend User object res.json({ message: 'This is a reply' }) }) ``` If you are using the JS Backend SDK on its own, you need to provide the `secretKey` and `publishableKey` to `createClerkClient()` so that it is passed to `authenticateRequest()`. You can set these values as [environment variables](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys) and then pass them to the function. ```tsx import { createClerkClient } from '@clerk/backend' // Initialize the JS Backend SDK // This varies depending on the SDK you're using // https://clerk.com/docs/js-backend/getting-started/quickstart const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY, publishableKey: process.env.CLERK_PUBLISHABLE_KEY, }) export async function GET(req: Request) { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await clerkClient.authenticateRequest(req, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) // Protect the route from unauthenticated users if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` ```tsx {{ filename: 'app/routes/example.tsx' }} import { redirect } from 'react-router' import { clerkClient } from '@clerk/react-router/server' import type { Route } from './+types/example' export async function loader(args: Route.LoaderArgs) { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await clerkClient(args).authenticateRequest(args.request, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) if (!isAuthenticated) { return redirect('/sign-in?redirect_url=' + args.request.url) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) } ``` ```tsx {{ filename: 'app/routes/api/example.tsx' }} import { createFileRoute } from '@tanstack/react-router' import { clerkClient } from '@clerk/tanstack-react-start/server' export const ServerRoute = createFileRoute('/api/example')({ server: { handlers: { GET: async ({ request }) => { // Use the `authenticateRequest()` method to verify the token const { isAuthenticated } = await clerkClient().authenticateRequest(request, { authorizedParties: ['https://example.com'], jwtKey: process.env.CLERK_JWT_KEY, }) if (!isAuthenticated) { return Response.json({ status: 401 }) } // Add logic to perform protected actions return Response.json({ message: 'This is a reply' }) }, }, }, }) ``` ## Manually verify a session token ### Retrieve the session token Retrieve the session token from either `__session` cookie for a same-origin request or from the `Authorization` header for cross-origin requests. ### Get your instance's public key Use one of the three ways to obtain your public key: 1. Use the Backend API in JSON Web Key Set (JWKS) format at the following endpoint [https://api.clerk.com/v1/jwks](/docs/reference/backend-api/tag/jwks/get/jwks){{ target: '_blank' }}. 2. Use your **Frontend API URL** in JWKS format, also known as the **JWKS URL**. The format is your Frontend API URL with `/.well-known/jwks.json` appended to it. Your **Frontend API URL** or **JWKS URL** can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. 3. Use your **JWKS Public Key**, which can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ### Verify the token signature To verify the token signature: 1. Verify that the token's algorithm has the expected value. 2. Use your instance's public key to verify the token's signature. 3. Validate that the token isn't expired by checking the `exp` ([expiration time](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4)) and `nbf` ([not before](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5)) claims. 4. Validate that the `azp` (authorized parties) claim equals any of your known origins permitted to generate those tokens. For better security, it's highly recommended to explicitly set the `authorizedParties` option when authorizing requests. The value should be a list of domains allowed to make requests to your application. Not setting this value can open your application to [CSRF attacks](https://owasp.org/www-community/attacks/csrf). For example, if you're permitting tokens retrieved from `http://localhost:3000`, then the `azp` claim should equal `http://localhost:3000`. You can also pass an array of strings, such as `['http://localhost:4003', 'https://clerk.dev']`. If the `azp` claim doesn't exist, you can skip this step. ### Optional: Check for a `sts` claim If you are using Clerk's [Organizations](/docs/guides/organizations/overview) feature and [have not enabled Personal Accounts](/docs/guides/organizations/overview#allow-personal-accounts), users are *required to be part of an Organization before accessing your application*. If the user has completed registration, but is not yet part of an Organization, a valid session token will be created, but the token will contain a `sts` (status) claim set to `pending`. You may want to reject requests to your backend with pending statuses to ensure that users are not able to work around the Organization requirement. ### Finished If the above process succeeds, the user is considered signed in to your application and authenticated. You can also retrieve the session ID and user ID from of the token's claims. ### Example The following example manually verifies a session token. ```tsx import Cookies from 'cookies' import jwt from 'jsonwebtoken' export default async function (req: Request, res: Response) { // Your public key should be set as an environment variable const publicKey = process.env.CLERK_PEM_PUBLIC_KEY // Retrieve session token from either `__session` cookie for a same-origin request // or from the `Authorization` header for cross-origin requests const cookies = new Cookies(req, res) const tokenSameOrigin = cookies.get('__session') const tokenCrossOrigin = req.headers.authorization if (!tokenSameOrigin && !tokenCrossOrigin) { res.status(401).json({ error: 'Not signed in' }) return } try { let decoded const options = { algorithms: ['RS256'] } // The algorithm used to sign the token. const permittedOrigins = ['http://localhost:3000', 'https://example.com'] // Replace with your permitted origins if (tokenSameOrigin) { decoded = jwt.verify(tokenSameOrigin, publicKey, options) } else { decoded = jwt.verify(tokenCrossOrigin, publicKey, options) } // Validate the token's expiration (exp) and not before (nbf) claims const currentTime = Math.floor(Date.now() / 1000) if (decoded.exp < currentTime || decoded.nbf > currentTime) { throw new Error('Token is expired or not yet valid') } // Validate the token's authorized party (azp) claim if (decoded.azp && !permittedOrigins.includes(decoded.azp)) { throw new Error("Invalid 'azp' claim") } res.status(200).json({ sessionToken: decoded }) } catch (error) { res.status(400).json({ error: error.message, }) } } ``` --- title: JWT templates description: Learn how to create custom JWT templates to generate JSON Web Tokens with Clerk. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/sessions/jwt-templates sourceFile: /docs/guides/sessions/jwt-templates.mdx --- > \[!WARNING] > This guide is for creating custom JWT templates in order to generate JSON Web Tokens with Clerk. If you are looking for how to customize your Clerk-generated session token, refer to the [Customize your session token](/docs/guides/sessions/customize-session-tokens) guide. Clerk offers the ability to generate [JSON Web Tokens](https://en.wikipedia.org/wiki/JSON_Web_Token) (JWTs). Each JWT, or token, represents a user that is currently signed in to your application. You can control the claims that will go into these tokens by creating custom **JWT templates** that fit your needs. This enables you to integrate with any third-party services that support authentication with JWTs. An example use case is integrating with a third-party service that is able to consume JWTs, but requires them to be in a particular format. > \[!WARNING] > When using custom JWTs, there may be increased latency in token generation due to the additional processing required to fetch and include the custom claim data. ## What is a JWT template? **JWT templates** are essentially JSON objects that specify claims to be included in the generated tokens, along with their respective values. Claim values can be either static or dynamic. Static values can be any of the regular JSON data types (strings, numbers, booleans, arrays, objects, null) and will be included as-is in the tokens. Dynamic values, also called **shortcodes**, are special strings that will be substituted for their actual values when the tokens are generated. Read more in the [Shortcodes](#shortcodes) section. The following example shows a template that demonstrates both static values and shortcodes. In this example, the values of the `aud` and `interests` claims are static, and the values of the `name` and `email` claims are dynamic. ```json { "aud": "https://example.com", "interests": ["hiking", "knitting"], "name": "{{user.first_name}}", "surname": "{{user.last_name}}", "email": "{{user.primary_email_address}}" } ``` A token generated using the template above would look something like this: ```json { "aud": "https://example.com", "interests": ["hiking", "knitting"], "name": "John", "surname": null, "email": "john@doe.org" // ...plus some automatically-included claims // See the following section section for more information } ``` ### Default claims In every generated token, there are certain claims that are automatically included and cannot be overridden by templates. Clerk calls these "default claims" and you can learn more about them in the [Session tokens](/docs/guides/sessions/session-tokens) reference documentation. For custom JWTs, Clerk automatically includes the following default claims: ```json { // default claims, included automatically "azp": "http://localhost:3000", "exp": 1639398300, "iat": 1639398272, "iss": "https://clean-mayfly-62.clerk.accounts.dev", "jti": "10db7f531a90cb2faea4", "nbf": 1639398220, "sub": "user_1deJLArSTiWiF1YdsEWysnhJLLY" } ``` However, other default claims - such as `sid` (session ID) - are only included in session-bound tokens, not in custom JWTs. Custom JWTs are not inherently tied to a session. Instead, they're designed to be flexible tokens that include the default claims listed above, along with any additional claims you explicitly set in your JWT template. For this reason, session-tied claims like `sid`, `v`, `pla`, or `fea` cannot be included in custom JWTs. If you need to generate a token that includes both session-bound data (like `sid`) and any additional claims, the recommended approach is to use a custom session token instead of a JWT template. See the [guide on customizing your Clerk session token](/docs/guides/sessions/customize-session-tokens). ### Shortcodes To include dynamic values in your tokens, you can use shortcodes. Shortcodes are strings that Clerk will replace with the actual values of the corresponding user information when the token is generated. > \[!NOTE] > Even though shortcodes are string values, their type in the generated token depends on the original type of the information that's included. For example, `{{user.public_metadata}}` will be substituted for a JSON object, not a string. #### Metadata in shortcodes While you can use the `{{user.public_metadata}}` or `{{user.unsafe_metadata}}` shortcodes to include the complete metadata object in the final token, there might be cases where you only need a specific piece of information. To keep your tokens lean, you can use the dot notation to access nested fields of the metadata object. Let's assume the user's public metadata are the following: ```json { "interests": ["hiking", "knitting"], "addresses": { "Home": "2355 Pointe Lane, 56301 Minnesota", "Work": "3759 Newton Street, 33487 Florida" } } ``` To access the `interests` array, you would use the shortcode `{{user.public_metadata.interests}}`. To access the `Home` address, you would use `{{user.public_metadata.addresses.Home}}`. See the following example: ```json {{ prettier: false }} // The template { "likes_to_do": "{{user.public_metadata.interests}}", "shipping_address": "{{user.public_metadata.addresses.Home}}" } // The generated token { "likes_to_do": ["hiking", "knitting"], "shipping_address": "2355 Pointe Lane, 56301 Minnesota" } ``` #### Interpolation in shortcodes Shortcodes can be interpolated inside strings. For example, you could use interpolation to build the user's full name: ```json { "full_name": "{{user.last_name}} {{user.first_name}}" } ``` Interpolated shortcodes will always result to string values. For example, if the user does not have a last name associated, the above full name value would be `null John`. #### Conditional expressions in shortcodes Conditional expressions use the `||` operator and can be used to substitute a default fallback value for shortcodes that would otherwise result in `null` or `false` values. The format of a conditional expression is the following: ```json { "key": "{{ || || }}" } ``` The result of a conditional expression is that of the first operand that does not evaluate to `null` or `false` (also known as "falsy"). If all operands of the expression are falsy, the last operand is returned no matter its value. Therefore, you should always place the default value as the last operand. See the following example: ```json { "has_verified_contact_info": "{{user.email_verified || user.phone_number_verified}}", // fallback to a string value "full_name": "{{user.full_name || 'Awesome User'}}", // fallback to a number value "age": "{{user.public_metadata.age || user.unsafe_metadata.age || 30 }}" } ``` For this example, in the case that user: * has verified their phone number * has not verified their email * has not provided their first or last name * does not have any public or unsafe metadata assigned Then, the output of the generated token would be: ```json { "has_verified_contact_info": true, "full_name": "Awesome User", "age": 30 } ``` The rules that govern conditional expressions are as follows: * The result of an expression is either the first operand that is not falsy, or the last operand (no matter its value). * String literals should use single quotes (`'`). * Only strings, booleans and numbers are permitted as literal (i.e. non-shortcodes) operands. ## Create a JWT template A template consists of the following four properties: * Template name: a unique identifier for the template. When generating a token, you will have to specify the template to use, using this name. This is a required field. * Token lifetime: the time in seconds, after which tokens generated with this template will expire. This setting determines the value of the `exp` claim (i.e. `exp=current_time+lifetime`). Default is 60 seconds. * Token allowed clock skew: the time in seconds, provided as a leeway to account for clock skews between different servers. This setting determines the value of the `nbf` claim (i.e. `nbf=current_time-allowed_clock_skew`). Default is 5 seconds. * Claims: the actual template that's entered into the JSON editor (see screenshot below). A template is essentially a JSON object that describes what the final token claims will look like (shortcodes can be used here). This is a required field. To create a JWT template: 1. In the Clerk Dashboard, navigate to the [**JWT templates**](https://dashboard.clerk.com/~/jwt-templates) page. 2. Select **New template**. 3. You can either select a blank template or choose one of the provided templates. ## Generate a JWT To generate a token using a template, you can use the `getToken()` method. See the reference documentation for more information and example usage. ## Complete example The following example demonstrates the full capabilities of JWT templates, including static claim values, dynamic claim values via shortcodes, and Clerk's "default claims". Given the following user: * First name: `Maria` * Last name: `Doe` * Profile picture URL: `https://example.com/avatar.jpg` * Clerk ID: `user_abcdef123456789` * Email address (verified): `maria@example.com` * Phone number: (not provided) * Public metadata: `{ "profile" : {"interests": ["reading", "climbing"] } }` * Unsafe metadata: `{ "foo" : { "bar": 42 } }` And given the following JWT template: ```json { // static values "aud": "https://my-site.com", "version": 1, "foo": { "bar": [1, 2, 3] }, // dynamic values "user_id": "{{user.id}}", "avatar": "{{user.image_url}}", "full_name": "{{user.last_name}} {{user.first_name}} ", "email": "{{user.primary_email_address}}", "phone": "{{user.primary_phone_address}}", "registration_date": "{{user.created_at}}", "likes_to_do": "{{user.public_metadata.profile.interests}}", "unsafe_meta": "{{user.unsafe_metadata}}", "invalid_shortcode": "{{user.i_dont_exist}}" } ``` The generated token would look like this: ```json { "aud": "https://my-site.com", "version": 1, "foo": { "bar": [1, 2, 3] }, "user_id": "user_abcdef123456789", "avatar": "https://example.com/avatar.jpg", "full_name": "Doe Maria", "email": "maria@example.com", "phone": null, "registration_date": 1227618844, "likes_to_do": ["reading", "climbing"], "unsafe_meta": { "foo": { "bar": 42 } }, "invalid_shortcode": null, // default claims, included automatically "azp": "http://localhost:3000", "exp": 1639398300, "iat": 1639398272, "iss": "https://clean-mayfly-62.clerk.accounts.dev", "jti": "10db7f531a90cb2faea4", "nbf": 1639398220, "sub": "user_1deJLArSTiWiF1YdsEWysnhJLLY" } ``` --- title: Sync auth status between your Chrome Extension and web app description: Learn how to configure your Chrome Extension to sync user authentication with your web application. sdk: chrome-extension sdkScoped: "true" canonical: /docs/guides/sessions/sync-host lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: chrome-extension notAvailableSdks: nextjs,react,js-frontend,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,go,astro,nuxt,vue,ruby,js-backend activeSdk: chrome-extension sourceFile: /docs/guides/sessions/sync-host.mdx --- Clerk allows you to sync the authentication state from your web app to your Chrome Extension using Clerk's Sync Host feature. When a user authenticates in your web app, they will also be authenticated in your Chrome Extension. > \[!WARNING] > Our Chrome Extension SDK currently does not fully support Sync Host on side panels. Currently, if a user authenticates in your web app, they need to close and reopen the side panel to update their auth status. > \[!WARNING] > This guide assumes assumes that you have followed the [Chrome Extension Quickstart](/docs/chrome-extension/getting-started/quickstart) and then the [Add React Router](/docs/guides/development/add-react-router) guide. ## Add `PLASMO_PUBLIC_CLERK_SYNC_HOST` to your environment variables The `PLASMO_PUBLIC_CLERK_SYNC_HOST` environment variable defines the host that the Chrome Extension will sync with. The values for `PLASMO_PUBLIC_CLERK_SYNC_HOST` will differ between development and production environments. Using separate `.env.development` and `.env.production` files allows you to seamlessly pass the appropriate values to your builds. Use the following tabs to view the instructions for development versus production instances. Add `PLASMO_PUBLIC_CLERK_SYNC_HOST` to your `.env.development` file. The value should be `http://localhost`. ```env {{ filename: '.env.development', mark: [3] }} PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_FRONTEND_API=https://{{fapi_url}} PLASMO_PUBLIC_CLERK_SYNC_HOST=http://localhost ``` Add `PLASMO_PUBLIC_CLERK_SYNC_HOST` to your `.env.production` file. The value should be the [domain that your Clerk Frontend API](https://dashboard.clerk.com/~/domains) runs on. For example, `https://clerk.your-domain.com`. ```env {{ filename: '.env.production', mark: [3] }} PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_123 CLERK_FRONTEND_API=https://clerk.your-domain.com PLASMO_PUBLIC_CLERK_SYNC_HOST=https://clerk.your-domain.com ``` ## Add `syncHost` prop to your `` Add the `syncHost` prop to your Chrome Extension's `` component. This prop tells the `` which host to sync with. ```tsx {{ filename: 'src/popup/layouts/root-layout.tsx', mark: [5, [7, 11], 22] }} import { ClerkProvider, SignedIn, SignedOut, UserButton } from '@clerk/chrome-extension' import { Link, Outlet, useNavigate } from 'react-router-dom' const PUBLISHABLE_KEY = process.env.PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY const SYNC_HOST = process.env.PLASMO_PUBLIC_CLERK_SYNC_HOST if (!PUBLISHABLE_KEY || !SYNC_HOST) { throw new Error( 'Please add the PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY and PLASMO_PUBLIC_CLERK_SYNC_HOST to the .env.development file', ) } export const RootLayout = () => { const navigate = useNavigate() return ( navigate(to)} routerReplace={(to) => navigate(to, { replace: true })} publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/" syncHost={SYNC_HOST} >
Settings Home Sign In Sign Up
) } ``` ### Hide unsupported authentication methods When using the Sync Host feature, authentication methods that you want to use in your web app [may not be fully supported in the Chrome Extension environment](/docs/reference/chrome-extension/overview#authentication-options). To hide unsupported methods in your Chrome Extension, you can use the [`appearance`](/docs/guides/customizing-clerk/appearance-prop/overview) prop with your extension's `` and `` components as demonstrated in the following examples. ", ""]}> ```tsx {{ filename: 'src/popup/pages/sign-up.tsx', mark: [[3, 7]] }} ``` ```tsx {{ filename: 'src/popup/pages/sign-in.tsx', mark: [[3, 7]] }} ``` ## Configure `host_permissions` `host_permissions` specifies which hosts, or websites, will have permission to sync auth state with your app. It accepts an array, allowing you to add more than one host. In the `package.json` file, in the `manifest` object, update the `host_permissions` array. Remove `http://localhost/*` and replace with `$PLASMO_PUBLIC_CLERK_SYNC_HOST/*`, as shown in the following example: ```json {{ filename: 'package.json', mark: [6] }} { // The rest of your package.json file "manifest": { "key": "$CRX_PUBLIC_KEY", "permissions": ["cookies", "storage"], "host_permissions": ["$PLASMO_PUBLIC_CLERK_SYNC_HOST/*", "$CLERK_FRONTEND_API/*"] } } ``` ## Add the Extension's ID to your web app's `allowed_origins` To allow your Chrome Extension to sync with your web app, you must add the extension's ID to your web app's `allowed_origins`. > \[!NOTE] > If you have not [configured a consistent key](/docs/guides/development/configure-consistent-crx-id), you will have to repeat this step every time your extension's ID changes. 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. Copy your Secret Key. It should start with `sk_test_` or `sk_live_` for your development and production instances, respectively. 3. In your terminal, paste the following command. Replace `YOUR_SECRET_KEY` with your Clerk Secret Key and the `` with your extension's ID. The final result should resemble the following: ```bash {{ filename: 'terminal' }} curl -X PATCH https://api.clerk.com/v1/instance \ -H "Authorization: Bearer {{secret}}" \ -H "Content-type: application/json" \ -d '{"allowed_origins": ["chrome-extension://"]}' ```
--- title: Verify a Clerk session in Go description: Learn how to verify a session with Clerk in your Go application. sdk: go sdkScoped: "true" canonical: /docs/guides/sessions/verifying lastUpdated: 2025-11-19T22:57:21.000Z availableSdks: go notAvailableSdks: nextjs,react,js-frontend,chrome-extension,expo,android,ios,expressjs,fastify,react-router,remix,tanstack-react-start,astro,nuxt,vue,ruby,js-backend activeSdk: go sourceFile: /docs/guides/sessions/verifying.mdx --- There are two ways to verify a session with Clerk in your Go application: * [Using Clerk middleware](#use-clerk-middleware-to-verify-a-session)
If you want to verify a session in an HTTP context, it is recommended to use Clerk middleware. Clerk middleware guarantees better performance and efficiency by making the minimum necessary requests to the Clerk Backend API. * [Manually verifying the session token](#manually-verify-a-session-token)
If you want to verify a session in a non-HTTP context, or if you would like total control over the verification process, you can verify the session token manually. ## Use Clerk middleware to verify a session Go enables you to create a simple HTTP server, and Clerk enables you to authenticate any request. Together, you can create a secure server that only allows authenticated users to access certain routes. Clerk Go SDK provides two functions for adding authentication to HTTP handlers: * [`WithHeaderAuthorization()`](https://pkg.go.dev/github.com/clerk/clerk-sdk-go/v2/http#WithHeaderAuthorization) * [`RequireHeaderAuthorization()`](https://pkg.go.dev/github.com/clerk/clerk-sdk-go/v2/http#RequireHeaderAuthorization), which calls `WithHeaderAuthorization()` under the hood, but responds with `HTTP 403 Forbidden` if it fails to detect valid session claims. Both middleware functions support header based authentication with a bearer token. The token will be parsed, verified, and its claims will be extracted as [`SessionClaims`](https://pkg.go.dev/github.com/clerk/clerk-sdk-go/v2#SessionClaims). The claims will then be made available in the `http.Request.Context` for the next handler in the chain. Clerk Go SDK provides the [`SessionClaimsFromContext()`](https://pkg.go.dev/github.com/clerk/clerk-sdk-go/v2#SessionClaimsFromContext) helper for accessing the claims from the context. The following example demonstrates how to use the `WithHeaderAuthorization()` middleware to protect a route. If the user tries accessing the route and their session token is valid, the user's ID and banned status will be returned in the response. > \[!NOTE] > Your Clerk Secret Key is required. If you are signed into the Clerk Dashboard, your Secret Key should become visible by selecting the eye icon. Otherwise, you can retrieve your Clerk Secret Key on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ```go {{ filename: 'main.go' }} package main import ( "fmt" "net/http" "github.com/clerk/clerk-sdk-go/v2" clerkhttp "github.com/clerk/clerk-sdk-go/v2/http" "github.com/clerk/clerk-sdk-go/v2/user" ) func main() { clerk.SetKey("{{secret}}") mux := http.NewServeMux() mux.HandleFunc("/", publicRoute) protectedHandler := http.HandlerFunc(protectedRoute) mux.Handle( "/protected", clerkhttp.WithHeaderAuthorization()(protectedHandler), ) http.ListenAndServe(":3000", mux) } func publicRoute(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`{"access": "public"}`)) } func protectedRoute(w http.ResponseWriter, r *http.Request) { claims, ok := clerk.SessionClaimsFromContext(r.Context()) if !ok { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } usr, err := user.Get(r.Context(), claims.Subject) if err != nil { // handle the error } fmt.Fprintf(w, `{"user_id": "%s", "user_banned": "%t"}`, usr.ID, usr.Banned) } ``` ## Manually verify a session token Manually verifying a Clerk session is useful when you want to verify a session in a non-HTTP context, or when you want full control over the verification process. Verifying a session token requires providing a **JSON Web Key**. With the solution above, Clerk middleware fetches the JSON Web Key **once** and automatically caches it for you, so it makes the minimum necessary requests to the Clerk Backend API. However, when manually verifying a session, you're responsible for fetching and caching the JSON Web Key yourself, as there is no caching layer for the key. For that reason, you must be mindful of API rate limits and unnecessary requests. Clerk Go SDK provides a set of functions for decoding and verifying JWTs, as well as fetching JSON Web Keys. It is recommended to cache your JSON Web Key and invalidate the cache only when a replacement key is generated. Before verifying a session token, you need to retrieve it from the request. Session tokens can be found in two places depending on your architecture: * **Authorization header** - For cross-origin requests, the token is typically sent as a Bearer token in the `Authorization` header. * **`__session` cookie** - For same-origin requests, the token is stored in a cookie named `__session`. The following example demonstrates how to manually verify a session token. If the user tries accessing the route and their session token is valid, the user's ID and banned status will be returned in the response. ```go {{ filename: 'main.go' }} package main import ( "fmt" "net/http" "strings" "github.com/clerk/clerk-sdk-go/v2" "github.com/clerk/clerk-sdk-go/v2/jwks" "github.com/clerk/clerk-sdk-go/v2/jwt" "github.com/clerk/clerk-sdk-go/v2/user" ) func main() { clerk.SetKey("{{secret}}") config := &clerk.ClientConfig{} config.Key = clerk.String("{{secret}}") jwksClient := jwks.NewClient(config) mux := http.NewServeMux() mux.HandleFunc("/", publicRoute) mux.HandleFunc("/protected", protectedRoute(jwksClient)) http.ListenAndServe(":3000", mux) } func publicRoute(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`{"access": "public"}`)) } func protectedRoute(jwksClient *jwks.Client) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { // Get the session JWT from the Authorization header or __session cookie sessionToken := getSessionToken(r) if sessionToken == "" { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } // Decode the session JWT to find the key ID unsafeClaims, err := jwt.Decode(r.Context(), &jwt.DecodeParams{ Token: sessionToken, }) if err != nil { // handle the error w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } // Fetch the JSON Web Key jwk, err := jwt.GetJSONWebKey(r.Context(), &jwt.GetJSONWebKeyParams{ KeyID: unsafeClaims.KeyID, JWKSClient: jwksClient, }) if err != nil { // handle the error w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } // Verify the session claims, err := jwt.Verify(r.Context(), &jwt.VerifyParams{ Token: sessionToken, JWK: jwk, }) if err != nil { // handle the error w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } usr, err := user.Get(r.Context(), claims.Subject) if err != nil { // handle the error } fmt.Fprintf(w, `{"user_id": "%s", "user_banned": "%t"}`, usr.ID, usr.Banned) } } // getSessionToken retrieves the session token from either the Authorization header // or the __session cookie, depending on the request type func getSessionToken(r *http.Request) string { // First try to get the token from the Authorization header (cross-origin) authHeader := r.Header.Get("Authorization") if authHeader != "" { return strings.TrimPrefix(authHeader, "Bearer ") } // If not found in header, try to get from __session cookie (same-origin) cookie, err := r.Cookie("__session") if err != nil { return "" } return cookie.Value } ``` If you need to verify session tokens frequently, it's recommended to cache the JSON Web Key for your instance in order to avoid making too many requests to the Clerk Backend API. The following example uses the same manual verification flow as above, with the addition of demonstrating a possible way to cache and store your JSON Web Key to avoid repeated requests to Clerk. The example is meant to serve as a guide; implementation may vary depending on your needs. ```go {{ filename: 'main.go', mark: [[17, 23], [50, 51], [76, 78], [117, 141]] }} package main import ( "fmt" "net/http" "strings" "github.com/clerk/clerk-sdk-go/v2" "github.com/clerk/clerk-sdk-go/v2/jwks" "github.com/clerk/clerk-sdk-go/v2/jwt" "github.com/clerk/clerk-sdk-go/v2/user" ) func main() { clerk.SetKey("{{secret}}") // Initialize storage for JSON Web Keys. You can cache/store // the key for as long as it's valid, and pass it to jwt.Verify. // This way jwt.Verify won't make requests to the Clerk // Backend API to refetch the JSON Web Key. // Make sure you refetch the JSON Web Key whenever your // Clerk Secret Key changes. jwkStore := NewJWKStore() config := &clerk.ClientConfig{} config.Key = clerk.String("{{secret}}") jwksClient := jwks.NewClient(config) mux := http.NewServeMux() mux.HandleFunc("/", publicRoute) mux.HandleFunc("/protected", protectedRoute(jwksClient, jwkStore)) http.ListenAndServe(":3000", mux) } func publicRoute(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`{"access": "public"}`)) } func protectedRoute(jwksClient *jwks.Client, store JWKStore) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { // Get the session JWT from the Authorization header or __session cookie sessionToken := getSessionToken(r) if sessionToken == "" { w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } // Attempt to get the JSON Web Key from your store. jwk := store.GetJWK() if jwk == nil { // Decode the session JWT to find the key ID. unsafeClaims, err := jwt.Decode(r.Context(), &jwt.DecodeParams{ Token: sessionToken, }) if err != nil { // handle the error w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } // Fetch the JSON Web Key jwk, err = jwt.GetJSONWebKey(r.Context(), &jwt.GetJSONWebKeyParams{ KeyID: unsafeClaims.KeyID, JWKSClient: jwksClient, }) if err != nil { // handle the error w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } } // Write the JSON Web Key to your store, so that next time // you can use the cached value. store.SetJWK(jwk) // Verify the session claims, err := jwt.Verify(r.Context(), &jwt.VerifyParams{ Token: sessionToken, JWK: jwk, }) if err != nil { // handle the error w.WriteHeader(http.StatusUnauthorized) w.Write([]byte(`{"access": "unauthorized"}`)) return } usr, err := user.Get(r.Context(), claims.Subject) if err != nil { // handle the error } fmt.Fprintf(w, `{"user_id": "%s", "user_banned": "%t"}`, usr.ID, usr.Banned) } } // getSessionToken retrieves the session token from either the Authorization header // or the __session cookie, depending on the request type func getSessionToken(r *http.Request) string { // First try to get the token from the Authorization header (cross-origin) authHeader := r.Header.Get("Authorization") if authHeader != "" { return strings.TrimPrefix(authHeader, "Bearer ") } // If not found in header, try to get from __session cookie (same-origin) cookie, err := r.Cookie("__session") if err != nil { return "" } return cookie.Value } // Sample interface for JSON Web Key storage. // Implementation may vary. type JWKStore interface { GetJWK() *clerk.JSONWebKey SetJWK(*clerk.JSONWebKey) } // Implementation may vary. This can be an // in-memory store, database, caching layer, etc. // This example uses an in-memory store. type InMemoryJWKStore struct { jwk *clerk.JSONWebKey } func (s *InMemoryJWKStore) GetJWK() *clerk.JSONWebKey { return s.jwk } func (s *InMemoryJWKStore) SetJWK(j *clerk.JSONWebKey) { s.jwk = j } func NewJWKStore() JWKStore { return &InMemoryJWKStore{} } ``` --- title: Cookies description: Learn how cookies enable secure authentication and manage browser-server interactions. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/how-clerk-works/cookies sourceFile: /docs/guides/how-clerk-works/cookies.mdx --- Cookies play a vital role in authentication, state management, and browser-server communication. By understanding their attributes, developers can ensure secure and efficient use in their applications. ## What are cookies? Cookies are small pieces of information stored in the browser and sent automatically alongside some requests coming from that browser. By default, HTTP requests are "stateless" and lack memory of previous interactions. Cookies change this behavior, as they are stored long term and can be sent alongside each request. ### Setting cookies Cookies are typically created by the server and communicated to the browser through the [`Set-Cookie` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie). When the browser receives this header, it stores the cookie and includes it in future requests to the **same domain**. Here's an example: ```http HTTP/2 200 Content-Type: text/html Set-Cookie: session_id=sess123

Hello, world!

``` This response sets a `session_id` cookie with the value `sess123`. To view cookies in your browser's developer tools, navigate to the **Application** tab. Then in the **Storage** section, select **Cookies**. Here's an example from Clerk's website: ![cookies in browser console](/docs/images/how-clerk-works/devtools-cookies.png) ## Cookie domains and scope Each cookie has a [`Domain`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent) that indicates **the domain from which the cookie was set**. This determines when the cookie will be included in requests. For example: * If a cookie is set by `example.com` without a `Domain` value, it will be sent only with requests *to* `example.com`. * If the cookie's `Domain` value is *explicitly* set to `example.com`, it will also be sent with requests to subdomains like `sub.example.com`. * However, cookies set by subdomains (e.g., `sub.example.com`) won't be sent with requests to the parent domain (`example.com`). ## Tracking cookies and privacy concerns Historically, cookies were often used for tracking user behavior across websites. For example, say you [hotlink](https://developer.mozilla.org/en-US/docs/Glossary/Hotlink) an image from `facebook.com` on to your website, `example.com`, as such: ```

Check out this cool picture of me on vacation that I posted on FB

``` To display the image, `example.com` requests the image from `facebook.com`. Let's say Facebook's web server: 1. Retrieves the image 2. Creates an entry for you as a user in their database with a unique ID 3. Records that you visited `example.com` 4. Sets a cookie with your unique ID and [the `SameSite` value set to "none"](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value) The response from Facebook would look something like: ``` HTTP/2 200 Set-Cookie: fb_tracker=user123; SameSite=none ...the content of the image ``` Now let's say you visit another website, `foobar.com`, and that website is using a script from Facebook for tracking the effectiveness of Facebook ads. So now `foobar.com` makes a request to `facebook.com`, and Facebook gets back the cookie that it set from the image on `example.com`. But how could this happen? Let's revisit this statement one more time: > Cookies are typically created by the server and communicated to the browser through the [`Set-Cookie` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie). When the browser receives this header, it stores the cookie and includes it in future requests to the **same domain**. Despite being set on `example.com`, the cookie's domain value is `facebook.com`, since it was set *by* Facebook. And remember that the cookie was set with the `SameSite` value set to “none”, which, according to [the docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value), means that the browser sends the cookie **with both cross-site and same-site requests.** So in this scenario, even if the cookie was set on a different website, the browser still sends the cookie back to Facebook, because the cookie has `facebook.com` set as its domain. Facebook then gets the cookie, is able to identify you as a user, and can identify that you also visited `foobar.com`. Any other site that you visit that loads anything from Facebook is an opportunity for Facebook to get back the cookie and use it to build a profile of your browsing habits and history. Clerk doesn't do any of this type of tracking. However, this example is still helpful for building a foundation around the edges of how cookies are stored and transmitted. ## Controlling cross-site cookie behavior with `SameSite` The `SameSite` attribute of cookies plays a crucial role in controlling cross-site cookie behavior. Clerk uses the `SameSite=Lax` setting to ensure a secure and user-friendly experience. This setting allows cookies to be sent with top-level navigation (e.g., clicking a link) but not with other cross-site requests (e.g., loading images). See MDN's guide on [`SameSite`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value) for more details. ## Sharing cookies across subdomains Sharing cookies across subdomains is controlled by the `Domain` attribute. * A cookie **explicitly** set with `Domain=example.com` will be sent with requests to both `example.com` and `sub.example.com`. * A cookie set without a domain value will only be sent to the domain that created it (e.g., `example.com`) and not its subdomains. Cookies **explicitly** set with a domain appear in devtools with a leading period (e.g., `.example.com`). Cookies set without a domain value appear without the leading period (e.g., `example.com`). ## Controlling JavaScript access with `HttpOnly` By default, cookies can be accessed via `document.cookie` in JavaScript. While this can be useful, it exposes cookies to risks like [Cross-Site Scripting (XSS) attacks](https://owasp.org/www-community/attacks/xss/). Setting the [`HttpOnly`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#httponly) flag prevents JavaScript from accessing the cookie, enhancing security. These cookies are still sent with HTTP requests but are inaccessible to client-side scripts. ## How Clerk uses cookies Clerk leverages cookies in a secure, privacy-compliant manner to facilitate seamless user authentication across domains and subdomains. Clerk sets cookies when your users interact with your application in ways that trigger requests for services, such as signing in or signing up. This cannot be disabled. These cookies: * Are required for Clerk to function, and should not be blocked by you or your users. * Do not store any personally identifiable information by default. * Can be configured by modifying the [session token](/docs/guides/sessions/session-tokens) in the [Clerk Dashboard](https://dashboard.clerk.com/~/jwt-templates). | Cookie Subgroup | Cookies | More Information | | - | - | - | | .clerk.com | `__session`, `__client_uat` | First party | | .clerk.com, .dashboard.clerk.com (cloudflare) | `_cfuvid` | Third party [Cloudflare Cookies](https://developers.cloudflare.com/fundamentals/reference/policies-compliances/cloudflare-cookies/) | > \[!WARNING] > You should seek legal advice before using this information to craft your privacy policy. To learn more about how Clerk uses cookies to store user information, see the [guide on how Clerk works](/docs/guides/how-clerk-works/overview). --- title: Tokens and signatures description: Learn about JWTs, digital signatures, and how Clerk uses them to securely authenticate users. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/how-clerk-works/tokens-and-signatures sourceFile: /docs/guides/how-clerk-works/tokens-and-signatures.mdx --- ## Digital signatures Digital signatures are a cryptographic technique that ensures the authenticity and integrity of messages. They guarantee that: 1. The message originates from a specific sender (authenticity). 2. The message's content hasn't been modified from how it was written by the sender (integrity). However, digital signatures do **not** encrypt the message—anyone can read its contents. ### How digital signatures work Digital signatures use **public key cryptography**, which involves a key pair: a private key (kept secret) and a public key (shared openly). Here's the process: 1. A private key is used to create a **signature**: 1. The message is [hashed](https://www.techtarget.com/searchdatamanagement/definition/hashing) (a unique, fixed-length representation of the message). 2. The hash is encrypted using the sender's private key, creating the signature. 2. The message and signature are sent to the recipient. 3. The recipient verifies the signature using the sender's public key by: 1. Decrypting the signature to retrieve the hash. 2. Independently hashing the message and comparing the two hashes. If they match, the message is authentic and has not been changed. So for example, imagine you get a publicly readable message, like `hello world`, and the message is “signed” with the signature `j2e80w8dj9f8`. If you'd like to be sure that the message is genuine, and you have a copy of the sender's public key, you can use this key to decrypt the signature and make sure that it is valid. If it is, you know two things for sure: who sent the message, and that nobody intercepted the message and messed with it in the middle, since part of the verification process involves hashing the message and comparing it to the decrypted signature. ### Key Terminology * **Sign**: The process of generating a digital signature with a private key and attaching it to a message. * **Verify**: The process of using a public key to confirm the signature's validity and the message's integrity. Clerk leverages digital signatures in **JSON Web Tokens (JWTs)** to securely authenticate users. ## JSON Web Tokens (JWTs) JSON Web Tokens (JWTs) are a lightweight format for transmitting digitally signed data over the internet. They are commonly used for authentication and information exchange. ### Structure of a JWT A JWT's format is three [base64-encoded](https://builtin.com/software-engineering-perspectives/base64-encoding) parts, separated by dots: ```plaintext
.. ``` Here's an example of a JWT: ```plaintext eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.Eci61G6w4zh_u9oOCk_v1M_sKcgk0svOmW4ZsL-rt4ojGUH2QY110bQTYNwbEVlowW7phCg7vluX_MCKVwJkxJT6tMk2Ij3Plad96Jf2G2mMsKbxkC-prvjvQkBFYWrYnKWClPBRCyIcG0dVfBvqZ8Mro3t5bX59IKwQ3WZ7AtGBYz5BSiBlrKkp6J1UmP_bFV3eEzIHEFgzRa3pbr4ol4TK6SnAoF88rLr2NhEz9vpdHglUMlOBQiqcZwqrI-Z4XDyDzvnrpujIToiepq9bCimPgVkP54VoZzy-mMSGbthYpLqsL_4MQXaI1Uf_wKFAUuAtzVn4-ebgsKOpvKNzVA ``` Let's decode and break down each part: **Header**: The header specifies metadata about the token, such as the hashing algorithm used for the signature. There are several different hashing algorithms that can be used to digitally sign a JWT. This example's header tells us that the signature's hash was created using the `RS256` algorithm: ```json { "alg": "RS256", "typ": "JWT" } ``` **Payload**: The payload contains the actual information that you want to send. In Clerk's case, this includes information about the authenticated user. [Read more about Clerk's session JWT payload](/docs/guides/sessions/session-tokens). ```json { "sub": "user_123", "iat": 1516239022 } ``` **Signature**: The signature is created by hashing the header and payload, and then encrypting the hash with the private key. ``` Error: The string is not correctly encoded ``` When decoding the signature from base64, an error is thrown because the signature is not base64-encoded. This is expected behavior. The recipient must use the JWT issuer's public key and the algorithm specified in the header (e.g., RS256) to verify the signature. Clerk's SDKs all ship with a method for verifying the signature of a Clerk JWT: authenticateRequest(). But if you'd like to verify the signature yourself, see the [guide on manual JWT verification](/docs/guides/sessions/manual-jwt-verification). ### How Clerk uses JWTs To learn more about how Clerk uses JWTs, read the [guide on how Clerk works](/docs/guides/how-clerk-works/overview). --- title: Rate limits description: Learn about rate limiting on the Clerk APIs. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/how-clerk-works/system-limits sourceFile: /docs/guides/how-clerk-works/system-limits.mdx --- Clerk rate limits certain endpoints to help protect users against brute-force attacks or to stop abuse of Clerk's platform. ## Errors If you receive a `429` error code, you have been rate limited. All subsequent requests to that specific endpoint will be blocked for a given amount of time. Requests that have been rate limited will receive the `Retry-After` response header, which contains the number of seconds after which the block expires. ## Frontend API requests Frontend API requests are rate-limited per user and identified by their IP address. * Create SignIn * `/v1/sign_ins` 5 requests per 10 seconds *** * Create SignUp * `/v1/sign_ups` 5 requests per 10 seconds *** * Attempt SignIn * `/v1/sign_ins/attempt_(first|second)_factor` 3 requests per 10 seconds *** * Attempt SignUp * `/v1/sign_ups/attempt_verification` 3 requests per 10 seconds ## Backend API requests Backend API requests are rate-limited per application instance which is identified by the Secret Key that is provided when making Backend API requests. These limits differ based on whether you're using a development or production instance. * Production instances 1000 requests per 10 seconds *** * Development instances 100 requests per 10 seconds *** * Get the JWKS of the instance * `GET /v1/jwks` No rate limit > \[!NOTE] > The `currentUser()` helper uses the `GET /v1/users/me` endpoint, so it is subject to the respective rate limits. --- title: Routing in Clerk description: Learn how Clerk handles routing in your application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/how-clerk-works/routing sourceFile: /docs/guides/how-clerk-works/routing.mdx --- Some of Clerk's components have their own internal routing. For example, say a user uses their email address to fill out the \ form. Once they submit the form, they are redirected from `/sign-up` to `/sign-up/verify-email-address`, which renders Clerk's UI for verifying a user's email address. This redirect is handled by Clerk's internal routing. ## `routing` prop The following Clerk components accept a `routing` prop in order to define the routing strategy: * \ * \ * \ * \ * \ There following routing strategies can be passed: * [`path`](#path-routing) * [`hash`](#hash-routing) Clerk will attempt to select the routing strategy that best integrates with your framework of choice. If for some reason the default routing strategy doesn't work for you, use the information below to pick a strategy that will work for your setup. ### `path` routing `path` routing uses the path in the URL to determine the route. This is useful for server-rendered pages where SEO and server-side routing are crucial, such as Next.js or Remix applications. For example, say you have a Clerk + Next.js application with the `` component on a dedicated `/sign-up` page. A user visit this page and uses their email address to fill out the `` form. Once they submit the form, they are redirected from `/sign-up` to `/sign-up/verify-email-address`. For the following SDKs, `path` routing is set *by default* on all Clerk components, as these frameworks support server-side routing out-of-the-box. There is no need to pass the `routing` or `path` props to Clerk components in these frameworks. * Next.js * Remix * Tanstack React Start * React Router ### `hash` routing `hash` routing uses [the hash (#) portion of the URL](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash) to determine the route. This is useful for single-page applications that use client-side routing. For example, say you have a Clerk + React application with the `` component on a dedicated `/sign-up` page. A user visit this page and uses their email address to fill out the `` form. Once they submit the form, they are redirected from `/sign-up` to `/sign-up#verify-email-address`. In Clerk applications that use any SDK other than [the ones listed in the previous section](#path-routing), `hash` routing is set *by default* on all Clerk components. --- title: How Clerk works description: Learn how Clerk is architected and how it works under the hood. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/how-clerk-works/overview sourceFile: /docs/guides/how-clerk-works/overview.mdx --- This guide provides a deep dive into Clerk's architecture and internal workings. For developers who are simply looking to add authentication to their app, see the [quickstart guides](/docs/getting-started/quickstart/overview). ## The frontend API When you create a new application through the [Clerk Dashboard](https://dashboard.clerk.com/), Clerk provisions a dedicated frontend API (FAPI) instance for your application. It is hosted at `https://.clerk.accounts.dev` in development environments, where `` is a unique identifier generated for your application. You can find your application's FAPI URL in the [**Domains**](https://dashboard.clerk.com/~/domains) page of the Clerk Dashboard. When configuring your Clerk app, you must provide a [Publishable Key](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys). The Publishable Key tells your app what your FAPI URL is, enabling your app to locate and communicate with your dedicated FAPI instance. The Clerk Publishable Key follows a specific format: it consists of your FAPI instance URL encoded in base64, prefixed with an environment identifier (e.g. `pk_test_` for development environments, `pk_live_` for production environments), and suffixed with a `$` delimiter for future extensibility. The base64-encoded URL enables your application to locate and communicate with your dedicated FAPI instance. You can verify this structure by decoding the key yourself: ```js const publishableKey = 'pk_test_ZXhhbXBsZS5hY2NvdW50cy5kZXYk' const keyWithoutPrefix = publishableKey.replace('pk_test_', '') atob(keyWithoutPrefix) // => example.accounts.dev$ ``` > \[!NOTE] > In previous versions of Clerk, the Frontend API URL was exposed directly rather than being encoded within a Publishable Key. This was a source of confusion for users, so we transitioned to encoding it as base64 and making it a key. FAPI manages authentication flows on a per-user basis. For instance, it handles flows for signing up a user, retrieving a user's active sessions, creating an Organization on behalf of a user, or fetching a user's Organization invites. You can find the complete FAPI documentation [here](/docs/reference/frontend-api){{ target: '_blank' }}. FAPI *does not* handle administrative actions that impact multiple users, such as listing all users, banning users, or impersonating a user. These types of tasks are handled by [the backend API](#the-backend-api). Some tasks, such as [signing up a user](/docs/reference/frontend-api/tag/sign-ups/post/v1/client/sign_ups){{ target: '_blank' }}, don't require authentication, as that would defeat the purpose of the endpoint. However, endpoints designed for authenticated users, like [updating a user's details](/docs/reference/frontend-api/tag/user/patch/v1/me){{ target: '_blank' }}, require FAPI to first identify the user making the request and then verify their authorization. This ensures that users cannot modify another user's details. Typically, this is achieved by sending a signed token with the request, either as a cookie or a header. You can [learn more about Clerk's authentication tokens later in this guide](#stateful-authentication). While it's possible to build complete authentication flows directly on top of the frontend API, it involves significantly more work. Most users prefer our frontend SDKs, which provide higher-level abstractions like the mountSignIn() method or the \ component (for React-based SDKs). These abstractions offer a well-tested, thoughtfully designed, a11y-optimized, and customizable UI for authentication flows, handling all possible configurations of your authentication preferences out-of-the-box. ## Levels of abstraction FAPI is the lowest level of abstraction that authentication flows can be built on with Clerk. However, there are several other abstraction layers that offer less work and more convenience. ### Clerk's prebuilt components Clerk's prebuilt UI components are Clerk's highest level of abstraction. They are "all in one" components, offering the most complete implementation of authentication with the least amount of effort. While it's strongly recommended to use these components, due to the amount of research we have put into delivering an optimal experience, it's not the only option if you feel that you need more control over your authentication flows. > **Customizability:** You can [modify the CSS for any part of the prebuilt components](/docs/guides/customizing-clerk/appearance-prop/overview), but not the HTML structure or the logic/ordering of how the authentication flow works. ### Clerk Elements The next level of abstraction is [Clerk Elements](/docs/guides/customizing-clerk/elements/overview), a headless UI library that provides the foundational building blocks used in Clerk's prebuilt components. Similar to established libraries like [Radix](https://www.radix-ui.com), [Reach UI](https://reach.tech), and [Headless UI](https://headlessui.com), Clerk Elements exposes a set of unstyled React components that handle complex authentication logic while giving you complete control over the presentation layer. **Clerk Elements is still in beta**, and only supports sign-up and sign-in flows, with more components planned for future releases. > **Customizability:** You have full control over both the CSS and the HTML structure of the components, but you can't change the logic/ordering of how the authentication flow works. ### Custom flows Finally, if you need complete control over the authentication flow, Clerk provides low-level primitives that directly wrap our API endpoints. These primitives enable you to build fully custom authentication flows from scratch. Clerk refers to these as ["custom flows"](/docs/guides/development/custom-flows/overview). While this approach offers maximum flexibility, it also requires significant development effort to implement and maintain. Custom flows should only be considered when you have specific requirements that cannot be met using the prebuilt components or Clerk Elements, as you'll need to handle all authentication logic, error states, and edge cases yourself. > **Customizability:** You have full control over every part of the authentication flow, including HTML structure, CSS, and the logic/ordering of how the authentication flow works. ## The backend API The frontend API (FAPI) is designed for use primarily from the frontend of your application. Its methods focus on signing in users and managing user-related resources and data once they are authenticated. However, as an application developer, you might also need to perform administrative tasks, such as modifying multiple user or Organization details, retrieving a list of all users, banning or impersonating a user, and more. To maintain security, these administrative tasks should only be executed on the server side using a secret key inaccessible to your users or the browser. These operations are handled by a separate API known as the backend API (BAPI). You can find the BAPI documentation [here](/docs/reference/backend-api){{ target: '_blank' }}. Although the administrative features of BAPI are useful for many applications, it's most commonly used to verify a user's authentication state when processing requests from your app's frontend. For instance, if a user submits a request to update some data associated with their account, **your server must ensure the user is authenticated and authorized to make this change.** Without proper validation, malicious actors could potentially take over user accounts. Like FAPI, while you can interact directly with BAPI, most developers opt to use Clerk's SDKs for smoother integration with their preferred language or framework. Documentation for Clerk's SDKs is available in [the left sidenav of the docs](https://clerk.com/docs). That being said, FAPI is a much more complex and nuanced API that relies on more custom logic outside of its endpoints to create a functional SDK on top of it. As such, **interacting directly with FAPI is not recommended**, whereas interacting directly with BAPI is generally reasonable. ## Stateful authentication To understand how authentication works in Clerk, it's important to first understand how the most common implementation of authentication logic works: the traditional "stateful authentication" model, also known as "session token authentication". A user's process of signing in would work as follows. This example assumes that the user already signed up and their credentials are stored in a database. 1. The user initiates authentication by navigating to `example.com/sign-in`, entering their credentials (e.g. username/password), and submitting the form, usually by clicking a "submit" button. This makes a request to the server with the credentials. 2. The server validates the credentials against a database. This is normally done by [hashing](https://clerk.com/glossary#hash) the password and comparing it with a stored password hash. Upon successful validation, it creates a new [session](https://clerk.com/glossary#session) in the database associated with the user. 3. The server responds to the browser's request by setting the session ID in a [`Set-Cookie`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) header in the response, which sets a cookie with this value in the browser. This cookie will be automatically included in future requests from the browser in order to authenticate the user. {unconnectedOptions.length > 0 && (

Add a new external account

    {unconnectedOptions.map((strategy) => { return (
  • ) })}
)} ) } ``` --- title: Build a custom flow for managing TOTP-based multi-factor authentication description: Learn how to use the Clerk API to build a custom flow for managing TOTP-based multi-factor authentication. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/account-updates/manage-totp-based-mfa sourceFile: /docs/guides/development/custom-flows/account-updates/manage-totp-based-mfa.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. [Multi-factor verification (MFA)](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) is an added layer of security that requires users to provide a second verification factor to access an account. One of the options that Clerk supports for MFA is **Authenticator applications (also known as TOTP - Time-based One-time Password)**. This guide will walk you through how to build a custom flow that allows users to manage their TOTP settings. > \[!TIP] > To learn how to build a custom flow for managing SMS MFA, see the [dedicated guide](/docs/guides/development/custom-flows/account-updates/manage-sms-based-mfa). ## Enable multi-factor authentication For your users to be able to enable MFA for their account, you need to enable MFA as an MFA authentication strategy in your Clerk application. 1. In the Clerk Dashboard, navigate to the [**Multi-factor**](https://dashboard.clerk.com/~/user-authentication/multi-factor) page. 2. Enable **Authenticator application** and **Backup codes**. 3. Select **Save**. > \[!WARNING] > If you're using Duo as an authenticator app, please note that Duo generates TOTP codes differently than other authenticator apps. Duo allows a code to be valid for 30 seconds from *the moment it is first displayed*, which may cause frequent `invalid_code` errors if the code is not entered promptly. More information can be found in [Duo's Help Center](https://help.duo.com/s/article/2107). ## Create the multi-factor management flow This example is written for Next.js App Router but it can be adapted for any React-based framework. This example consists of two pages: * The main page where users can manage their MFA settings * The page where users can add TOTP MFA. Use the following tabs to view the code necessary for each page. ```tsx {{ filename: 'app/account/manage-mfa/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useUser, useReverification } from '@clerk/nextjs' import Link from 'next/link' import { BackupCodeResource } from '@clerk/types' // If TOTP is enabled, provide the option to disable it const TotpEnabled = () => { const { user } = useUser() const disableTOTP = useReverification(() => user?.disableTOTP()) return (

TOTP via authentication app enabled -

) } // If TOTP is disabled, provide the option to enable it const TotpDisabled = () => { return (

Add TOTP via authentication app -{' '}

) } // Generate and display backup codes export function GenerateBackupCodes() { const { user } = useUser() const [backupCodes, setBackupCodes] = React.useState(undefined) const createBackupCode = useReverification(() => user?.createBackupCode()) const [loading, setLoading] = React.useState(false) React.useEffect(() => { if (backupCodes) { return } setLoading(true) void createBackupCode() .then((backupCode: BackupCodeResource | undefined) => { setBackupCodes(backupCode) setLoading(false) }) .catch((err) => { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) setLoading(false) }) }, []) if (loading) { return

Loading...

} if (!backupCodes) { return

There was a problem generating backup codes

} return (
    {backupCodes.codes.map((code, index) => (
  1. {code}
  2. ))}
) } export default function ManageMFA() { const { isLoaded, isSignedIn, user } = useUser() const [showNewCodes, setShowNewCodes] = React.useState(false) if (!isLoaded) { // Handle loading state return null } if (!isSignedIn) { // Handle signed out state return

You must be logged in to access this page

} return ( <>

User MFA Settings

{/* Manage TOTP MFA */} {user.totpEnabled ? : } {/* Manage backup codes */} {user.backupCodeEnabled && user.twoFactorEnabled && (

Generate new backup codes? -{' '}

)} {showNewCodes && ( <> )} ) } ```
```tsx {{ filename: 'app/account/manage-mfa/add/page.tsx', collapsible: true }} 'use client' import { useUser, useReverification } from '@clerk/nextjs' import { TOTPResource } from '@clerk/types' import Link from 'next/link' import * as React from 'react' import { QRCodeSVG } from 'qrcode.react' import { GenerateBackupCodes } from '../page' type AddTotpSteps = 'add' | 'verify' | 'backupcodes' | 'success' type DisplayFormat = 'qr' | 'uri' function AddTotpScreen({ setStep, }: { setStep: React.Dispatch> }) { const { user } = useUser() const [totp, setTOTP] = React.useState(undefined) const [displayFormat, setDisplayFormat] = React.useState('qr') const createTOTP = useReverification(() => user?.createTOTP()) React.useEffect(() => { void createTOTP() .then((totp: TOTPResource) => { setTOTP(totp) }) .catch((err) => // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)), ) }, []) return ( <>

Add TOTP MFA

{totp && displayFormat === 'qr' && ( <>
)} {totp && displayFormat === 'uri' && ( <>

{totp.uri}

)}

Once you have set up your authentication app, verify your code

) } function VerifyTotpScreen({ setStep, }: { setStep: React.Dispatch> }) { const { user } = useUser() const [code, setCode] = React.useState('') const verifyTotp = async (e: React.FormEvent) => { e.preventDefault() try { await user?.verifyTOTP({ code }) setStep('backupcodes') } catch (err) { console.error(JSON.stringify(err, null, 2)) } } return ( <>

Verify TOTP

verifyTotp(e)}> setCode(e.currentTarget.value)} />
) } function BackupCodeScreen({ setStep, }: { setStep: React.Dispatch> }) { return ( <>

Verification was a success!

Save this list of backup codes somewhere safe in case you need to access your account in an emergency

) } function SuccessScreen() { return ( <>

Success!

You have successfully added TOTP MFA via an authentication application.

) } export default function AddMFaScreen() { const [step, setStep] = React.useState('add') const { isLoaded, isSignedIn, user } = useUser() if (!isLoaded) { // Handle loading state return null } if (!isSignedIn) { // Handle signed out state return

You must be logged in to access this page

} return ( <> {step === 'add' && } {step === 'verify' && } {step === 'backupcodes' && } {step === 'success' && } Manage MFA ) } ```
### Before you start Install `expo-checkbox` for the UI and `react-native-qr-svg` for the QR code. ```npm npm install expo-checkbox react-native-qr-svg ``` ### Build the flow To allow users to configure their MFA settings, you'll create a basic dashboard. The following example consists of three pages: * The layout page that checks if the user is signed in * The page where users can manage their account, including their MFA settings * The page where users can add TOTP MFA Use the following tabs to view the code necessary for each page. 1. Create the `(dashboard)` route group. This groups your account page and the "Add TOTP MFA" page. 2. Create a `_layout.tsx` file with the following code. The useAuth() hook is used to check if the user is signed in. If the user isn't signed in, they'll be redirected to the sign-in page. ```tsx {{ filename: 'app/(dashboard)/_layout.tsx' }} import { Redirect, Stack } from 'expo-router' import { useAuth } from '@clerk/clerk-expo' export default function AuthenticatedLayout() { const { isSignedIn } = useAuth() if (!isSignedIn) { return } return } ``` In the `(dashboard)` group, create an `account.tsx` file with the following code. This page shows users whether or not MFA is enabled, and allows them to add MFA with an authenticator app. ```tsx {{ filename: 'app/(dashboard)/account.tsx', collapsible: true }} import React from 'react' import { useUser } from '@clerk/clerk-expo' import { useRouter } from 'expo-router' import { View, Text, Button, FlatList } from 'react-native' import { BackupCodeResource } from '@clerk/types' export default function ManageTOTPMfa() { const router = useRouter() const [backupCodes, setBackupCodes] = React.useState(undefined) const [loading, setLoading] = React.useState(false) const { isLoaded, isSignedIn, user } = useUser() if (!isLoaded) { // Handle loading state return null } if (!isSignedIn) { // Handle signed out state return

You must be signed in to access this page

} const generateBackupCodes = () => { setLoading(true) void user ?.createBackupCode() .then((backupCodes: BackupCodeResource) => { setBackupCodes(backupCodes) setLoading(false) }) .catch((error) => { console.log('Error:', error) setLoading(false) }) } const disableTOTP = async () => { await user.disableTOTP() } const MFAEnabled = () => { return ( TOTP via authentication app enabled - ) })} ) } ``` ```tsx {{ filename: 'app/dashboard/_actions.ts' }} 'use server' import { auth } from '@clerk/nextjs/server' export async function generateActorToken(actorId: string, userId: string) { // Check if the user has the Permission to impersonate if (!auth().has({ permission: 'org:admin:impersonate' })) { return { ok: false, message: 'You do not have permission to access this page.', } } const params = JSON.stringify({ user_id: userId, actor: { sub: actorId, }, }) // Create an actor token using Clerk's Backend API const res = await fetch('https://api.clerk.com/v1/actor_tokens', { method: 'POST', headers: { Authorization: `Bearer ${process.env.CLERK_SECRET_KEY}`, 'Content-type': 'application/json', }, body: params, }) if (!res.ok) { return { ok: false, message: 'Failed to generate actor token' } } const data = await res.json() return { ok: true, token: data.token } } ```
The following example creates a basic dashboard for impersonating users. ### Protect the dashboard route > \[!WARNING] > It is **recommended** that you build impersonation into a dashboard that **only authorized users** can access. 1. Create the `dashboard/` directory. 2. In the `dashboard/` directory, create a `_layout.tsx` file with the following code. The useAuth() hook is used to access the user's authentication state. If the user is already signed in, they'll be redirected to the home page. The \ component is used to ensure that only users with the `org:dashboard:access` Permission can access it. You can modify the `permission` attribute to fit your use case. ```tsx {{ filename: 'app/dashboard/_layout.tsx' }} import { Redirect, Stack } from 'expo-router' import { Protect, useAuth } from '@clerk/clerk-expo' import { Text } from 'react-native' export default function GuestLayout() { const { isSignedIn } = useAuth() if (!isSignedIn) { return } return ( You don't have the permissions to access the dashboard.} > ) } ``` ### Create an API route to generate actor tokens To sign in as a different user, you must supply an actor token when creating a session. Create the `generateActorToken+api.tsx` file with the following code. This creates an API route that will call Clerk's Backend API [`/actor_tokens`](/docs/reference/backend-api/tag/actor-tokens/post/actor_tokens){{ target: '_blank' }} endpoint to create an actor token. ```tsx {{ filename: 'app/generateActorToken+api.tsx', collapsible: true }} export async function POST(req: Request) { const { actorId, userId } = await req.json() try { // Create an actor token using Clerk's Backend API const res = await fetch('https://api.clerk.com/v1/actor_tokens', { method: 'POST', headers: { Authorization: `Bearer ${process.env.CLERK_SECRET_KEY}`, 'Content-type': 'application/json', }, body: JSON.stringify({ user_id: userId, actor: { sub: actorId, }, }), }) const data = await res.json() return Response.json(data) } catch (err) { return Response.json({ error: 'Failed to generate actor token' }, { status: 500 }) } } ``` ### Create a hook to get users To impersonate a user, you need a list of your application's users to be able to select one for impersonation. 1. Create the `hooks/` directory. 2. In the `hooks/` directory, create the `useUsers.tsx` file with the following code. This creates a hook that will fetch the list of your application's users. ```tsx {{ filename: 'app/hooks/useUsers.tsx', collapsible: true }} import { UserJSON } from '@clerk/types' import { useEffect, useState } from 'react' type UseUsersReturn = { users: UserJSON[] | null isLoading: boolean error: Error | null } /** * Returns a list of users for the application. * * Until the users are fetched, `isLoading` will be set to `true`. * * @example * * import { useUsers } from '@/app/hooks/useUsers'; * * function Hello() { * const { users, isLoading, error } = useUsers(); * if(isLoading) { * return
Loading...
; * } * return
Users: {users?.map((user) => user.firstName).join(', ')}
* } */ export default function useUsers(): UseUsersReturn { const [users, setUsers] = useState(null) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { const getUsers = async () => { try { const res = await fetch('/getUsers') if (!res.ok) { throw new Error('Failed to fetch users') } const data = await res.json() setUsers(data) } catch (err) { setError(err instanceof Error ? err : new Error('Unknown error')) } finally { setIsLoading(false) } } getUsers() }, []) // Remove users from dependency array to prevent infinite loop return { users, isLoading, error } } ``` ### Create the dashboard UI 1. In the `dashboard/` directory, create the `index.tsx` file with the following code. This creates the UI for the dashboard, which displays a list of users and allows you to impersonate one. ```tsx {{ filename: 'app/dashboard/index.tsx', collapsible: true }} import React, { useState } from 'react' import { Button, Text, View } from 'react-native' import { useRouter } from 'expo-router' import { useUser, useSignIn } from '@clerk/clerk-expo' import useUsers from '../hooks/useUsers' export default function Dashboard() { const [error, setError] = useState(null) const { isLoaded, signIn, setActive } = useSignIn() const { isSignedIn, user } = useUser() const router = useRouter() const { users, isLoading } = useUsers() if (!isSignedIn) { // Handle signed out state return null } // Create an actor token for the impersonation async function createActorToken(actorId: string, userId: string) { setError(null) try { const res = await fetch('/generateActorToken', { method: 'POST', body: JSON.stringify({ actorId, userId, }), }) const data = await res.json() if (data.errors) { setError(data.errors[0].long_message) return null } return data.token } catch (err) { setError('Failed to generate actor token') return null } } // Handle "Impersonate" button click async function impersonateUser(actorId: string, userId: string) { setError(null) if (!isLoaded) return // Calls your /generateActorToken API route const actorToken = await createActorToken(actorId, userId) // Sign in as the impersonated user if (actorToken) { try { const { createdSessionId } = await signIn.create({ strategy: 'ticket', ticket: actorToken, }) await setActive({ session: createdSessionId }) router.push('/') } catch (err) { setError('Failed to impersonate user') // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } } return ( Welcome to the dashboard, {user?.firstName}! Your user ID is {user?.id} {isLoading && Loading your users...} {!isLoading && users && ( User ID Email ID First Name Actions {users.map((userFromList) => { const primaryEmail = userFromList.email_addresses?.find( (email) => email.id === userFromList.primary_email_address_id, ) return ( {userFromList.id} {primaryEmail?.id || 'N/A'} {userFromList.first_name || 'N/A'} {/* Don't allow impersonation of yourself */} {userFromList.id !== user.id ? (
) } return
Organization invitation accepted!
} ``` --- title: Build a custom flow for creating Organizations description: Learn how to use the Clerk API to build a custom flow for creating Organizations. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/organizations/create-organizations sourceFile: /docs/guides/development/custom-flows/organizations/create-organizations.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. This guide demonstrates how to use Clerk's API to build a custom flow for creating Organizations. The following example uses the useOrganizationList() hook to access the `createOrganization()` method. This method is used to create a new Organization with the provided name. This example is written for Next.js App Router but can be adapted for any React-based framework. ```tsx {{ filename: 'app/components/CreateOrganization.tsx' }} 'use client' import { useOrganizationList } from '@clerk/nextjs' import { FormEventHandler, useState } from 'react' export default function CreateOrganization() { const { isLoaded, createOrganization } = useOrganizationList() const [organizationName, setOrganizationName] = useState('') if (!isLoaded) return null const handleSubmit: FormEventHandler = async (e) => { e.preventDefault() createOrganization({ name: organizationName }) .then((res) => { console.log(res) }) .catch((err) => { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) }) setOrganizationName('') } return (
setOrganizationName(e.currentTarget.value)} />
) } ```
The following example uses the clerk.createOrganization() method to create a new Organization with the provided name. Use the tabs to view the code necessary for the `index.html` and `main.js` files. ```html {{ filename: 'index.html' }} Clerk + JavaScript App

Create an organization

``` ```js {{ filename: 'main.js' }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!pubKey) { throw new Error('Add your VITE_CLERK_PUBLISHABLE_KEY to .env file') } const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { const form = document.getElementById('create-organization') form.addEventListener('submit', function (e) { e.preventDefault() const inputEl = document.getElementById('name') if (!inputEl) { // ... handle empty input return } clerk .createOrganization({ name: inputEl.value }) .then((res) => console.log(res)) .catch((error) => console.log('An error occurred:', error)) }) } else { // If there is no active user, mount Clerk's document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ```
--- title: Build a custom flow for managing Organization membership requests description: Learn how to use the Clerk API to build a custom flow for managing Organization membership requests. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/organizations/manage-membership-requests sourceFile: /docs/guides/development/custom-flows/organizations/manage-membership-requests.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. This guide will demonstrate how to use the Clerk API to build a custom flow for managing [Organization membership requests](/docs/guides/organizations/verified-domains#membership-requests). The following example: 1. Uses the useOrganization() hook to get `membershipRequests`, which is a list of the Active Organization'sA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. membership requests. * `membershipRequests` is an object with `data` that contains an array of OrganizationMembershipRequest objects. * Each `OrganizationMembershipRequest` object has an accept() and reject() method to accept or reject the membership request, respectively. 2. Maps over the `data` array to display the membership requests in a table, providing an "Accept" and "Reject" button for each request that calls the `accept()` and `reject()` methods, respectively. This example is written for Next.js App Router but can be adapted for any React-based framework. ```jsx {{ filename: 'app/components/MembershipRequests.tsx', collapsible: true }} 'use client' import { useOrganization } from '@clerk/nextjs' export const MembershipRequestsParams = { membershipRequests: { pageSize: 5, keepPreviousData: true, }, } // List of organization membership requests. export const MembershipRequests = () => { const { isLoaded, membershipRequests } = useOrganization(MembershipRequestsParams) if (!isLoaded) { return <>Loading } return ( <>

Membership requests

{membershipRequests?.data?.map((mem) => ( ))}
User Date requested Actions
{mem.publicUserData.identifier} {mem.createdAt.toLocaleDateString()}
) } ```
The following example: 1. Calls the getMembershipRequests() method to retrieve the list of membership requests for the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. This method returns `data`, which is an array of OrganizationMembershipRequest objects. 2. Maps over the `data` array to display the membership requests in a table. 3. Provides an "Accept" and "Reject" button for each request that calls the accept() and reject() methods, respectively. Use the tabs to view the code necessary for the `index.html` and `main.js` files. ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

Membership Requests

User Date requested Accept Reject
``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!pubKey) { throw new Error('Add your VITE_CLERK_PUBLISHABLE_KEY to .env file') } const clerk = new Clerk('{{pub_key}}') await clerk.load() if (clerk.isSignedIn) { // Check for an Active Organization if (clerk.organization) { const requestsTable = document.getElementById('requests-table-body') const { data } = await clerk.organization .getMembershipRequests() .then((res) => console.log(`Membership requests:`, data).catch((err) => console.error(err))) const requests = data requests.map((request) => { const row = requestsTable.insertRow() row.insertCell().textContent = request.publicUserData.identifier row.insertCell().textContent = request.createdAt.toLocaleDateString() // Accept request const acceptBtn = document.createElement('button') acceptBtn.textContent = 'Accept' acceptBtn.addEventListener('click', async function (e) { e.preventDefault() await request.accept() }) row.insertCell().appendChild(acceptBtn) // Reject request const rejectBtn = document.createElement('button') rejectBtn.textContent = 'Reject' rejectBtn.addEventListener('click', async function (e) { e.preventDefault() await request.reject() }) row.insertCell().appendChild(rejectBtn) }) } else { // If there is no Active Organization, // mount Clerk's // to allow the user to set an organization as active document.getElementById('app').innerHTML = `

Select an organization to set it as active

` const orgSwitcherDiv = document.getElementById('org-switcher') clerk.mountOrganizationSwitcher(orgSwitcherDiv) } } else { // If there is no active user, mount Clerk's document.getElementById('app').innerHTML = `
` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ```
--- title: Build a custom flow for creating and managing Organization invitations description: Learn how to use the Clerk API to build a custom flow for creating and managing Organization invitations. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/organizations/manage-organization-invitations sourceFile: /docs/guides/development/custom-flows/organizations/manage-organization-invitations.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. Organization members with appropriate [Permissions](/docs/guides/organizations/roles-and-permissions) can invite new users to their Organization and manage those invitations. The invitation recipient can be either an existing user of your application or a new user. If they are a new user, they will need to sign up in order to accept the invitation. Users with the appropriate Permissions can also revoke Organization invitations for users that have not yet joined, which will prevent the user from becoming an Organization member. This guide will demonstrate how to use the Clerk API to build a custom flow for inviting users to an Organization and managing an Organization's pending invitations. > \[!NOTE] > This guide is for creating and managing Organization invitations client-side. You can also create an Organization invitation using the Backend API. See the [Organization invitations reference](/docs/guides/organizations/invitations) for more information. > > Also, see the [custom flow for accepting Organization invitations](/docs/guides/development/custom-flows/organizations/accept-organization-invitations). To invite a user: 1. Use the useOrganization() hook to get `organization`, which is the Active Organization'sA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. 2. Use `organization` to call the inviteMember() method, with the recipient's email address and desired Role passed as arguments. To revoke an invitation: 1. Use the `useOrganization()` hook to get `invitations`, which is a list of invitations for the Active Organization'sA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. 2. `invitations` is an array of OrganizationInvitation objects. Each `OrganizationInvitation` object has a revoke() method that can be called to revoke the invitation. The following example includes: * An `` component that allows administrators to invite new members to their Organization. * An `` component that lists all pending invitations and allows administrators to revoke them. This example is written for Next.js App Router but can be adapted for any React-based framework. ```tsx {{ filename: 'app/components/InvitationList.tsx', collapsible: true }} 'use client' import { useOrganization } from '@clerk/nextjs' import { OrganizationCustomRoleKey } from '@clerk/types' import { ChangeEventHandler, useEffect, useRef, useState } from 'react' export const OrgMembersParams = { memberships: { pageSize: 5, keepPreviousData: true, }, } export const OrgInvitationsParams = { invitations: { pageSize: 5, keepPreviousData: true, }, } // Form to invite a new member to the organization. export const InviteMember = () => { const { isLoaded, organization, invitations } = useOrganization(OrgInvitationsParams) const [emailAddress, setEmailAddress] = useState('') const [disabled, setDisabled] = useState(false) if (!isLoaded || !organization) { return <>Loading } const onSubmit = async (e: React.ChangeEvent) => { e.preventDefault() const submittedData = Object.fromEntries(new FormData(e.currentTarget).entries()) as { email: string | undefined role: OrganizationCustomRoleKey | undefined } if (!submittedData.email || !submittedData.role) { return } setDisabled(true) await organization.inviteMember({ emailAddress: submittedData.email, role: submittedData.role, }) await invitations?.revalidate?.() setEmailAddress('') setDisabled(false) } return (
setEmailAddress(e.target.value)} /> ) } type SelectRoleProps = { fieldName?: string isDisabled?: boolean onChange?: ChangeEventHandler defaultRole?: string } const SelectRole = (props: SelectRoleProps) => { const { fieldName, isDisabled = false, onChange, defaultRole } = props const { organization } = useOrganization() const [fetchedRoles, setRoles] = useState([]) const isPopulated = useRef(false) useEffect(() => { if (isPopulated.current) return organization ?.getRoles({ pageSize: 20, initialPage: 1, }) .then((res) => { isPopulated.current = true setRoles(res.data.map((roles) => roles.key as OrganizationCustomRoleKey)) }) }, [organization?.id]) if (fetchedRoles.length === 0) return null return ( ) } // List of pending invitations to an organization. export const InvitationList = () => { const { isLoaded, invitations, memberships } = useOrganization({ ...OrgInvitationsParams, ...OrgMembersParams, }) if (!isLoaded) { return <>Loading } return ( <> {invitations?.data?.map((inv) => ( ))}
User Invited Role Actions
{inv.emailAddress} {inv.createdAt.toLocaleDateString()} {inv.role}
) } ```
To check if the current user is an Organization admin: 1. Get the Active Organization'sA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. ID from the `clerk` object. 2. Call the getOrganizationMemberships() method to get a list of Organizations that the user is a member of. This method returns `data`, which is an array of `OrganizationMembership` objects. 3. In the list of Organizations that the user is a member of, find the `OrganizationMembership` object that has an ID that matches the Active Organization's ID. 4. Check the `role` property of the `OrganizationMembership` object to see if the user is an admin. To invite a user: 1. Use the active `organization` object to call the inviteMember() method, with the recipient's email address and desired Role passed as arguments. To revoke an invitation: 1. Use the active `organization` object to call the getInvitations() method to get an array of `OrganizationInvitation` objects. 2. Each `OrganizationInvitation` object has a revoke() method that can be called to revoke the invitation. The following example includes: * A `renderInvitations()` function that lists all invitations and allows administrators to revoke them. * An `checkAdminAndRenderInvitations()` function that gets the current Organization, checks if the current user is an admin, renders invitations, and sets up a form that allows administrators to invite new members to their Organization. Use the tabs to view the code necessary for the `index.html` and `main.js` files. ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

Invitations List

    Send a new invitation

    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!pubKey) { throw new Error('Add your VITE_CLERK_PUBLISHABLE_KEY to .env file') } const clerk = new Clerk('{{pub_key}}') await clerk.load() if (clerk.isSignedIn) { // Check for an Active Organization if (clerk.organization) { // Render list of organization invitations async function renderInvitations(organization, isAdmin) { const list = document.getElementById('invitations_list') try { const { data } = await organization.getInvitations() const invitations = data if (invitations.length === 0) { list.textContent = 'No invitations' } invitations.map((invitation) => { const li = document.createElement('li') li.textContent = `${invitation.emailAddress} - ${invitation.role}` // Add administrative actions; revoke invitation if (isAdmin) { const revokeBtn = document.createElement('button') revokeBtn.textContent = 'Revoke' revokeBtn.addEventListener('click', async function (e) { e.preventDefault() await invitation.revoke() }) li.appendChild(revokeBtn) } // Add the entry to the list list.appendChild(li) }) } catch (err) { console.error(err) } } // Gets the current org, checks if the current user is an admin, // renders invitations, and sets up the new invitation form. async function checkAdminAndRenderInvitations() { // This is the current organization ID. const organizationId = clerk.organization.id const { data } = await clerk.user.getOrganizationMemberships() const organizationMemberships = data const currentMembership = organizationMemberships.find( (membership) => membership.organization.id === organizationId, ) const currentOrganization = currentMembership.organization if (!currentOrganization) return const isAdmin = currentMembership.role === 'org:admin' renderInvitations(currentOrganization, isAdmin) if (isAdmin) { const form = document.getElementById('new_invitation') form.addEventListener('submit', async function (e) { e.preventDefault() const inputEl = document.getElementById('email_address') if (!inputEl) return try { await currentOrganization.inviteMember({ emailAddress: inputEl.value, role: 'org:member', }) } catch (err) { console.error(err) } }) } } checkAdminAndRenderInvitations() } else { // If there is no Active Organization, // mount Clerk's // to allow the user to set an organization as active document.getElementById('app').innerHTML = `

    Select an organization to set it as active

    ` const orgSwitcherDiv = document.getElementById('org-switcher') clerk.mountOrganizationSwitcher(orgSwitcherDiv) } } else { // If there is no active user, mount Clerk's document.getElementById('app').innerHTML = `
    ` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ```
    ## Next steps Now that you've created a flow for managing Organization invitations, you might want to create a flow for accepting invitations. See the [dedicated custom flow guide](/docs/guides/development/custom-flows/organizations/accept-organization-invitations) for more information. --- title: Build a custom flow for managing member Roles in an Organization description: Learn how to use the Clerk API build a custom flow for managing member Roles in an Organization. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/organizations/manage-roles sourceFile: /docs/guides/development/custom-flows/organizations/manage-roles.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. Organization members with appropriate [Permissions](/docs/guides/organizations/roles-and-permissions#permissions) can manage a member's [Roles](/docs/guides/organizations/roles-and-permissions#roles) and remove members within an Organization. This guide will demonstrate how to use the Clerk API to build a custom flow for managing member Roles in an Organization. The following example: 1. Uses the useOrganization() hook to get `memberships`, which is a list of the Active Organization'sA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. memberships. * `memberships` is an object with `data` that contains an array of OrganizationMembership objects. * Each `OrganizationMembership` object has an update() and destroy() method to update the member's Role and remove the member from the Organization, respectively. 2. Maps over the `data` array to display the memberships in a table, providing an "Update Role" and "Remove Member" button for each membership that calls the `update()` and `destroy()` methods, respectively. This example is written for Next.js App Router but can be adapted for any React-based framework. ```tsx {{ filename: 'app/components/ManageRoles.tsx', collapsible: true }} 'use client' import { useState, useEffect, ChangeEventHandler, useRef } from 'react' import { useOrganization, useUser } from '@clerk/nextjs' import type { OrganizationCustomRoleKey } from '@clerk/types' export const OrgMembersParams = { memberships: { pageSize: 5, keepPreviousData: true, }, } // List of organization memberships. Administrators can // change member Roles or remove members from the Organization. export const ManageRoles = () => { const { user } = useUser() const { isLoaded, memberships } = useOrganization(OrgMembersParams) if (!isLoaded) { return <>Loading } return ( <>

    Memberships List

    {memberships?.data?.map((mem) => ( ))}
    User Joined Role Actions
    {mem.publicUserData.identifier} {mem.publicUserData.userId === user?.id && '(You)'} {mem.createdAt.toLocaleDateString()} { await mem.update({ role: e.target.value as OrganizationCustomRoleKey, }) await memberships?.revalidate() }} />
    ) } type SelectRoleProps = { fieldName?: string isDisabled?: boolean onChange?: ChangeEventHandler defaultRole?: string } const SelectRole = (props: SelectRoleProps) => { const { fieldName, isDisabled = false, onChange, defaultRole } = props const { organization } = useOrganization() const [fetchedRoles, setRoles] = useState([]) const isPopulated = useRef(false) useEffect(() => { if (isPopulated.current) return organization ?.getRoles({ pageSize: 20, initialPage: 1, }) .then((res) => { isPopulated.current = true setRoles(res.data.map((roles) => roles.key as OrganizationCustomRoleKey)) }) }, [organization?.id]) if (fetchedRoles.length === 0) return null return ( ) } ```
    The following example includes a `checkAdminAndRenderMemberships()` function that checks if the user is an admin of the currently active Organization and calls `renderMemberships()`. The `renderMemberships()` function lists the Organization's memberships and allows administrators to update a member's Role and remove a member from the Organization. Use the tabs to view the code necessary for the `index.html` and `main.js` files. ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Memberships List

    User ID User identifier Joined Role
    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!pubKey) { throw new Error('Add your VITE_CLERK_PUBLISHABLE_KEY to .env file') } const clerk = new Clerk('{{pub_key}}') await clerk.load() if (clerk.isSignedIn) { // Check for an Active Organization if (clerk.organization) { // Render list of organization memberships async function renderMemberships(organization, isAdmin) { try { const { data } = await organization.getMemberships() const memberships = data console.log(`getMemberships:`, memberships) memberships.map((membership) => { const membershipTable = document.getElementById('memberships-table-body') const row = membershipTable.insertRow() row.insertCell().textContent = membership.publicUserData.userId row.insertCell().textContent = membership.publicUserData.identifier row.insertCell().textContent = membership.createdAt.toLocaleDateString() row.insertCell().textContent = membership.role // Add administrative actions: // Add and remove a member, and update a member's Role. if (isAdmin) { // Show update and remove member buttons document.getElementById('update-role-head').removeAttribute('hidden') document.getElementById('remove-member-head').removeAttribute('hidden') // Get the user ID of the member const userId = membership.publicUserData.userId // Update a member's Role const updateBtn = document.createElement('button') updateBtn.textContent = 'Change role' updateBtn.addEventListener('click', async function (e) { e.preventDefault() const role = membership.role === 'org:admin' ? 'org:member' : 'org:admin' await organization .updateMember({ userId, role }) .then((res) => console.log(`updateMember response:`, res)) .catch((error) => console.log('An error occurred:', error)) }) row.insertCell().appendChild(updateBtn) // Remove a member const removeBtn = document.createElement('button') removeBtn.textContent = 'Remove' removeBtn.addEventListener('click', async function (e) { e.preventDefault() await organization .removeMember(userId) .then((res) => console.log(`removeMember response:`, res)) .catch((error) => console.log('An error occurred:', error)) }) row.insertCell().appendChild(removeBtn) } }) } catch (error) { console.log('An error occurred:', error) } } /** * Checks if a user is an admin of the * currently Active Organization and * renders the Organization's memberships. */ async function checkAdminAndRenderMemberships() { const organizationId = clerk.organization.id const { data } = await clerk.user.getOrganizationMemberships() const organizationMemberships = data const currentMembership = organizationMemberships.find( (membership) => membership.organization.id === organizationId, ) const currentOrganization = currentMembership.organization if (!currentOrganization) return const isAdmin = currentMembership.role === 'org:admin' console.log(`Current organization:`, currentOrganization) renderMemberships(currentOrganization, isAdmin) } checkAdminAndRenderMemberships() } else { // If there is no Active Organization, // mount Clerk's // to allow the user to set an Organization as active document.getElementById('app').innerHTML = `

    Select an Organization to set it as active

    ` const orgSwitcherDiv = document.getElementById('org-switcher') clerk.mountOrganizationSwitcher(orgSwitcherDiv) } } else { // If there is no active user, mount Clerk's document.getElementById('app').innerHTML = `
    ` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ```
    --- title: Build a custom flow for managing a user's Organization invitations description: Learn how to use the Clerk API to build a custom flow for managing a user's Organization invitations. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/organizations/manage-user-org-invitations sourceFile: /docs/guides/development/custom-flows/organizations/manage-user-org-invitations.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. This guide will demonstrate how to use the Clerk API to build a custom flow for managing a user's [Organization invitations](/docs/guides/organizations/overview#organization-invitations). The following example: 1. Uses the useOrganizationList() hook to get `userInvitations`, which is a list of the user's Organization invitations. * `userInvitations` is an object with `data` that contains an array of UserOrganizationInvitation objects. * Each `UserOrganizationInvitation` object has an accept() method that accepts the invitation to the Organization. 2. Maps over the `data` array to display the invitations in a table, providing an "Accept" button for each invitation that calls the `accept()` method. This example is written for Next.js App Router but can be adapted for any React-based framework. ```jsx {{ filename: 'app/components/UserInvitationsList.tsx', collapsible: true }} 'use client' import { useOrganizationList } from '@clerk/nextjs' import React from 'react' export default function UserInvitationsList() { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { infinite: true, keepPreviousData: true, }, }) if (!isLoaded || userInvitations.isLoading) { return <>Loading } return ( <>

    Organization invitations

    {userInvitations.data?.map((invitation) => ( ))}
    Email Organization name Role Actions
    {invitation.emailAddress} {invitation.publicOrganizationData.name} {invitation.role}
    ) } ```
    The following example: 1. Calls the getOrganizationInvitations() method to retrieve the list of Organization invitations for the active user. This method returns `data`, which is an array of UserOrganizationInvitation objects. 2. Maps over the `data` array to display the invitations in a table. 3. Provides an "Accept" button for each invitation that calls the accept() method. Use the following tabs to view the code necessary for the `index.html` and `main.js` files. ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Organization invitations

    Email Organization name Role Status Actions
    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!pubKey) { throw new Error('Add your VITE_CLERK_PUBLISHABLE_KEY to .env file') } const clerk = new Clerk('{{pub_key}}') await clerk.load() if (clerk.isSignedIn) { const { data } = await clerk.user.getOrganizationInvitations() const invitations = data invitations.map((invitation) => { const tableBody = document.getElementById('invitations-table-body') const row = tableBody.insertRow() row.insertCell().textContent = invitation.emailAddress row.insertCell().textContent = invitation.publicOrganizationData.name row.insertCell().textContent = invitation.role row.insertCell().textContent = invitation.status // Show accept button for pending invitations if (invitation.status === 'pending') { const acceptBtn = document.createElement('button') acceptBtn.textContent = 'Accept' acceptBtn.addEventListener('click', async function (e) { e.preventDefault() await invitation.accept() }) row.insertCell().appendChild(acceptBtn) } }) } else { // If there is no active user, mount Clerk's document.getElementById('app').innerHTML = `
    ` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ```
    --- title: Build a custom flow for switching Organizations description: Learn how to use the Clerk API to build a custom flow for switching between Organizations. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/organizations/organization-switcher sourceFile: /docs/guides/development/custom-flows/organizations/organization-switcher.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. This guide will demonstrate how to use the Clerk API to build a custom flow for switching between Organizations. Two examples are provided: one for a paginated list and one for an infinite list. The following examples: 1. Use the useOrganizationList() hook to get `memberships`, which is a list of the current user's Organization memberships. `memberships` returns `data`, which is an array of OrganizationMembership objects. 2. Map over the `data` array to display the user's Organization memberships in a table, providing a button that calls `setActive()` to set the selected Organization as the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. * If there are no Organizations, the [`` component (custom-flow version, not the Clerk component)](/docs/guides/development/custom-flows/organizations/create-organizations) is rendered to allow the user to create an Organization. The difference between the two examples is the parameters passed to the `useOrganizationList()` hook in order to determine how the list is paginated. * The "Paginated list" example provides a button to load more Organizations if there are more available. The `data` array is paginated and will only return the first 5 results, so the `fetchNext()` method is used to load more Organizations if they are available. * The "Infinite list" example sets the `infinite` option to `true` to enable infinite results. This example is written for Next.js App Router but can be adapted for any React-based framework. ```jsx {{ filename: 'app/components/CustomOrganizationSwitcher.tsx', collapsible: true }} 'use client' import { useAuth, useOrganizationList } from '@clerk/nextjs' import CreateOrganization from '../components/create-organization' // See /docs/guides/development/custom-flows/organizations/create-organizations for this component // List user's organization memberships export default function JoinedOrganizations() { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { // Set pagination parameters pageSize: 5, keepPreviousData: true, }, }) const { orgId } = useAuth() if (!isLoaded) { return

    Loading...

    } return ( <>

    Joined organizations

    {userMemberships?.data?.length > 0 && ( <> {userMemberships?.data?.map((mem) => ( ))}
    Identifier Organization Joined Role Set as active org
    {mem.publicUserData.identifier} {mem.organization.name} {mem.createdAt.toLocaleDateString()} {mem.role} {orgId === mem.organization.id ? ( ) : (

    Currently active

    )}
    )} {userMemberships?.data?.length === 0 && (

    No organizations found

    )} ) } ``` ```jsx {{ filename: 'app/components/CustomOrganizationSwitcher.tsx', collapsible: true }} 'use client' import { useAuth, useOrganizationList } from '@clerk/nextjs' import CreateOrganization from '../components/create-organization' // See /docs/guides/development/custom-flows/organizations/create-organizations for this component // List user's organization memberships export default function JoinedOrganizations() { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { // Set pagination parameters infinite: true, }, }) const { orgId } = useAuth() if (!isLoaded) { return

    Loading...

    } return ( <>

    Joined organizations

    {userMemberships?.data?.length > 0 && ( {userMemberships?.data?.map((mem) => ( ))}
    Identifier Organization Joined Role Set as active org
    {mem.publicUserData.identifier} {mem.organization.name} {mem.createdAt.toLocaleDateString()} {mem.role} {orgId === mem.organization.id ? ( ) : (

    Currently active

    )}
    )} {userMemberships?.data?.length === 0 && (

    No organizations found

    )} ) } ```
    The following example: 1. Calls the getOrganizationMemberships() method to retrieve the list of Organizations the current user is a part of. This method returns `data`, which is an array of OrganizationMembership objects. 2. Maps over the `data` array to display the user's Organization memberships in a list, providing a button that calls setActive() to set the selected Organization as the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization.. Use the tabs to view the code necessary for the `index.html` and `main.js` files. ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Joined organizations

    Identifier Organization Joined Role Set as active org
    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!pubKey) { throw new Error('Add your VITE_CLERK_PUBLISHABLE_KEY to .env file') } const clerk = new Clerk('{{pub_key}}') await clerk.load() if (clerk.isSignedIn) { // Check for an Active Organization if (clerk.organization) { const { data } = await clerk.user.getOrganizationMemberships() const memberships = data memberships.map((membership) => { const membershipTable = document.getElementById('memberships-table-body') const row = membershipTable.insertRow() row.insertCell().textContent = membership.publicUserData.identifier row.insertCell().textContent = membership.organization.name row.insertCell().textContent = membership.createdAt.toLocaleDateString() row.insertCell().textContent = membership.role // Set as Active Organization const addBtn = document.createElement('button') addBtn.textContent = 'Set as active' addBtn.addEventListener('click', async function (e) { e.preventDefault() await clerk .setActive({ organization: membership.organization.id }) .then((res) => { console.log('Set as active:', res) }) .catch((err) => { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) }) }) row.insertCell().appendChild(addBtn) }) } else { // If there is no Active Organization, // render a form to create an Organization document.getElementById('create-organization-container').removeAttribute('hidden') const form = document.getElementById('create-organization') form.addEventListener('submit', function (e) { e.preventDefault() const inputEl = document.getElementById('name') if (!inputEl) { // ... handle empty input return } clerk .createOrganization({ name: inputEl.value }) .then((res) => console.log(res)) .catch((error) => console.log('An error occurred:', error)) }) } } else { // If there is no active user, mount Clerk's // or add your sign-in custom flow document.getElementById('app').innerHTML = `
    ` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ```
    --- title: Build a custom flow for updating an Organization description: Learn how to use the Clerk API to build a custom flow for updating an Organization in your application. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/organizations/update-organizations sourceFile: /docs/guides/development/custom-flows/organizations/update-organizations.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. Organization members with appropriate [Permissions](/docs/guides/organizations/roles-and-permissions) can update an Organization. This guide will demonstrate how to use Clerk's API to build a custom flow for updating an Organization. The following example: 1. Uses the useOrganization() hook to fetch the active `organization`. 2. Uses `organization` to call the `update()` method with the desired name to update the Organization. To see what other attributes can be updated, see the update() reference doc. This example is written for Next.js App Router but can be adapted for any React-based framework. ```tsx {{ filename: 'app/components/UpdateOrganization.tsx', collapsible: true }} 'use client' import { useState, useEffect } from 'react' import { useRouter } from 'next/navigation' import { useOrganization } from '@clerk/nextjs' export default function UpdateOrganization() { const [name, setName] = useState('') const router = useRouter() const { organization } = useOrganization() useEffect(() => { if (!organization) { return } setName(organization.name) }, [organization]) if (!organization) { return null } async function submit(e: React.FormEvent) { e.preventDefault() try { await organization?.update({ name }) router.push(`/organizations/${organization?.id}`) } catch (err) { console.error(err) } } return (

    Update the current organization

    setName(e.target.value)} />
    ) } ```
    The following example uses the `organization.update()` method to update the Active Organization'sA user can be a member of multiple Organizations, but only one can be active at a time. The **Active Organization** determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. name. To see what other attributes can be updated, see the update() reference doc. Use the tabs to view the code necessary for the `index.html` and `main.js` files. ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Update the current organization

    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!pubKey) { throw new Error('Add your VITE_CLERK_PUBLISHABLE_KEY to .env file') } const clerk = new Clerk('{{pub_key}}') await clerk.load() if (clerk.isSignedIn) { // Check for an Active Organization if (clerk.organization) { const form = document.getElementById('update-organization') form.addEventListener('submit', function (e) { e.preventDefault() const inputEl = document.getElementById('name') if (!inputEl) { // ... handle empty input return } clerk.organization .update({ name: inputEl.value }) .then((res) => console.log(`Updated org:`, res)) .catch((error) => console.log('An error occurred:', error)) }) } else { // If there is no Active Organization, // mount Clerk's // to allow the user to set an organization as active document.getElementById('app').innerHTML = `

    Select an organization to set it as active

    ` const orgSwitcherDiv = document.getElementById('org-switcher') clerk.mountOrganizationSwitcher(orgSwitcherDiv) } } else { // If there is no active user, mount Clerk's document.getElementById('app').innerHTML = `
    ` const signInDiv = document.getElementById('sign-in') clerk.mountSignIn(signInDiv) } ```
    --- title: Build a custom flow for adding a new payment method description: Learn how to use the Clerk API to build a custom flow for adding a new payment method to a user's account. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/billing/add-new-payment-method sourceFile: /docs/guides/development/custom-flows/billing/add-new-payment-method.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. This guide will walk you through how to build a custom user interface that allows users to **add a new payment method to their account**. This is a common feature in a user's billing or account settings page, allowing them to pre-emptively add a payment method for future use. For the custom flow that allows users to add a new payment method **during checkout**, see the [dedicated guide](/docs/guides/development/custom-flows/billing/checkout-new-payment-method). ### Enable Billing Features To use Billing Features, you first need to ensure they are enabled for your application. Follow the [Billing documentation](/docs/guides/billing/overview) to enable them and set up your Plans. ### Add payment method flow To add a new payment method for a user, you must: 1. Set up the \ to create a context for the user's payment actions. 2. Render the \ to display the secure payment fields from your provider. 3. Use the usePaymentElement() hook to submit the form and create a payment token. 4. Use the useUser() hook to attach the newly created payment method to the user. The following example demonstrates how to create a billing page where a user can add a new payment method. It is split into two components: * **``**: Sets up the ``, which specifies that the payment actions within its children are `for` the `user`. * **``**: Renders the payment form and handles the submission logic. It uses `usePaymentElement()` to get the `submit` function and `useUser()` to get the `user` object. When the form is submitted, it first creates a payment token and then attaches it to the user. ", ""]}> ```tsx {{ filename: 'app/user/billing/page.tsx' }} import { ClerkLoaded } from '@clerk/nextjs' import { PaymentElementProvider } from '@clerk/nextjs/experimental' import { AddPaymentMethodForm } from './AddPaymentMethodForm' export default function Page() { return (

    Billing Settings

    ) } ``` ```tsx {{ filename: 'app/user/billing/AddPaymentMethodForm.tsx', collapsible: true }} 'use client' import { useUser } from '@clerk/nextjs' import { usePaymentElement, PaymentElement } from '@clerk/nextjs/experimental' import { useState } from 'react' export function AddPaymentMethodForm() { const { user } = useUser() const { submit, isFormReady } = usePaymentElement() const [isSubmitting, setIsSubmitting] = useState(false) const [error, setError] = useState(null) const handleAddPaymentMethod = async (e: React.FormEvent) => { e.preventDefault() if (!isFormReady || !user) { return } setError(null) setIsSubmitting(true) try { // 1. Submit the form to the payment provider to get a payment token const { data, error } = await submit() // Usually a validation error from stripe that you can ignore. if (error) { setIsSubmitting(false) return } // 2. Use the token to add the payment source to the user await user.addPaymentSource(data) // 3. Handle success (e.g., show a confirmation, clear the form) alert('Payment method added successfully!') } catch (err: any) { setError(err.message || 'An unexpected error occurred.') } finally { setIsSubmitting(false) } } return (

    Add a new payment method

    {error &&

    {error}

    } ) } ```
    ", ""]}> ```tsx {{ filename: 'src/pages/user/billing/page.tsx' }} import { ClerkLoaded } from '@clerk/clerk-react' import { PaymentElementProvider } from '@clerk/clerk-react/experimental' import { AddPaymentMethodForm } from './AddPaymentMethodForm' export default function Page() { return (

    Billing Settings

    ) } ``` ```tsx {{ filename: 'src/pages/user/billing/AddPaymentMethodForm.tsx', collapsible: true }} import { useUser } from '@clerk/clerk-react' import { usePaymentElement, PaymentElement } from '@clerk/clerk-react/experimental' import { useState } from 'react' export function AddPaymentMethodForm() { const { user } = useUser() const { submit, isFormReady } = usePaymentElement() const [isSubmitting, setIsSubmitting] = useState(false) const [error, setError] = useState(null) const handleAddPaymentMethod = async (e: React.FormEvent) => { e.preventDefault() if (!isFormReady || !user) { return } setError(null) setIsSubmitting(true) try { // 1. Submit the form to the payment provider to get a payment token const { data, error } = await submit() // Usually a validation error from stripe that you can ignore. if (error) { setIsSubmitting(false) return } // 2. Use the token to add the payment source to the user await user.addPaymentSource(data) // 3. Handle success (e.g., show a confirmation, clear the form) alert('Payment method added successfully!') } catch (err: any) { setError(err.message || 'An unexpected error occurred.') } finally { setIsSubmitting(false) } } return (

    Add a new payment method

    {error &&

    {error}

    } ) } ```
    --- title: Build a custom checkout flow with an existing payment method description: Learn how to use the Clerk API to build a custom checkout flow that allows users to checkout with an existing payment method. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/billing/checkout-existing-payment-method sourceFile: /docs/guides/development/custom-flows/billing/checkout-existing-payment-method.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. This guide will walk you through how to build a custom user interface for a checkout flow that allows users to checkout **with an existing payment method**. For the custom flow that allows users to **add a new payment method** during checkout, see the [dedicated guide](/docs/guides/development/custom-flows/billing/checkout-new-payment-method). ## Enable Billing Features To use Billing Features, you first need to ensure they are enabled for your application. Follow the [Billing documentation](/docs/guides/billing/overview) to enable them and setup your Plans. ## Checkout flow To create a checkout session with an existing payment method, you must: 1. Set up the checkout provider with Plan details. 2. Initialize the checkout session when the user is ready. 3. Fetch and display the user's existing payment methods. 4. Confirm the payment with the selected payment method. 5. Complete the checkout process and redirect the user. The following example: 1. Uses the useCheckout() hook to initiate and manage the checkout session. 2. Uses the usePaymentMethods() hook to fetch the user's existing payment methods. 3. Assumes that you have already have a valid `planId`, which you can acquire in many ways: * [Copy from the Clerk Dashboard](https://dashboard.clerk.com/~/billing/plans?tab=user). * Use the [Clerk Backend API](/docs/reference/backend-api/tag/commerce/get/commerce/plans#tag/commerce/get/commerce/plans){{ target: '_blank' }}. * Use the new usePlans() hook to get the Plan details. This example is written for Next.js App Router but can be adapted for any React-based framework. ```tsx {{ filename: 'app/checkout/page.tsx' }} 'use client' import * as React from 'react' import { SignedIn, ClerkLoaded } from '@clerk/nextjs' import { useRouter } from 'next/navigation' import { CheckoutProvider, useCheckout, usePaymentMethods } from '@clerk/nextjs/experimental' import { useMemo, useState } from 'react' export default function CheckoutPage() { return ( ) } function CustomCheckout() { const { checkout } = useCheckout() const { status } = checkout if (status === 'needs_initialization') { return } return (
    ) } function CheckoutInitialization() { const { checkout } = useCheckout() const { start, status, fetchStatus } = checkout if (status !== 'needs_initialization') { return null } return ( ) } function PaymentSection() { const { checkout } = useCheckout() const { data, isLoading } = usePaymentMethods({ for: 'user', pageSize: 20, }) const { isConfirming, confirm, finalize, error } = checkout const [isProcessing, setIsProcessing] = useState(false) const [paymentMethodId, setPaymentMethodId] = useState(null) const router = useRouter() const defaultMethod = useMemo(() => data?.find((method) => method.isDefault), [data]) const submitSelectedMethod = async () => { const paymentSourceId = paymentMethodId || defaultMethod?.id if (isProcessing || !paymentSourceId) return setIsProcessing(true) try { // Confirm checkout with payment method await confirm({ paymentSourceId }) // Complete checkout and redirect await finalize({ navigate: () => router.push('/dashboard'), }) } catch (error) { console.error('Payment failed:', error) } finally { setIsProcessing(false) } } if (isLoading) { return
    Loading...
    } return ( <> {error &&
    {error.message}
    } ) } function CheckoutSummary() { const { checkout } = useCheckout() const { plan, totals } = checkout if (!plan) { return null } return (

    Order Summary

    {plan.name} {totals.totalDueNow.currencySymbol} {totals.totalDueNow.amountFormatted}
    ) } ```
    --- title: Build a custom checkout flow with a new payment method description: Learn how to use the Clerk API to build a custom checkout flow that allows users to add a new payment method during checkout. lastUpdated: 2025-11-21T22:00:50.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/billing/checkout-new-payment-method sourceFile: /docs/guides/development/custom-flows/billing/checkout-new-payment-method.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. > \[!WARNING] > > Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend [pinning](/docs/pinning) your SDK and `clerk-js` package versions. This guide will walk you through how to build a custom user interface for a checkout flow that allows users to **add a new payment method during checkout**. For the custom flow that allows users to checkout **with an existing payment** method, see the [dedicated guide](/docs/guides/development/custom-flows/billing/checkout-existing-payment-method). For the custom flow that allows users to add a new payment method to their account, **outside of a checkout flow**, see the [dedicated guide](/docs/guides/development/custom-flows/billing/add-new-payment-method). ## Enable Billing Features To use Billing Features, you first need to ensure they are enabled for your application. Follow the [Billing documentation](/docs/guides/billing/overview) to enable them and setup your Plans. ## Checkout flow To create a checkout session with a new payment card, you must: 1. Set up the checkout provider with Plan details. 2. Initialize the checkout session when the user is ready. 3. Render the payment form for card collection. 4. Confirm the payment with the collected payment method. 5. Complete the checkout process and redirect the user. The following example: 1. Uses the useCheckout() hook to get to initiate and manage the checkout session. 2. Uses the usePaymentElement() hook to control the payment element, which is rendered by ``. 3. Assumes that you have already have a valid `planId`, which you can acquire in many ways. * [Copy from the Clerk Dashboard](https://dashboard.clerk.com/~/billing/plans?tab=user). * Use the [Clerk Backend API](/docs/reference/backend-api/tag/commerce/get/commerce/plans#tag/commerce/get/commerce/plans){{ target: '_blank' }}. * Use the new usePlans() hook to get the Plan details. This example is written for Next.js App Router but can be adapted for any React-based framework. ```tsx {{ filename: 'app/checkout/page.tsx' }} 'use client' import * as React from 'react' import { SignedIn, ClerkLoaded } from '@clerk/nextjs' import { CheckoutProvider, useCheckout, PaymentElementProvider, PaymentElement, usePaymentElement, } from '@clerk/nextjs/experimental' import { useRouter } from 'next/navigation' export default function CheckoutPage() { return ( ) } function CustomCheckout() { const { checkout } = useCheckout() const { status } = checkout if (status === 'needs_initialization') { return } return (
    ) } function CheckoutInitialization() { const { checkout } = useCheckout() const { start, status, fetchStatus } = checkout if (status !== 'needs_initialization') { return null } return ( ) } function PaymentSection() { const { checkout } = useCheckout() const { isConfirming, confirm, finalize, error } = checkout const { isFormReady, submit } = usePaymentElement() const [isProcessing, setIsProcessing] = React.useState(false) const router = useRouter() const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!isFormReady || isProcessing) return setIsProcessing(true) try { // Submit payment form to get payment method const { data, error } = await submit() // Usually a validation error from stripe that you can ignore if (error) { return } // Confirm checkout with payment method await confirm(data) // Complete checkout and redirect await finalize({ navigate: () => router.push('/dashboard'), }) } catch (error) { console.error('Payment failed:', error) } finally { setIsProcessing(false) } } return (
    Loading payment element...
    } /> {error &&
    {error.message}
    } ) } function CheckoutSummary() { const { checkout } = useCheckout() const { plan, totals } = checkout if (!plan) { return null } return (

    Order Summary

    {plan.name} {totals.totalDueNow.currencySymbol} {totals.totalDueNow.amountFormatted}
    ) } ``` --- title: Build a custom Google One Tap authentication flow description: Learn how to build a custom Google One Tap authentication flow using the Clerk API. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/google-one-tap sourceFile: /docs/guides/development/custom-flows/authentication/google-one-tap.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. [Google One Tap](https://developers.google.com/identity/gsi/web/guides/features) enables users to press a single button to authentication in your Clerk application with a Google account. This guide will walk you through how to build a custom Google One Tap authentication flow. ## Enable Google as a social connection To use Google One Tap with Clerk, follow the steps in the [dedicated guide](/docs/guides/configure/auth-strategies/social-connections/google#configure-for-your-production-instance) to configure Google as a social connection in the Clerk Dashboard using custom credentials. ## Create the Google One Tap authentication flow To authenticate users with Google One Tap, you must: 1. Initialize a ["Sign In With Google"](https://developers.google.com/identity/gsi/web/reference/js-reference) client UI, passing in your Client ID. 2. Use the response to authenticate the user in your Clerk app if the request was successful. 3. Redirect the user back to the page they started the authentication flow from by default, or to another URL if necessary. The following example creates a component that implements a custom Google One Tap authentication flow, which can be used in a sign-in or sign-up page. ```tsx {{ filename: 'app/components/CustomGoogleOneTap.tsx', collapsible: true }} 'use client' import { useClerk } from '@clerk/nextjs' import { useRouter } from 'next/navigation' import Script from 'next/script' import { useEffect } from 'react' // Add clerk to Window to avoid type errors declare global { interface Window { google: any } } export function CustomGoogleOneTap({ children }: { children: React.ReactNode }) { const clerk = useClerk() const router = useRouter() useEffect(() => { // Will show the One Tap UI after two seconds const timeout = setTimeout(() => oneTap(), 2000) return () => { clearTimeout(timeout) } }, []) const oneTap = () => { const { google } = window if (google) { google.accounts.id.initialize({ // Add your Google Client ID here. client_id: 'xxx-xxx-xxx', callback: async (response: any) => { // Here we call our provider with the token provided by Google call(response.credential) }, }) // Uncomment below to show the One Tap UI without // logging any notifications. // return google.accounts.id.prompt() // without listening to notification // Display the One Tap UI, and log any errors that occur. return google.accounts.id.prompt((notification: any) => { console.log('Notification ::', notification) if (notification.isNotDisplayed()) { console.log('getNotDisplayedReason ::', notification.getNotDisplayedReason()) } else if (notification.isSkippedMoment()) { console.log('getSkippedReason ::', notification.getSkippedReason()) } else if (notification.isDismissedMoment()) { console.log('getDismissedReason ::', notification.getDismissedReason()) } }) } } const call = async (token: any) => { try { const res = await clerk.authenticateWithGoogleOneTap({ token, }) await clerk.handleGoogleOneTapCallback(res, { signInFallbackRedirectUrl: '/example-fallback-path', }) } catch (error) { router.push('/sign-in') } } return ( <> ) } ``` You can then display this component on any page. The following example demonstrates a page that displays this component: ```tsx {{ filename: 'app/google-sign-in-example/page.tsx' }} import { CustomGoogleOneTap } from '@/app/components/CustomGoogleOneTap' export default function CustomOneTapPage({ children }: { children: React.ReactNode }) { return (

    Google One Tap Example

    ) } ```
    --- title: Build a custom flow for displaying the last authentication method description: Learn how to use the Clerk API to build a custom flow for displaying the `lastAuthenticationStrategy` property and highlighting the last used OAuth provider with a badge. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/last-authentication-strategy sourceFile: /docs/guides/development/custom-flows/authentication/last-authentication-strategy.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. The `Client` object includes a `lastAuthenticationStrategy` property that tracks the last authentication method used by the user. This is useful for improving the user experience by showing a "Last used" badge on OAuth buttons, helping returning users quickly identify their preferred sign-in method. ## Access the last authentication strategy The `lastAuthenticationStrategy` property is available on the Client object. You can access it through the `client` property of the Clerk instance. This example is written for Next.js App Router but it can be adapted for any React-based framework. The following example demonstrates how to: 1. Access the `client` object using the useClerk() hook. 2. Check the `lastAuthenticationStrategy` property to identify which OAuth provider was last used. 3. Display a badge next to the corresponding OAuth button. ```tsx {{ filename: 'app/sign-in/page.tsx' }} 'use client' import * as React from 'react' import { OAuthStrategy } from '@clerk/types' import { useSignIn, useClerk } from '@clerk/nextjs' export default function Page() { const { signIn } = useSignIn() const { client } = useClerk() if (!signIn) return null const lastStrategy = client?.lastAuthenticationStrategy const signInWith = (strategy: OAuthStrategy) => { return signIn.authenticateWithRedirect({ strategy, redirectUrl: '/sign-in/sso-callback', redirectUrlComplete: '/', }) } const providers = [ { strategy: 'oauth_google' as const, name: 'Google' }, { strategy: 'oauth_github' as const, name: 'GitHub' }, ] return (

    Sign in

    {providers.map((provider) => ( ))}
    ) } ```
    The following example demonstrates how to: 1. Access the `client` object from the `Clerk` instance. 2. Check the `lastAuthenticationStrategy` property to identify which OAuth provider was last used. 3. Display a badge next to the corresponding OAuth button. ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App
    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.user) { // User is already signed in document.getElementById('app').innerHTML = `
    ` clerk.mountUserButton(document.getElementById('user-button')) } else { const lastStrategy = clerk.client?.lastAuthenticationStrategy const providers = [ { strategy: 'oauth_google', name: 'Google' }, { strategy: 'oauth_github', name: 'GitHub' }, ] const buttons = providers .map( (provider) => ` `, ) .join('') document.getElementById('app').innerHTML = `

    Sign in

    ${buttons} ` providers.forEach((provider) => { document.getElementById(provider.strategy)?.addEventListener('click', async () => { try { await clerk.client.signIn.authenticateWithRedirect({ strategy: provider.strategy, redirectUrl: '/sso-callback', redirectUrlComplete: '/', }) } catch (error) { console.error('Error:', error) } }) }) } ```
    --- title: Build a custom multi-session flow description: Learn how to use the Clerk API to add multi-session handling to your application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/multi-session-applications sourceFile: /docs/guides/development/custom-flows/authentication/multi-session-applications.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. A multi-session application is an application that allows multiple accounts to be signed in from the same browser at the same time. The user can switch from one account to another seamlessly. Each account is independent from the rest and has access to different resources. This guide provides you with the necessary information to build a custom multi-session flow using the Clerk API. To implement the multi-session feature to your application, you need to handle the following scenarios: * [Switching between different accounts](#switch-between-sessions) * [Adding new accounts](#add-a-new-session) * [Signing out from one account, while remaining signed in to the rest](#sign-out-active-session) * [Signing out from all accounts](#sign-out-all-sessions) ## Enable multi-session in your application To enable multi-session in your application, you need to configure it in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**Sessions**](https://dashboard.clerk.com/~/sessions) page. 2. Toggle on **Multi-session handling**. 3. Select **Save changes**. ## Get the session and user ```jsx import { useClerk } from '@clerk/clerk-react' // Get the session and user const { session, user } = useClerk() ``` ```js // Get the session const currentSession = window.Clerk.session // Get the user const currentUser = window.Clerk.user ``` ```swift // Get the current session var currentSession: Session? { Clerk.shared.session } // Get the current user var currentUser: User? { Clerk.shared.user } ``` ## Switch between sessions ```jsx import { useClerk } from '@clerk/clerk-react' const { client, setActive } = useClerk() // You can get all the available sessions through the client const availableSessions = client.sessions const currentSession = availableSessions[0].id // Use setActive() to set the session as active await setActive({ session: currentSession.id, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } router.push('/') }, }) ``` ```js // You can get all the available sessions through the client const availableSessions = window.Clerk.client.sessions // Use setActive() to set the session as active await window.Clerk.setActive({ session: availableSessions[0].id, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } router.push('/') }, }) ``` ```swift // You can get all the available sessions through the client var availableSessions: [Session] { Clerk.shared.client?.sessions ?? [] } // Use setActive() to set the session as active try await Clerk.shared.setActive(sessionId: session.id) ``` ## Add a new session To add a new session, simply link to your existing sign-in flow. New sign-ins will automatically add to the list of available sessions on the client. To create a sign-in flow, see one of the following popular guides: * [Email and password](/docs/guides/development/custom-flows/authentication/email-password) * [Passwordless authentication](/docs/guides/development/custom-flows/authentication/email-sms-otp) * [Social sign-in (OAuth)](/docs/guides/configure/auth-strategies/social-connections/overview) For more information on how Clerk's sign-in flow works, see the [detailed sign-in guide](/docs/guides/development/custom-flows/overview#sign-in-flow). ## Sign out all sessions Use signOut() to deactivate all sessions on the current client. ```jsx import { useClerk } from '@clerk/clerk-react' const { signOut, session } = useClerk() // Use signOut to sign-out all active sessions. await signOut() ``` ```js // Use signOut to sign-out all active sessions. await window.Clerk.signOut() ``` ```swift // Use signOut to sign-out all active sessions. try await Clerk.shared.signOut() ``` ## Sign out active session Use signOut() to deactivate a specific session by passing the session ID. ```jsx import { useClerk } from '@clerk/clerk-react' // Get the signOut method and the active session const { signOut, session } = useClerk() // Use signOut to sign-out the active session await signOut(session.id) ``` ```js // Get the current session const currentSession = window.Clerk.session // Use signOut to sign-out the active session await window.Clerk.signOut(currentSession.id) ``` ```swift // Use signOut to sign-out a specific session try await Clerk.shared.signOut(sessionId: session.id) ``` --- title: Build a custom flow for authenticating with OAuth connections description: Learn how to use the Clerk API to build a custom sign-up and sign-in flow that supports OAuth connections. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/oauth-connections sourceFile: /docs/guides/development/custom-flows/authentication/oauth-connections.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. ## Before you start You must configure your application instance through the Clerk Dashboard for the social connection(s) that you want to use. Visit [the appropriate guide for your platform](/docs/guides/configure/auth-strategies/social-connections/all-providers) to learn how to configure your instance. ## Create the sign-up and sign-in flow First, in your `.env` file, set the `NEXT_PUBLIC_CLERK_SIGN_IN_URL` environment variable to tell Clerk where the sign-in page is being hosted. Otherwise, your app may default to using the [Account Portal sign-in page](/docs/guides/customizing-clerk/account-portal#sign-in) instead. This guide uses the `/sign-in` route. ```env {{ filename: '.env' }} NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in ``` The following example **will both sign up *and* sign in users**, eliminating the need for a separate sign-up page. However, if you want to have separate sign-up and sign-in pages, the sign-up and sign-in flows are equivalent, meaning that all you have to do is swap out the `SignIn` object for the `SignUp` object using the useSignUp() hook. The following example: 1. Accesses the SignIn object using the useSignIn() hook. 2. Starts the authentication process by calling SignIn.authenticateWithRedirect(params). This method requires a `redirectUrl` param, which is the URL that the browser will be redirected to once the user authenticates with the identity provider. 3. Creates a route at the URL that the `redirectUrl` param points to. The following example names this route `/sso-callback`. This route should either render the prebuilt \ component or call the Clerk.handleRedirectCallback() method if you're not using the prebuilt component. The following example shows two files: 1. The sign-in page where the user can start the authentication flow. 2. The SSO callback page where the flow is completed. ```tsx {{ filename: 'app/sign-in/page.tsx' }} 'use client' import * as React from 'react' import { OAuthStrategy } from '@clerk/types' import { useSignIn } from '@clerk/nextjs' export default function Page() { const { signIn } = useSignIn() if (!signIn) return null const signInWith = (strategy: OAuthStrategy) => { return signIn .authenticateWithRedirect({ strategy, redirectUrl: '/sign-in/sso-callback', redirectUrlComplete: '/sign-in/tasks', // Learn more about session tasks at https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks }) .then((res) => { console.log(res) }) .catch((err: any) => { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.log(err.errors) console.error(err, null, 2) }) } // Render a button for each supported OAuth provider // you want to add to your app. This example uses only Google. return (
    ) } ``` ```tsx {{ filename: 'app/sign-in/sso-callback/page.tsx' }} import { AuthenticateWithRedirectCallback } from '@clerk/nextjs' export default function Page() { // Handle the redirect flow by calling the Clerk.handleRedirectCallback() method // or rendering the prebuilt component. return ( <> {/* Required for sign-up flows Clerk's bot sign-up protection is enabled by default */}
    ) } ``` The following example **will both sign up *and* sign in users**, eliminating the need for a separate sign-up page. The following example: 1. Uses the useSSO() hook to access the `startSSOFlow()` method. 2. Calls the `startSSOFlow()` method with the `strategy` param set to `oauth_google`, but you can use any of the supported OAuth strategies. The optional `redirect_url` param is also set in order to redirect the user once they finish the authentication flow. * If authentication is successful, the `setActive()` method is called to set the active session with the new `createdSessionId`. * If authentication is not successful, you can [handle the missing requirements](#handle-missing-requirements), such as MFA, using the signIn or signUp object returned from `startSSOFlow()`, depending on if the user is signing in or signing up. These objects include properties, like `status`, that can be used to determine the next steps. See the respective linked references for more information. ```tsx {{ filename: 'app/(auth)/sign-in.tsx', collapsible: true }} import React, { useCallback, useEffect } from 'react' import * as WebBrowser from 'expo-web-browser' import * as AuthSession from 'expo-auth-session' import { useSSO } from '@clerk/clerk-expo' import { View, Button, Platform } from 'react-native' // Preloads the browser for Android devices to reduce authentication load time // See: https://docs.expo.dev/guides/authentication/#improving-user-experience export const useWarmUpBrowser = () => { useEffect(() => { if (Platform.OS !== 'android') return void WebBrowser.warmUpAsync() return () => { // Cleanup: closes browser when component unmounts void WebBrowser.coolDownAsync() } }, []) } // Handle any pending authentication sessions WebBrowser.maybeCompleteAuthSession() export default function Page() { useWarmUpBrowser() // Use the `useSSO()` hook to access the `startSSOFlow()` method const { startSSOFlow } = useSSO() const onPress = useCallback(async () => { try { // Start the authentication process by calling `startSSOFlow()` const { createdSessionId, setActive, signIn, signUp } = await startSSOFlow({ strategy: 'oauth_google', // For web, defaults to current path // For native, you must pass a scheme, like AuthSession.makeRedirectUri({ scheme, path }) // For more info, see https://docs.expo.dev/versions/latest/sdk/auth-session/#authsessionmakeredirecturioptions redirectUrl: AuthSession.makeRedirectUri(), }) // If sign in was successful, set the active session if (createdSessionId) { setActive!({ session: createdSessionId, // Check for session tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks navigate: async ({ session }) => { if (session?.currentTask) { console.log(session?.currentTask) router.push('/sign-in/tasks') return } router.push('/') }, }) } else { // If there is no `createdSessionId`, // there are missing requirements, such as MFA // See https://clerk.com/docs/guides/development/custom-flows/authentication/oauth-connections#handle-missing-requirements } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } }, []) return (
    ) } // Handle other statuses if needed return ( <> {/* Required for sign-up flows Clerk's bot sign-up protection is enabled by default */}
    ) } ``` ```tsx {{ filename: 'app/sign-in/sso-callback/page.tsx' }} import { AuthenticateWithRedirectCallback } from '@clerk/nextjs' export default function Page() { // Set the `continueSignUpUrl` to the route of your "Continue" page // Once a user authenticates with the OAuth provider, they will be redirected to that route return ( <> {/* Required for sign-up flows Clerk's bot sign-up protection is enabled by default */}
    ) } ``` --- title: Build a custom flow for handling legal acceptance description: Learn how to use the Clerk API to build a custom user interface for handling legal acceptance. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/legal-acceptance sourceFile: /docs/guides/development/custom-flows/authentication/legal-acceptance.mdx --- When the legal acceptance feature is enabled, users are required to agree to your Terms of Service and Privacy Policy before they can sign up to your application. If you're using the `` component, a checkbox appears and the legal acceptance flow is handled for you. However, if you're building a custom user interface, you need to handle legal acceptance in your sign-up form. This guide demonstrates how to use the Clerk API to build a custom user interface for handling legal acceptance. ## Before you start By default, the legal acceptance feature is disabled. To enable it, navigate to the [**Legal**](https://dashboard.clerk.com/~/compliance/legal) page in the Clerk Dashboard. ## Add legal acceptance to your sign-up flow To support legal acceptance, you need to add a checkbox to your sign-up form, capture the checkbox value, and pass it to the SignUp.create() method. The following example adds the legal acceptance logic to the [Email and password custom flow](/docs/guides/development/custom-flows/authentication/email-password), but you can apply the same logic to any custom flow. This example is written for Next.js App Router but it can be adapted for any React-based framework. ```tsx {{ filename: 'app/sign-up/[[...sign-up]]/page.tsx', mark: [12, 28, [129, 141]], collapsible: true }} 'use client' import * as React from 'react' import { useSignUp } from '@clerk/nextjs' import { useRouter } from 'next/navigation' import Link from 'next/link' export default function Page() { const { isLoaded, signUp, setActive } = useSignUp() const [emailAddress, setEmailAddress] = React.useState('') const [password, setPassword] = React.useState('') const [legalAccepted, setLegalAccepted] = React.useState(false) const [verifying, setVerifying] = React.useState(false) const [code, setCode] = React.useState('') const router = useRouter() // Handle submission of the sign-up form const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!isLoaded) return
    Loading...
    // Start the sign-up process using the email and password provided try { await signUp.create({ emailAddress, password, legalAccepted, }) // Send the user an email with the verification code await signUp.prepareEmailAddressVerification({ strategy: 'email_code', }) // Set 'verifying' true to display second form // and capture the OTP code setVerifying(true) } catch (err: any) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } // Handle the submission of the verification form const handleVerify = async (e: React.FormEvent) => { e.preventDefault() if (!isLoaded) return
    Loading...
    try { // Use the code the user provided to attempt verification const signUpAttempt = await signUp.attemptEmailAddressVerification({ code, }) // If verification was completed, set the session to active // and redirect the user if (signUpAttempt.status === 'complete') { await setActive({ session: signUpAttempt.createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for session tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) router.push('/sign-up/tasks') return } router.push('/') }, }) } else { // If the status is not complete, check why. User may need to // complete further steps. console.error('Sign-up attempt not complete:', signUpAttempt) console.error('Sign-up attempt status:', signUpAttempt.status) } } catch (err: any) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } // Display the verification form to capture the OTP code if (verifying) { return ( <>

    Verify your email

    setCode(e.target.value)} />
    ) } // Display the initial sign-up form to capture the email and password return ( <>

    Sign up

    setEmailAddress(e.target.value)} />
    setPassword(e.target.value)} />
    setLegalAccepted(e.target.checked)} />
    {/* Required for sign-up flows Clerk's bot sign-up protection is enabled by default */}
    ) } ``` --- title: Build a custom authentication flow using passkeys description: Learn how to use the Clerk API to build a custom authentication flow using passkeys. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/passkeys sourceFile: /docs/guides/development/custom-flows/authentication/passkeys.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. Clerk supports passwordless authentication via [passkeys](/docs/guides/configure/auth-strategies/sign-up-sign-in-options#passkeys), enabling users to sign in without having to remember a password. Instead, users select a passkey associated with their device, which they can use to authenticate themselves. This guide demonstrates how to use the Clerk API to build a custom user interface for creating, signing users in with, and managing passkeys. ## Enable passkeys To use passkeys, first enable the strategy in the [Clerk Dashboard](https://dashboard.clerk.com/~/user-authentication/user-and-authentication?user_auth_tab=passkeys). When setting up passkeys with Android, there are a few additional steps to follow. Learn more about passkeys for Android. When setting up passkeys with Expo, there are a few additional steps to follow. Learn more about passkeys for Expo. ### Domain restrictions for passkeys Passkeys are tied to the domain they are created on and **cannot be used across different domains**. However, passkeys **do work on subdomains** if they are registered on the root domain. For example: * Passkeys created on `your-domain.com` **cannot be used** on `your-domain-admin.com` (different domains). * Passkeys created on `your-domain.com` **can be used** on `accounts.your-domain.com` (subdomain of the same root domain). * Passkeys created on `staging1.your-domain.com` **cannot be used** on `staging2.your-domain.com` (sibling subdomains) unless the passkey was scoped to `your-domain.com` (i.e. the shared root domain). **If you're using [satellite domains](/docs/guides/dashboard/dns-domains/satellite-domains)**, in both development and production, passkeys won't be portable between your primary domain and your satellite domains so you should avoid using them. If you're **not** using satellite domains: * **In development**, you can either: * **The recommended approach**. Use Clerk's components, [Elements](/docs/guides/customizing-clerk/elements/overview), or custom flowsA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview)., instead of the [Account Portal](/docs/guides/customizing-clerk/account-portal). This ensures the passkey is created and used entirely on your development domain, so passkeys created on `localhost` will only work on `localhost`. * Create a passkey directly through the Account Portal instead of your local application to keep it tied to the Account Portal's domain. Passkeys created on your Account Portal (e.g., `your-app.accounts.dev`) will only work on that domain, which can cause issues if you switch between `localhost` and the Account Portal during development. If you choose this approach, ensure all testing happens on the same domain where the passkey was created. * **In production,** your Account Portal is usually hosted on a subdomain of your main domain (e.g. `accounts.your-domain.com`), enabling passkeys to work seamlessly across your app. However, as stated above, if you use **satellite domains**, passkeys will not work as intended. ## Create user passkeys To create a passkey for a user, you must call User.createPasskey(), as shown in the following example: ```tsx {{ filename: 'app/components/CustomCreatePasskeysButton.tsx' }} export function CreatePasskeyButton() { const { isSignedIn, user } = useUser() const createClerkPasskey = async () => { if (!isSignedIn) { // Handle signed out state return } try { await user?.createPasskey() } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) } } return } ``` ## Sign a user in with a passkey To sign a user into your Clerk app with a passkey, you must call SignIn.authenticateWithPasskey(). This method allows users to choose from their discoverable passkeys, such as hardware keys or passkeys in password managers. ```tsx {{ filename: 'components/SignInWithPasskeyButton.tsx' }} export function SignInWithPasskeyButton() { const { signIn } = useSignIn() const router = useRouter() const signInWithPasskey = async () => { // 'discoverable' lets the user choose a passkey // without auto-filling any of the options try { const signInAttempt = await signIn?.authenticateWithPasskey({ flow: 'discoverable', }) if (signInAttempt?.status === 'complete') { await setActive({ session: signInAttempt.createdSessionId, redirectUrl: '/', navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } router.push('/') }, }) } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(JSON.stringify(signInAttempt, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) } } return } ``` ## Rename user passkeys Clerk generates a name based on the device associated with the passkey when it's created. Sometimes users may want to rename a passkey to make it easier to identify. To rename a user's passkey in your Clerk app, you must call the update() method of the passkey object, as shown in the following example: ```tsx {{ filename: 'components/RenamePasskeyUI.tsx' }} export function RenamePasskeyUI() { const { user } = useUser() const { passkeys } = user const passkeyToUpdateId = useRef(null) const newPasskeyName = useRef(null) const [success, setSuccess] = useState(false) const renamePasskey = async () => { try { const passkeyToUpdate = passkeys?.find( (pk: PasskeyResource) => pk.id === passkeyToUpdateId.current?.value, ) await passkeyToUpdate?.update({ name: newPasskeyName.current?.value, }) setSuccess(true) } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) setSuccess(false) } } return ( <>

    Passkeys:

      {passkeys?.map((pk: PasskeyResource) => { return (
    • Name: {pk.name} | ID: {pk.id}
    • ) })}

    Passkey updated: {success ? 'Yes' : 'No'}

    ) } ``` ## Delete user passkeys To delete a user's passkey from your Clerk app, you must call the delete() method of the passkey object, as shown in the following example: ```tsx {{ filename: 'components/DeletePasskeyUI.tsx' }} export function DeletePasskeyUI() { const { user } = useUser() const { passkeys } = user const passkeyToDeleteId = useRef(null) const [success, setSuccess] = useState(false) const deletePasskey = async () => { const passkeyToDelete = passkeys?.find((pk: any) => pk.id === passkeyToDeleteId.current?.value) try { await passkeyToDelete?.delete() setSuccess(true) } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) setSuccess(false) } } return ( <>

    Passkeys:

      {passkeys?.map((pk: any) => { return (
    • Name: {pk.name} | ID: {pk.id}
    • ) })}

    Passkey deleted: {success ? 'Yes' : 'No'}

    ) } ``` --- title: Build a custom email or SMS OTP authentication flow description: Learn how build a custom email or SMS one time code (OTP) authentication flow using the Clerk API. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/email-sms-otp sourceFile: /docs/guides/development/custom-flows/authentication/email-sms-otp.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. Clerk supports passwordless authentication, which lets users sign in and sign up without having to remember a password. Instead, users receive a one-time password (OTP), also known as a one-time code, via email or SMS, which they can use to authenticate themselves. This guide will walk you through how to build a custom SMS OTP sign-up and sign-in flow. The process for using email OTP is similar, and the differences will be highlighted throughout. > \[!WARNING] > Phone numbers must be in [E.164 format](https://en.wikipedia.org/wiki/E.164). ## Enable SMS OTP To use SMS OTP, you first need to enable it for your application. 1. In the Clerk Dashboard, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page. 2. Select the **Phone** tab and enable **Sign-up with phone** and **Sign-in with phone** and keep the default settings. ## Sign-up flow To sign up a user using an OTP, you must: 1. Initiate the sign-up process by collecting the user's identifier, which for this example is a phone number. 2. Prepare the verification, which sends a one-time code to the given identifier. 3. Attempt to complete the verification with the code the user provides. 4. If the verification is successful, set the newly created session as the active session. This example is written for Next.js App Router but it can be adapted to any React-based framework. ```tsx {{ filename: 'app/sign-up/[[...sign-up]]/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useSignUp } from '@clerk/nextjs' import { useRouter } from 'next/navigation' export default function Page() { const { isLoaded, signUp, setActive } = useSignUp() const [verifying, setVerifying] = React.useState(false) const [phone, setPhone] = React.useState('') const [code, setCode] = React.useState('') const router = useRouter() async function handleSubmit(e: React.FormEvent) { e.preventDefault() if (!isLoaded && !signUp) return null try { // Start the sign-up process using the phone number method await signUp.create({ phoneNumber: phone, }) // Start the verification - a SMS message will be sent to the // number with a one-time code await signUp.preparePhoneNumberVerification() // Set verifying to true to display second form and capture the OTP code setVerifying(true) } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) } } async function handleVerification(e: React.FormEvent) { e.preventDefault() if (!isLoaded && !signUp) return null try { // Use the code provided by the user and attempt verification const signUpAttempt = await signUp.attemptPhoneNumberVerification({ code, }) // If verification was completed, set the session to active // and redirect the user if (signUpAttempt.status === 'complete') { await setActive({ session: signUpAttempt.createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } await router.push('/') }, }) } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(signUpAttempt) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) } } if (verifying) { return ( <>

    Verify your phone number

    setCode(e.target.value)} />
    ) } return ( <>

    Sign up

    setPhone(e.target.value)} />
    ) } ```
    ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Sign up

    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Mount user button component document.getElementById('signed-in').innerHTML = `
    ` const userbuttonDiv = document.getElementById('user-button') clerk.mountUserButton(userbuttonDiv) } else if (clerk.session?.currentTask) { // Check for pending tasks and display custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks switch (clerk.session.currentTask.key) { case 'choose-organization': { document.getElementById('app').innerHTML = `
    ` const taskDiv = document.getElementById('task') clerk.mountTaskChooseOrganization(taskDiv) } } } else { // Handle the sign-up form document.getElementById('sign-up-form').addEventListener('submit', async (e) => { e.preventDefault() const formData = new FormData(e.target) const phoneNumber = formData.get('phone') try { // Start the sign-up process using the phone number method await clerk.client.signUp.create({ phoneNumber }) await clerk.client.signUp.preparePhoneNumberVerification() // Hide sign-up form document.getElementById('sign-up').setAttribute('hidden', '') // Show verification form document.getElementById('verifying').removeAttribute('hidden') } catch (error) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(error) } }) // Handle the verification form document.getElementById('verifying').addEventListener('submit', async (e) => { const formData = new FormData(e.target) const code = formData.get('code') try { // Verify the phone number const verify = await clerk.client.signUp.attemptPhoneNumberVerification({ code, }) // Now that the user is created, set the session to active. await clerk.setActive({ session: verify.createdSessionId }) } catch (error) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(error) } }) } ```
    ```swift {{ filename: 'SMSOTPSignUpView.swift', collapsible: true }} import SwiftUI import Clerk struct SMSOTPSignUpView: View { @State private var phoneNumber = "" @State private var code = "" @State private var isVerifying = false var body: some View { if isVerifying { TextField("Enter your verification code", text: $code) Button("Verify") { Task { await verify(code: code) } } } else { TextField("Enter phone number", text: $phoneNumber) Button("Continue") { Task { await submit(phoneNumber: phoneNumber) } } } } } extension SMSOTPSignUpView { func submit(phoneNumber: String) async { do { // Start the sign-up process using the phone number method. let signUp = try await SignUp.create(strategy: .standard(phoneNumber: phoneNumber)) // Start the verification - a SMS message will be sent to the // number with a one-time code. try await signUp.prepareVerification(strategy: .phoneCode) // Set isVerifying to true to display second form and capture the OTP code. isVerifying = true } catch { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling dump(error) } } func verify(code: String) async { do { // Access the in progress sign up stored on the client object. guard let inProgressSignUp = Clerk.shared.client?.signUp else { return } // Use the code provided by the user and attempt verification. let signUp = try await inProgressSignUp.attemptVerification(strategy: .phoneCode(code: code)) switch signUp.status { case .complete: // If verification was completed, navigate the user as needed. dump(Clerk.shared.session) default: // If the status is not complete, check why. User may need to // complete further steps. dump(signUp.status) } } catch { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling dump(error) } } } ``` ```kotlin {{ filename: 'SMSOTPSignUpViewModel.kt', collapsible: true }} import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.clerk.api.Clerk import com.clerk.api.network.serialization.flatMap import com.clerk.api.network.serialization.onFailure import com.clerk.api.network.serialization.onSuccess import com.clerk.api.signup.SignUp import com.clerk.api.signup.attemptVerification import com.clerk.api.signup.prepareVerification import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.launch class SMSOTPSignUpViewModel : ViewModel() { private val _uiState = MutableStateFlow(UiState.Unverified) val uiState = _uiState.asStateFlow() init { combine(Clerk.isInitialized, Clerk.userFlow) { isInitialized, user -> _uiState.value = when { !isInitialized -> UiState.Loading user == null -> UiState.Unverified else -> UiState.Verified } } .launchIn(viewModelScope) } fun submit(phoneNumber: String) { viewModelScope.launch { SignUp.create(SignUp.CreateParams.Standard(phoneNumber = phoneNumber)) .flatMap { it.prepareVerification(SignUp.PrepareVerificationParams.Strategy.PhoneCode()) } .onSuccess { _uiState.value = UiState.Verifying } .onFailure { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling } } } fun verify(code: String) { val inProgressSignUp = Clerk.signUp ?: return viewModelScope.launch { inProgressSignUp .attemptVerification(SignUp.AttemptVerificationParams.PhoneCode(code)) .onSuccess { if (it.status == SignUp.Status.COMPLETE) { _uiState.value = UiState.Verified } else { // The user may need to complete further steps } } .onFailure { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling } } } sealed interface UiState { data object Loading : UiState data object Unverified : UiState data object Verifying : UiState data object Verified : UiState } } ``` ```kotlin {{ filename: 'SMSOTPSignUpActivity.kt', collapsible: true }} import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle class SMSOTPSignUpActivity : ComponentActivity() { val viewModel: SMSOTPSignUpViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val state by viewModel.uiState.collectAsStateWithLifecycle() SMSOTPSignUpView(state, viewModel::submit, viewModel::verify) } } } @Composable fun SMSOTPSignUpView( state: SMSOTPSignUpViewModel.UiState, onSubmit: (String) -> Unit, onVerify: (String) -> Unit, ) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { when (state) { SMSOTPSignUpViewModel.UiState.Unverified -> { InputContent( placeholder = "Enter your phone number", buttonText = "Continue", onClick = onSubmit, ) } SMSOTPSignUpViewModel.UiState.Verified -> { Text("Verified") } SMSOTPSignUpViewModel.UiState.Verifying -> { InputContent( placeholder = "Enter your verification code", buttonText = "Verify", onClick = onVerify, ) } SMSOTPSignUpViewModel.UiState.Loading -> { CircularProgressIndicator() } } } } @Composable fun InputContent(placeholder: String, buttonText: String, onClick: (String) -> Unit) { var value by remember { mutableStateOf("") } Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically), ) { TextField(placeholder = { Text(placeholder) }, value = value, onValueChange = { value = it }) Button(onClick = { onClick(value) }) { Text(buttonText) } } } ```
    To create a sign-up flow for email OTP, use the prepareEmailAddressVerification and attemptEmailAddressVerification. These helpers work the same way as their phone number counterparts do in the previous example. You can find all available methods in the SignUp object documentation. ## Sign-in flow To authenticate a user with an OTP, you must: 1. Initiate the sign-in process by creating a `SignIn` using the identifier provided, which for this example is a phone number. 2. Prepare the first factor verification. 3. Attempt verification with the code the user provides. 4. If the attempt is successful, set the newly created session as the active session. This example is written for Next.js App Router but it can be adapted to any React-based framework. ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useSignIn } from '@clerk/nextjs' import { PhoneCodeFactor, SignInFirstFactor } from '@clerk/types' import { useRouter } from 'next/navigation' export default function Page() { const { isLoaded, signIn, setActive } = useSignIn() const [verifying, setVerifying] = React.useState(false) const [phone, setPhone] = React.useState('') const [code, setCode] = React.useState('') const router = useRouter() async function handleSubmit(e: React.FormEvent) { e.preventDefault() if (!isLoaded && !signIn) return null try { // Start the sign-in process using the phone number method const { supportedFirstFactors } = await signIn.create({ identifier: phone, }) // Filter the returned array to find the 'phone_code' entry const isPhoneCodeFactor = (factor: SignInFirstFactor): factor is PhoneCodeFactor => { return factor.strategy === 'phone_code' } const phoneCodeFactor = supportedFirstFactors?.find(isPhoneCodeFactor) if (phoneCodeFactor) { // Grab the phoneNumberId const { phoneNumberId } = phoneCodeFactor // Send the OTP code to the user await signIn.prepareFirstFactor({ strategy: 'phone_code', phoneNumberId, }) // Set verifying to true to display second form // and capture the OTP code setVerifying(true) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) } } async function handleVerification(e: React.FormEvent) { e.preventDefault() if (!isLoaded && !signIn) return null try { // Use the code provided by the user and attempt verification const signInAttempt = await signIn.attemptFirstFactor({ strategy: 'phone_code', code, }) // If verification was completed, set the session to active // and redirect the user if (signInAttempt.status === 'complete') { await setActive({ session: signInAttempt.createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } router.push('/') }, }) } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(signInAttempt) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) } } if (verifying) { return ( <>

    Verify your phone number

    setCode(e.target.value)} />
    ) } return ( <>

    Sign in

    setPhone(e.target.value)} />
    ) } ```
    ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Sign in

    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Mount user button component document.getElementById('signed-in').innerHTML = `
    ` const userbuttonDiv = document.getElementById('user-button') clerk.mountUserButton(userbuttonDiv) } else { // Handle the sign-in form document.getElementById('sign-in-form').addEventListener('submit', async (e) => { e.preventDefault() const formData = new FormData(e.target) const phone = formData.get('phone') try { // Start the sign-in process using the user's identifier. // In this case, it's their phone number. const { supportedFirstFactors } = await clerk.client.signIn.create({ identifier: phone, }) // Find the phoneNumberId from all the available first factors for the current sign-in const firstPhoneFactor = supportedFirstFactors.find((factor) => { return factor.strategy === 'phone_code' }) const { phoneNumberId } = firstPhoneFactor // Prepare first factor verification, specifying // the phone code strategy. await clerk.client.signIn.prepareFirstFactor({ strategy: 'phone_code', phoneNumberId, }) // Hide sign-in form document.getElementById('sign-in').setAttribute('hidden', '') // Show verification form document.getElementById('verifying').removeAttribute('hidden') } catch (error) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(error) } }) // Handle the verification form document.getElementById('verifying').addEventListener('submit', async (e) => { const formData = new FormData(e.target) const code = formData.get('code') try { // Verify the phone number const verify = await clerk.client.signIn.attemptFirstFactor({ strategy: 'phone_code', code, }) // Now that the user is created, set the session to active. await clerk.setActive({ session: verify.createdSessionId }) } catch (error) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(error) } }) } ```
    ```swift {{ filename: 'SMSOTPSignInView.swift', collapsible: true }} import SwiftUI import Clerk struct SMSOTPSignInView: View { @State private var phoneNumber = "" @State private var code = "" @State private var isVerifying = false var body: some View { if isVerifying { TextField("Enter your verification code", text: $code) Button("Verify") { Task { await verify(code: code) } } } else { TextField("Enter phone number", text: $phoneNumber) Button("Continue") { Task { await submit(phoneNumber: phoneNumber) } } } } } extension SMSOTPSignInView { func submit(phoneNumber: String) async { do { // Start the sign-in process using the phone number method. let signIn = try await SignIn.create(strategy: .identifier(phoneNumber)) // Send the OTP code to the user. try await signIn.prepareFirstFactor(strategy: .phoneCode()) // Set isVerifying to true to display second form // and capture the OTP code. isVerifying = true } catch { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling dump(error) } } func verify(code: String) async { do { // Access the in progress sign in stored on the client object. guard let inProgressSignIn = Clerk.shared.client?.signIn else { return } // Use the code provided by the user and attempt verification. let signIn = try await inProgressSignIn.attemptFirstFactor(strategy: .phoneCode(code: code)) switch signIn.status { case .complete: // If verification was completed, navigate the user as needed. dump(Clerk.shared.session) default: // If the status is not complete, check why. User may need to // complete further steps. dump(signIn.status) } } catch { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling dump(error) } } } ``` ```kotlin {{ filename: 'SMSOTPSignInViewModel.kt', collapsible: true }} import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.clerk.api.Clerk import com.clerk.api.network.serialization.flatMap import com.clerk.api.network.serialization.onFailure import com.clerk.api.network.serialization.onSuccess import com.clerk.api.signin.SignIn import com.clerk.api.signin.attemptFirstFactor import com.clerk.api.signin.prepareFirstFactor import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.launch class SMSOTPSignInViewModel : ViewModel() { private val _uiState = MutableStateFlow(UiState.Unverified) val uiState = _uiState.asStateFlow() init { combine(Clerk.isInitialized, Clerk.userFlow) { isInitialized, user -> _uiState.value = when { !isInitialized -> UiState.Loading user == null -> UiState.Unverified else -> UiState.Verified } } .launchIn(viewModelScope) } fun submit(phoneNumber: String) { viewModelScope.launch { SignIn.create(SignIn.CreateParams.Strategy.PhoneCode(phoneNumber)).flatMap { it .prepareFirstFactor(SignIn.PrepareFirstFactorParams.PhoneCode()) .onSuccess { _uiState.value = UiState.Verifying } .onFailure { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling } } } } fun verify(code: String) { val inProgressSignIn = Clerk.signIn ?: return viewModelScope.launch { inProgressSignIn .attemptFirstFactor(SignIn.AttemptFirstFactorParams.PhoneCode(code)) .onSuccess { if (it.status == SignIn.Status.COMPLETE) { _uiState.value = UiState.Verified } else { // The user may need to complete further steps } } .onFailure { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling } } } sealed interface UiState { data object Loading : UiState data object Unverified : UiState data object Verifying : UiState data object Verified : UiState } } ``` ```kotlin {{ filename: 'SMSOTPSignInActivity.kt', collapsible: true }} import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle class SMSOTPSignInActivity : ComponentActivity() { val viewModel: SMSOTPSignInViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val state by viewModel.uiState.collectAsStateWithLifecycle() SMSOTPSignInView(state, viewModel::submit, viewModel::verify) } } } @Composable fun SMSOTPSignInView( state: SMSOTPSignInViewModel.UiState, onSubmit: (String) -> Unit, onVerify: (String) -> Unit, ) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { when (state) { SMSOTPSignInViewModel.UiState.Unverified -> { InputContent( placeholder = "Enter your phone number", buttonText = "Continue", onClick = onSubmit, ) } SMSOTPSignInViewModel.UiState.Verified -> { Text("Verified") } SMSOTPSignInViewModel.UiState.Verifying -> { InputContent( placeholder = "Enter your verification code", buttonText = "Verify", onClick = onVerify, ) } SMSOTPSignInViewModel.UiState.Loading -> { CircularProgressIndicator() } } } } @Composable fun InputContent(placeholder: String, buttonText: String, onClick: (String) -> Unit) { var value by remember { mutableStateOf("") } Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically), ) { TextField(placeholder = { Text(placeholder) }, value = value, onValueChange = { value = it }) Button(onClick = { onClick(value) }) { Text(buttonText) } } } ```
    To create a sign-in flow for email OTP, pass the value `email_code` as the first factor strategy. You can find all available methods in the SignIn object documentation.
    --- title: Embeddable email links with sign-in tokens description: Learn how to build custom embeddable email link sign-in flows to increase user engagement and reduce drop off in transactional emails, SMS's, and more. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/embedded-email-links sourceFile: /docs/guides/development/custom-flows/authentication/embedded-email-links.mdx --- > \[!WARNING] > Expo does not support email links. You can request this feature on [Clerk's roadmap](https://feedback.clerk.com/). An "email link" is a link that, when visited, will automatically authenticate your user so that they can perform some action on your site with less friction than if they had to sign in manually. You can create email links with Clerk by generating a sign-in token. Common use cases include: * Welcome emails when users are added off a waitlist * Promotional emails for users * Recovering abandoned carts * Surveys or questionnaires This guide will demonstrate how to generate a sign-in token and use it to sign in a user. ## Generate a sign-in token [Sign-in tokens](/docs/reference/backend-api/tag/sign-in-tokens/post/sign_in_tokens){{ target: '_blank' }} are JWTs that can be used to sign in to an application without specifying any credentials. A sign-in token can be used **once**, and can be consumed from the Frontend API using the ticket strategy, which is demonstrated in the following example. > \[!NOTE] > By default, sign-in tokens expire in 30 days. You can optionally specify a different duration in seconds using the `expires_in_seconds` property. The following example demonstrates a cURL request that creates a valid sign-in token: ```bash curl 'https://api.clerk.com/v1/sign_in_tokens' \ -X POST \ -H 'Authorization: Bearer {{secret}}' \ -H 'Content-Type: application/json' \ -d '{ "user_id": "user_123" }' ``` This will return a `url` property, which can be used as your email link. Keep in mind that this link will use the [Account Portal sign-in page](/docs/guides/customizing-clerk/account-portal#sign-in) to sign in the user. If you would rather use your own sign-in page, you can use the `token` property that is returned. Add the `token` as a query param in any link, such as the following example: `https://your-site.com/accept-token?token=` Then, you can embed this link anywhere, such as an email. ## Build a custom flow for signing in with a sign-in token To handle email links with sign-in tokens, you must set up a page in your frontend that detects the token, signs the user in, and performs any additional actions you need. The following example demonstrates basic code that detects a token in the URL query params and uses it to initiate a sign-in with Clerk: ```tsx {{ filename: 'app/accept-token/page.tsx' }} 'use client' import { useUser, useSignIn } from '@clerk/nextjs' import { useEffect, useState } from 'react' import { useSearchParams } from 'next/navigation' export default function Page() { const [loading, setLoading] = useState(false) const { signIn, setActive } = useSignIn() const { isSignedIn, user } = useUser() // Get the token from the query params const signInToken = useSearchParams().get('token') useEffect(() => { if (!signIn || !setActive || !signInToken || user || loading) { return } const createSignIn = async () => { setLoading(true) try { // Create the `SignIn` with the token const signInAttempt = await signIn.create({ strategy: 'ticket', ticket: signInToken as string, }) // If the sign-in was successful, set the session to active if (signInAttempt.status === 'complete') { setActive({ session: signInAttempt.createdSessionId, }) } else { // If the sign-in attempt is not complete, check why. // User may need to complete further steps. console.error(JSON.stringify(signInAttempt, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) } finally { setLoading(false) } } createSignIn() }, [signIn, setActive, signInToken, user, loading]) if (!signInToken) { return
    No token provided.
    } if (!isSignedIn) { // Handle signed out state return null } if (loading) { return
    Signing you in...
    } return
    Signed in as {user.id}
    } ``` ```tsx {{ filename: 'pages/accept-token.tsx' }} import { InferGetServerSidePropsType, GetServerSideProps } from 'next' import { useUser, useSignIn } from '@clerk/nextjs' import { useEffect, useState } from 'react' // Get the token from the query param server-side, and pass through props export const getServerSideProps: GetServerSideProps = async (context) => { return { props: { signInToken: context.query.token ? context.query.token : null }, } } export default function AcceptTokenPage({ signInToken, }: InferGetServerSidePropsType) { const [loading, setLoading] = useState(false) const { signIn, setActive } = useSignIn() const { isSignedIn, user } = useUser() useEffect(() => { if (!signIn || !setActive || !signInToken || user || loading) { return } const createSignIn = async () => { setLoading(true) try { // Create the `SignIn` with the token const signInAttempt = await signIn.create({ strategy: 'ticket', ticket: signInToken as string, }) // If the sign-in was successful, set the session to active if (signInAttempt.status === 'complete') { setActive({ session: signInAttempt.createdSessionId, }) } else { // If the sign-in attempt is not complete, check why. // User may need to complete further steps. console.error(JSON.stringify(signInAttempt, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) setLoading(true) } finally { setLoading(false) } } createSignIn() }, [signIn, setActive, signInToken, user, loading]) if (!signInToken) { return
    No token provided.
    } if (loading) { return
    Loading...
    } if (!isSignedIn) { // Handle signed out state return null } return
    Signed in as {user.id}
    } ```
    --- title: Build a custom flow for authenticating with enterprise connections description: Learn how to use the Clerk API to build a custom sign-up and sign-in flow that supports enterprise connections. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/enterprise-connections sourceFile: /docs/guides/development/custom-flows/authentication/enterprise-connections.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. ## Before you start You must configure your application instance through the Clerk Dashboard for the enterprise connection(s) that you want to use. Visit [the appropriate guide for your platform](/docs/guides/configure/auth-strategies/enterprise-connections/overview) to learn how to configure your instance. ## Create the sign-up and sign-in flow The following example **will both sign up *and* sign in users**, eliminating the need for a separate sign-up page. However, if you want to have separate sign-up and sign-in pages, the sign-up and sign-in flows are equivalent, meaning that all you have to do is swap out the `SignIn` object for the `SignUp` object using the useSignUp() hook. The following example: 1. Accesses the SignIn object using the useSignIn() hook. 2. Starts the authentication process by calling SignIn.authenticateWithRedirect(params). This method requires a `redirectUrl` param, which is the URL that the browser will be redirected to once the user authenticates with the identity provider. 3. Creates a route at the URL that the `redirectUrl` param points to. The following example names this route `/sso-callback`. This route should either render the prebuilt \ component or call the Clerk.handleRedirectCallback() method if you're not using the prebuilt component. The following example shows two files: 1. The sign-in page where the user can start the authentication flow. 2. The SSO callback page where the flow is completed. ```tsx {{ filename: 'app/sign-in/page.tsx' }} 'use client' import * as React from 'react' import { useSignIn } from '@clerk/nextjs' export default function Page() { const { signIn, isLoaded } = useSignIn() const signInWithEnterpriseSSO = (e: React.FormEvent) => { e.preventDefault() if (!isLoaded) return null const email = (e.target as HTMLFormElement).email.value signIn .authenticateWithRedirect({ identifier: email, strategy: 'enterprise_sso', redirectUrl: '/sign-in/sso-callback', redirectUrlComplete: '/', }) .then((res) => { console.log(res) }) .catch((err: any) => { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.log(err.errors) console.error(err, null, 2) }) } return (
    signInWithEnterpriseSSO(e)}>
    ) } ``` ```jsx {{ filename: 'app/sign-in/sso-callback/page.tsx' }} import { AuthenticateWithRedirectCallback } from '@clerk/nextjs' export default function Page() { // Handle the redirect flow by calling the Clerk.handleRedirectCallback() method // or rendering the prebuilt component. // This is the final step in the custom Enterprise SSO flow. return } ```
    The following example **will both sign up *and* sign in users**, eliminating the need for a separate sign-up page. The following example: 1. Uses the useSSO() hook to access the `startSSOFlow()` method. 2. Calls the `startSSOFlow()` method with the `strategy` param set to `enterprise_sso` and the `identifier` param set to the user's email address that they provided. The optional `redirect_url` param is also set in order to redirect the user once they finish the authentication flow. * If authentication is successful, the `setActive()` method is called to set the active session with the new `createdSessionId`. * If authentication is not successful, you can handle the missing requirements, such as MFA, using the signIn or signUp object returned from `startSSOFlow()`, depending on if the user is signing in or signing up. These objects include properties, like `status`, that can be used to determine the next steps. See the respective linked references for more information. ```tsx {{ filename: 'app/(auth)/sign-in.tsx', collapsible: true }} import React, { useEffect, useState } from 'react' import * as WebBrowser from 'expo-web-browser' import * as AuthSession from 'expo-auth-session' import { useSSO } from '@clerk/clerk-expo' import { View, Button, TextInput, Platform } from 'react-native' export const useWarmUpBrowser = () => { useEffect(() => { // Preloads the browser for Android devices to reduce authentication load time // See: https://docs.expo.dev/guides/authentication/#improving-user-experience if (Platform.OS !== 'android') return void WebBrowser.warmUpAsync() return () => { // Cleanup: closes browser when component unmounts void WebBrowser.coolDownAsync() } }, []) } // Handle any pending authentication sessions WebBrowser.maybeCompleteAuthSession() export default function Page() { useWarmUpBrowser() const [email, setEmail] = useState('') // Use the `useSSO()` hook to access the `startSSOFlow()` method const { startSSOFlow } = useSSO() const onPress = async () => { try { // Start the authentication process by calling `startSSOFlow()` const { createdSessionId, setActive, signIn, signUp } = await startSSOFlow({ strategy: 'enterprise_sso', identifier: email, // For web, defaults to current path // For native, you must pass a scheme, like AuthSession.makeRedirectUri({ scheme, path }) // For more info, see https://docs.expo.dev/versions/latest/sdk/auth-session/#authsessionmakeredirecturioptions redirectUrl: AuthSession.makeRedirectUri(), }) // If sign in was successful, set the active session if (createdSessionId) { setActive!({ session: createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } router.push('/') }, }) } else { // If there is no `createdSessionId`, // there are missing requirements, such as MFA // Use the `signIn` or `signUp` returned from `startSSOFlow` // to handle next steps } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } return ( ) } ``` ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App
    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Attach signOut function to the sign-out button document.getElementById('sign-out').addEventListener('click', async () => { await clerk.signOut() // Optional: refresh page after sign-out window.location.reload() }) } ```
    The useClerk() hook is used to access the `signOut()` function, which is called when the user clicks the "Sign out" button. ```tsx {{ filename: 'app/components/SignOutButton.tsx', collapsible: true }} import { useClerk } from '@clerk/clerk-expo' import { useRouter } from 'expo-router' import { Text, TouchableOpacity } from 'react-native' export const SignOutButton = () => { // Use `useClerk()` to access the `signOut()` function const { signOut } = useClerk() const router = useRouter() const handleSignOut = async () => { try { await signOut() // Redirect to your desired page router.replace('/') } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } return ( Sign out ) } ``` ```swift {{ filename: 'SignOutView.swift', collapsible: true }} import SwiftUI import Clerk struct SignOutView: View { @Environment(Clerk.self) private var clerk var body: some View { if let session = clerk.session { Text("Active Session: \(session.id)") Button("Sign out") { Task { await signOut() } } } else { Text("You are signed out") } } } extension SignOutView { func signOut() async { do { try await clerk.signOut() } catch { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling. dump(error) } } } ``` ```kotlin {{ filename: 'MainViewModel.kt', collapsible: true }} import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.clerk.api.Clerk import com.clerk.api.network.serialization.onFailure import com.clerk.api.network.serialization.onSuccess import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.launch class MainViewModel : ViewModel() { private val _uiState = MutableStateFlow(UiState.Loading) val uiState = _uiState.asStateFlow() init { combine(Clerk.isInitialized, Clerk.userFlow) { isInitialized, user -> _uiState.value = when { !isInitialized -> UiState.Loading user != null -> UiState.SignedIn else -> UiState.SignedOut } } .launchIn(viewModelScope) } fun signOut() { viewModelScope.launch { Clerk.signOut() .onSuccess { _uiState.value = UiState.SignedOut } .onFailure { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling } } } sealed interface UiState { data object SignedIn : UiState data object SignedOut : UiState data object Loading : UiState } } ``` ```kotlin {{ filename: 'MainActivity.kt', collapsible: true }} import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle class MainActivity : ComponentActivity() { val viewModel: MainViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { val state by viewModel.uiState.collectAsStateWithLifecycle() Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { when (state) { MainViewModel.UiState.Loading -> { CircularProgressIndicator() } MainViewModel.UiState.SignedIn -> { Button(onClick = { viewModel.signOut() }) { Text("Sign out") } } MainViewModel.UiState.SignedOut -> { // Signed out content } } } } } } ```
    --- title: Sign-up with application invitations description: Learn how to use the Clerk API to build a custom flow for handling application invitations. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/application-invitations sourceFile: /docs/guides/development/custom-flows/authentication/application-invitations.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. When a user visits an [invitation](/docs/guides/users/inviting) link, Clerk first checks whether a custom redirect URL was provided. **If no redirect URL is specified**, the user will be redirected to the appropriate Account Portal page (either [sign-up](/docs/guides/customizing-clerk/account-portal#sign-up) or [sign-in](/docs/guides/customizing-clerk/account-portal#sign-in)), or to the custom sign-up/sign-in pages that you've configured for your application. **If you specified [a redirect URL when creating the invitation](/docs/guides/users/inviting#with-a-redirect-url)**, you must handle the authentication flows in your code for that page. You can either embed the \ component on that page, or if the prebuilt component doesn't meet your specific needs or if you require more control over the logic, you can rebuild the existing Clerk flows using the Clerk API. This guide demonstrates how to use Clerk's API to build a custom flow for accepting application invitations. ## Build the custom flow Once the user visits the invitation link and is redirected to the specified URL, the query parameter `__clerk_ticket` will be appended to the URL. This query parameter contains the invitation token. For example, if the redirect URL was `https://www.example.com/accept-invitation`, the URL that the user would be redirected to would be `https://www.example.com/accept-invitation?__clerk_ticket=.....`. To create a sign-up flow using the invitation token, you need to extract the token from the URL and pass it to the signUp.create() method, as shown in the following example. The following example also demonstrates how to collect additional user information for the sign-up; you can either remove these fields or adjust them to fit your application. ```tsx {{ filename: 'app/accept-invitation/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useSignUp, useUser } from '@clerk/nextjs' import { useSearchParams, useRouter } from 'next/navigation' export default function Page() { const { isSignedIn, user } = useUser() const router = useRouter() const { isLoaded, signUp, setActive } = useSignUp() const [firstName, setFirstName] = React.useState('') const [lastName, setLastName] = React.useState('') const [password, setPassword] = React.useState('') // Handle signed-in users visiting this page // This will also redirect the user once they finish the sign-up process React.useEffect(() => { if (isSignedIn) { router.push('/') } }, [isSignedIn]) // Get the token from the query params const token = useSearchParams().get('__clerk_ticket') // If there is no invitation token, restrict access to this page if (!token) { return

    No invitation token found.

    } // Handle submission of the sign-up form const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!isLoaded) return try { if (!token) return null // Create a new sign-up with the supplied invitation token. // Make sure you're also passing the ticket strategy. // After the below call, the user's email address will be // automatically verified because of the invitation token. const signUpAttempt = await signUp.create({ strategy: 'ticket', ticket: token, firstName, lastName, password, }) // If the sign-up was completed, set the session to active if (signUpAttempt.status === 'complete') { await setActive({ session: signUpAttempt.createdSessionId }) } else { // If the sign-up status is not complete, check why. User may need to // complete further steps. console.error(JSON.stringify(signUpAttempt, null, 2)) } } catch (err) { console.error(JSON.stringify(err, null, 2)) } } return ( <>

    Sign up

    setFirstName(e.target.value)} />
    setLastName(e.target.value)} />
    setPassword(e.target.value)} />
    ) } ``` ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Sign up

    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Mount user button component document.getElementById('signed-in').innerHTML = `
    ` const userbuttonDiv = document.getElementById('user-button') clerk.mountUserButton(userbuttonDiv) } else if (clerk.session.currentTask) { // Check for pending tasks and display custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks switch (clerk.session.currentTask.key) { case 'choose-organization': { document.getElementById('app').innerHTML = `
    ` const taskDiv = document.getElementById('task') clerk.mountTaskChooseOrganization(taskDiv) } } } else { // Get the token from the query parameter const param = '__clerk_ticket' const token = new URL(window.location.href).searchParams.get(param) // Handle the sign-up form document.getElementById('sign-up-form').addEventListener('submit', async (e) => { e.preventDefault() const formData = new FormData(e.target) const firstName = formData.get('firstName') const lastName = formData.get('lastName') const password = formData.get('password') try { // Start the sign-up process using the ticket method const signUpAttempt = await clerk.client.signUp.create({ strategy: 'ticket', ticket: token, firstName, lastName, password, }) // If sign-up was successful, set the session to active if (signUpAttempt.status === 'complete') { await clerk.setActive({ session: signUpAttempt.createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } await router.push('/') }, }) } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(JSON.stringify(signUpAttempt, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } }) } ```
    --- title: Add bot protection to your custom sign-up flow description: Learn how to add Clerk's bot protection to your custom sign-up flow. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/bot-sign-up-protection sourceFile: /docs/guides/development/custom-flows/authentication/bot-sign-up-protection.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. Clerk provides the ability to add a CAPTCHA widget to your sign-up flows to protect against bot sign-ups. The \ component handles this flow out-of-the-box. However, if you're building a custom user interface, this guide will show you how to add the CAPTCHA widget to your custom sign-up flow. ## Enable bot sign-up protection 1. In the Clerk Dashboard, navigate to the [**Attack protection**](https://dashboard.clerk.com/~/user-authentication/attack-protection) page. 2. Enable the **Bot sign-up protection** toggle. > \[!WARNING] > If you currently have the **Invisible** CAPTCHA type selected, it's highly recommended to switch to the **Smart** option, as the **Invisible** option is deprecated and will be removed in a future update. ## Add the CAPTCHA widget to your custom sign-up form To render the CAPTCHA widget in your custom sign-up form, **you need to include the `
    ` element by the time you call `signUp.create()`**. This element acts as a placeholder onto which the widget will be rendered. If this element is not found, the SDK will transparently fall back to an invisible widget in order to avoid breaking your sign-up flow. If this happens, you should see a relevant error in your browser's console. > \[!TIP] > The invisible widget fallback automatically blocks suspected bot traffic without offering users falsely detected as bots with an opportunity to prove otherwise. Therefore, it's strongly recommended that you ensure the `
    ` element exists in your DOM. The following example shows how to support the CAPTCHA widget: ```tsx {{ mark: [[25, 26]] }} <>

    Sign up

    setEmailAddress(e.target.value)} />
    setPassword(e.target.value)} />
    {/* Clerk's CAPTCHA widget */}
    ``` ## Customize the appearance of the CAPTCHA widget You can customize the appearance of the CAPTCHA widget by passing data attributes to the `
    ` element. The following attributes are supported: * `data-cl-theme`: The CAPTCHA widget theme. Can take the following values: `'light'`, `'dark'`, `'auto'`. Defaults to `'auto'`. * `data-cl-size`: The CAPTCHA widget size. Can take the following values: `'normal'`, `'flexible'`, `'compact'`. Defaults to `'normal'`. * `data-cl-language`: The CAPTCHA widget language. Must be either `'auto'` (default) to use the language that the visitor has chosen, or language and country code (e.g. `'en-US'`). Some languages are [supported by Clerk](/docs/guides/customizing-clerk/localization) but not by Cloudflare Turnstile, which is used for the CAPTCHA widget. See [Cloudflare Turnstile's supported languages](https://developers.cloudflare.com/turnstile/reference/supported-languages). For example, to set the theme to `'dark'`, the size to `'flexible'`, and the language to `'es-ES'`, you would add the following attributes to the `
    ` element: ```html
    ``` --- title: Build a custom flow for handling email links description: Learn how to build a custom flow using Clerk's API to handle email links for sign-up, sign-in, and email address verification. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/email-links sourceFile: /docs/guides/development/custom-flows/authentication/email-links.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. > \[!WARNING] > Expo does not support email links. You can request this feature on [Clerk's roadmap](https://feedback.clerk.com/). [Email links](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) can be used to sign up new users, sign in existing users, or allow existing users to verify newly added email addresses to their user profiles. The email link flow works as follows: 1. The user enters their email address and asks for an email link. 2. Clerk sends an email to the user, containing a link to the verification URL. 3. The user visits the email link, either on the same device where they entered their email address or on a different device, depending on the settings in the Clerk Dashboard. 4. Clerk verifies the user's identity and advances any sign-up or sign-in attempt that might be in progress. 5. If the verification is successful, the user is authenticated or their email address is verified, depending on the reason for the email link. This guide demonstrates how to use Clerk's API to build a custom flow for handling email links. It covers the following scenarios: * [Sign up](#sign-up-flow) * [Sign in](#sign-in-flow) * [Verify a new email address](#add-new-email-flow) ## Enable email link authentication To allow your users to sign up or sign in using email links, you must first configure the appropriate settings in the Clerk Dashboard. 1. In the Clerk Dashboard, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page. 2. Enable **Verify at sign-up**, and under **Verification methods**, enable **Email verification link**. 3. Enable **Sign-in with email**. Because this guide focuses on email links, disable **Email verification code** and enable **Email verification link**. By default, **Require the same device and browser** is enabled, which means that email links are required to be verified from the same device and browser on which the sign-up or sign-in was initiated. For this guide, leave this setting enabled. ## Sign-up flow 1. The useSignUp() hook is used to get the SignUp object. 2. The `SignUp` object is used to access the createEmailLinkFlow() method. 3. The `createEmailLinkFlow()` method is used to access the `startEmailLinkFlow()` method. 4. The `startEmailLinkFlow()` method is called with the `redirectUrl` parameter set to `/sign-up/verify`. It sends an email with a verification link to the user. When the user visits the link, they are redirected to the URL that was provided. 5. On the `/sign-up/verify` page, the useClerk() hook is used to get the handleEmailLinkVerification() method. 6. The `handleEmailLinkVerification()` method is called to verify the email address. Error handling is included to handle any errors that occur during the verification process. ```tsx {{ filename: 'app/sign-up/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useSignUp } from '@clerk/nextjs' export default function SignInPage() { const [emailAddress, setEmailAddress] = React.useState('') const [verified, setVerified] = React.useState(false) const [verifying, setVerifying] = React.useState(false) const [error, setError] = React.useState('') const { signUp, isLoaded } = useSignUp() if (!isLoaded) return null const { startEmailLinkFlow } = signUp.createEmailLinkFlow() async function submit(e: React.FormEvent) { e.preventDefault() // Reset states in case user resubmits form mid sign-up setVerified(false) setError('') setVerifying(true) if (!isLoaded && !signUp) return null // Start the sign-up process using the email provided try { await signUp.create({ emailAddress, }) // Dynamically set the host domain for dev and prod // You could instead use an environment variable or other source for the host domain const protocol = window.location.protocol const host = window.location.host // Send the user an email with the email link const signUpAttempt = await startEmailLinkFlow({ // URL to navigate to after the user visits the link in their email redirectUrl: `${protocol}//${host}/sign-up/verify`, }) // Check the verification result const verification = signUpAttempt.verifications.emailAddress // Handle if user visited the link and completed sign-up from /sign-up/verify if (verification.verifiedFromTheSameClient()) { setVerifying(false) setVerified(true) } } catch (err: any) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) if (err.errors?.[0]?.longMessage) { console.log('Clerk error:', err.errors[0].longMessage) setError(err.errors[0].longMessage) } else { setError('An error occurred.') } } } async function reset(e: React.FormEvent) { e.preventDefault() setVerifying(false) } if (error) { return (

    Error: {error}

    ) } if (verifying) { return (

    Check your email and visit the link that was sent to you.

    ) } if (verified) { return
    Signed up successfully!
    } return (

    Sign up

    setEmailAddress(e.target.value)} />
    ) } ``` ```tsx {{ filename: 'app/sign-up/verify/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useClerk } from '@clerk/nextjs' import { EmailLinkErrorCodeStatus, isEmailLinkError } from '@clerk/nextjs/errors' import Link from 'next/link' export default function VerifyEmailLink() { const [verificationStatus, setVerificationStatus] = React.useState('loading') const { handleEmailLinkVerification, loaded } = useClerk() async function verify() { try { // Dynamically set the host domain for dev and prod // You could instead use an environment variable or other source for the host domain const protocol = window.location.protocol const host = window.location.host await handleEmailLinkVerification({ // URL to navigate to if sign-up flow needs more requirements, such as MFA redirectUrl: `${protocol}//${host}/sign-up`, }) // If not redirected at this point, // the flow has completed setVerificationStatus('verified') } catch (err: any) { let status = 'failed' if (isEmailLinkError(err)) { // If link expired, set status to expired if (err.code === EmailLinkErrorCodeStatus.Expired) { status = 'expired' } else if (err.code === EmailLinkErrorCodeStatus.ClientMismatch) { // OPTIONAL: This check is only required if you have // the 'Require the same device and browser' setting // enabled in the Clerk Dashboard status = 'client_mismatch' } } setVerificationStatus(status) } } React.useEffect(() => { if (!loaded) return verify() }, [handleEmailLinkVerification, loaded]) if (verificationStatus === 'loading') { return
    Loading...
    } if (verificationStatus === 'failed') { return (

    Verify your email

    The email link verification failed.

    Sign up
    ) } if (verificationStatus === 'expired') { return (

    Verify your email

    The email link has expired.

    Sign up
    ) } // OPTIONAL: This check is only required if you have // the 'Require the same device and browser' setting // enabled in the Clerk Dashboard if (verificationStatus === 'client_mismatch') { return (

    Verify your email

    You must complete the email link sign-up on the same device and browser that you started it on.

    Sign up
    ) } return (

    Verify your email

    Successfully signed up. Return to the original tab to continue.

    ) } ```
    ## Sign-in flow 1. The useSignIn() hook is used to get the SignIn object. 2. The `SignIn` object is used to access the createEmailLinkFlow() method. 3. The `createEmailLinkFlow()` method is used to access the `startEmailLinkFlow()` method. 4. The `startEmailLinkFlow()` method is called with the `redirectUrl` parameter set to `/sign-in/verify`. It sends an email with a verification link to the user. When the user visits the link, they are redirected to the URL that was provided. 5. On the `/sign-in/verify` page, the useClerk() hook is used to get the handleEmailLinkVerification() method. 6. The `handleEmailLinkVerification()` method is called to verify the email address. Error handling is included to handle any errors that occur during the verification process. ```tsx {{ filename: 'app/sign-in/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useSignIn } from '@clerk/nextjs' import { EmailLinkFactor, SignInFirstFactor } from '@clerk/types' export default function SignInPage() { const [emailAddress, setEmailAddress] = React.useState('') const [verified, setVerified] = React.useState(false) const [verifying, setVerifying] = React.useState(false) const [error, setError] = React.useState('') const { signIn, isLoaded } = useSignIn() if (!isLoaded) return null const { startEmailLinkFlow } = signIn.createEmailLinkFlow() async function submit(e: React.FormEvent) { e.preventDefault() // Reset states in case user resubmits form mid sign-in setVerified(false) setError('') if (!isLoaded && !signIn) return null // Start the sign-in process using the email provided try { const { supportedFirstFactors } = await signIn.create({ identifier: emailAddress, }) setVerifying(true) // Filter the returned array to find the 'email_link' entry const isEmailLinkFactor = (factor: SignInFirstFactor): factor is EmailLinkFactor => { return factor.strategy === 'email_link' } const emailLinkFactor = supportedFirstFactors?.find(isEmailLinkFactor) if (!emailLinkFactor) { setError('Email link factor not found') return } const { emailAddressId } = emailLinkFactor // Dynamically set the host domain for dev and prod // You could instead use an environment variable or other source for the host domain const protocol = window.location.protocol const host = window.location.host // Send the user an email with the email link const signInAttempt = await startEmailLinkFlow({ emailAddressId, redirectUrl: `${protocol}//${host}/sign-in/verify`, }) // Check the verification result const verification = signInAttempt.firstFactorVerification // Handle if verification expired if (verification.status === 'expired') { setError('The email link has expired.') } // Handle if user visited the link and completed sign-in from /sign-in/verify if (verification.verifiedFromTheSameClient()) { setVerifying(false) setVerified(true) } } catch (err: any) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) setError('An error occurred.') } } async function reset(e: React.FormEvent) { e.preventDefault() setVerifying(false) } if (error) { return (

    Error: {error}

    ) } if (verifying) { return (

    Check your email and visit the link that was sent to you.

    ) } if (verified) { return
    Signed in successfully!
    } return (

    Sign in

    setEmailAddress(e.target.value)} />
    ) } ``` ```tsx {{ filename: 'app/sign-in/verify/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useClerk } from '@clerk/nextjs' import { EmailLinkErrorCodeStatus, isEmailLinkError } from '@clerk/nextjs/errors' import Link from 'next/link' export default function VerifyEmailLink() { const [verificationStatus, setVerificationStatus] = React.useState('loading') const { handleEmailLinkVerification, loaded } = useClerk() async function verify() { try { // Dynamically set the host domain for dev and prod // You could instead use an environment variable or other source for the host domain const protocol = window.location.protocol const host = window.location.host await handleEmailLinkVerification({ // URL to navigate to if sign-in flow needs more requirements, such as MFA redirectUrl: `${protocol}//${host}/sign-in`, }) // If not redirected at this point, // the flow has completed setVerificationStatus('verified') } catch (err: any) { let status = 'failed' if (isEmailLinkError(err)) { // If link expired, set status to expired if (err.code === EmailLinkErrorCodeStatus.Expired) { status = 'expired' } else if (err.code === EmailLinkErrorCodeStatus.ClientMismatch) { // OPTIONAL: This check is only required if you have // the 'Require the same device and browser' setting // enabled in the Clerk Dashboard status = 'client_mismatch' } } setVerificationStatus(status) return } } React.useEffect(() => { if (!loaded) return verify() }, [handleEmailLinkVerification, loaded]) if (verificationStatus === 'loading') { return
    Loading...
    } if (verificationStatus === 'failed') { return (

    Verify your email

    The email link verification failed.

    Sign in
    ) } if (verificationStatus === 'expired') { return (

    Verify your email

    The email link has expired.

    Sign in
    ) } // OPTIONAL: This check is only required if you have // the 'Require the same device and browser' setting // enabled in the Clerk Dashboard if (verificationStatus === 'client_mismatch') { return (

    Verify your email

    You must complete the email link sign-in on the same device and browser as you started it on.

    Sign in
    ) } return (

    Verify your email

    Successfully signed in. Return to the original tab to continue.

    ) } ```
    ## Add new email flow When a user adds an email address to their account, you can use email links to verify the email address. {/* Adds an email address to a user's account, and verifies it using an email link. */} 1. Every user has a User object that represents their account. The `User` object has a `emailAddresses` property that contains all the email addresses associated with the user. The useUser() hook is used to get the `User` object. 2. The User.createEmailAddress() method is passed to the useReverification() hook to require the user to reverify their credentials before being able to add an email address to their account. 3. If the `createEmailAddress()` function is successful, a new EmailAddress object is created and stored in `User.emailAddresses`. 4. The newly created `EmailAddress` object is used to access the createEmailLinkFlow() method. 5. The `createEmailLinkFlow()` method is used to access the `startEmailLinkFlow()` method. 6. The `startEmailLinkFlow()` method is called with the `redirectUrl` parameter set to `/account/add-email/verify`. It sends an email with a verification link to the user. When the user visits the link, they are redirected to the URL that was provided. 7. On the `/account/add-email/verify` page, the useClerk() hook is used to get the `handleEmailLinkVerification()` method. 8. The handleEmailLinkVerification() method is called to verify the email address. Error handling is included to handle any errors that occur during the verification process. ```tsx {{ filename: 'app/account/add-email/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useUser, useReverification } from '@clerk/nextjs' export default function Page() { const { isLoaded, isSignedIn, user } = useUser() const [email, setEmail] = React.useState('') const [verifying, setVerifying] = React.useState(false) const [error, setError] = React.useState('') const createEmailAddress = useReverification((email: string) => user?.createEmailAddress({ email }), ) if (!isLoaded) { // Handle loading state return null } if (!isSignedIn) { // Handle signed out state return

    You must be signed in to access this page

    } // Handle addition of the email address const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() try { setVerifying(true) // Add an unverified email address to user const res = await createEmailAddress(email) // Reload user to get updated User object await user.reload() // Find the email address that was just added const emailAddress = user.emailAddresses.find((a) => a.id === res.id) if (!emailAddress) { setError('Email address not found') return } const { startEmailLinkFlow } = emailAddress.createEmailLinkFlow() // Dynamically set the host domain for dev and prod // You could instead use an environment variable or other source for the host domain const protocol = window.location.protocol const host = window.location.host // Send the user an email with the verification link startEmailLinkFlow({ redirectUrl: `${protocol}//${host}/account/add-email/verify` }) } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) setError('An error occurred.') } } async function reset(e: React.FormEvent) { e.preventDefault() setVerifying(false) } if (error) { return (

    Error: {error}

    ) } if (verifying) { return (

    Check your email and visit the link that was sent to you.

    ) } // Display the initial form to capture the email address return ( <>

    Add email

    handleSubmit(e)}> setEmail(e.target.value)} />
    ) } ``` ```tsx {{ filename: 'app/account/add-email/verify/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useClerk } from '@clerk/nextjs' import { EmailLinkErrorCodeStatus, isEmailLinkError } from '@clerk/nextjs/errors' import Link from 'next/link' export type VerificationStatus = | 'expired' | 'failed' | 'loading' | 'verified' | 'verified_switch_tab' | 'client_mismatch' export default function VerifyEmailLink() { const [verificationStatus, setVerificationStatus] = React.useState('loading') const { handleEmailLinkVerification, loaded } = useClerk() async function verify() { try { await handleEmailLinkVerification({}) setVerificationStatus('verified') } catch (err: any) { let status: VerificationStatus = 'failed' if (isEmailLinkError(err)) { // If link expired, set status to expired if (err.code === EmailLinkErrorCodeStatus.Expired) { status = 'expired' } else if (err.code === EmailLinkErrorCodeStatus.ClientMismatch) { // OPTIONAL: This check is only required if you have // the 'Require the same device and browser' setting // enabled in the Clerk Dashboard status = 'client_mismatch' } } setVerificationStatus(status) return } } React.useEffect(() => { if (!loaded) return verify() }, [handleEmailLinkVerification, loaded]) if (verificationStatus === 'loading') { return
    Loading...
    } if (verificationStatus === 'failed') { return (

    Verify your email

    The email link verification failed.

    Return to add email
    ) } if (verificationStatus === 'expired') { return (

    Verify your email

    The email link has expired.

    Return to add email
    ) } // OPTIONAL: This check is only required if you have // the 'Require the same device and browser' setting // enabled in the Clerk Dashboard if (verificationStatus === 'client_mismatch') { return (

    Verify your email

    You must complete the email link verification on the same device and browser as you started it on.

    Return to add email
    ) } return (

    Verify your email

    Successfully added email!

    ) } ```
    --- title: Build a custom sign-in flow with multi-factor authentication description: Learn how to build a custom email/password sign-in flow that requires multi-factor authentication (MFA). lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/custom-flows/authentication/email-password-mfa sourceFile: /docs/guides/development/custom-flows/authentication/email-password-mfa.mdx --- > \[!WARNING] > This guide is for users who want to build a custom flowA **custom flow** refers to a user interface built entirely from scratch using the Clerk API. Learn more about [custom flows](/docs/guides/development/custom-flows/overview).. To use a *prebuilt* UI, use the [Account Portal pages](/docs/guides/customizing-clerk/account-portal) or prebuilt components. [Multi-factor verification (MFA)](/docs/guides/configure/auth-strategies/sign-up-sign-in-options) is an added layer of security that requires users to provide a second verification factor to access an account. Clerk supports second factor verification through **SMS verification code**, **Authenticator application**, and **Backup codes**. This guide will walk you through how to build a custom email/password sign-in flow that supports **Authenticator application** and **Backup codes** as the second factor. ## Enable email and password This guide uses email and password to sign in, however, you can modify this approach according to the needs of your application. To follow this guide, you first need to ensure email and password are enabled for your application. 1. In the Clerk Dashboard, navigate to the [**User & authentication**](https://dashboard.clerk.com/~/user-authentication/user-and-authentication) page. 2. Enable **Sign-in with email**. 3. Select the **Password** tab and enable **Sign-up with password**. Leave **Require a password at sign-up** enabled. ## Enable multi-factor authentication For your users to be able to enable MFA for their account, you need to enable MFA for your application. 1. In the Clerk Dashboard, navigate to the [**Multi-factor**](https://dashboard.clerk.com/~/user-authentication/multi-factor) page. 2. For the purpose of this guide, toggle on both the **Authenticator application** and **Backup codes** strategies. 3. Select **Save**. > \[!WARNING] > If you're using Duo as an authenticator app, please note that Duo generates TOTP codes differently than other authenticator apps. Duo allows a code to be valid for 30 seconds from *the moment it is first displayed*, which may cause frequent `invalid_code` errors if the code is not entered promptly. More information can be found in [Duo's Help Center](https://help.duo.com/s/article/2107). ## Sign-in flow Signing in to an MFA-enabled account is identical to the regular sign-in process. However, in the case of an MFA-enabled account, a sign-in won't convert until both first factor and second factor verifications are completed. To authenticate a user using their email and password, you need to: 1. Initiate the sign-in process by collecting the user's email address and password. 2. Prepare the first factor verification. 3. Attempt to complete the first factor verification. 4. Prepare the second factor verification. (This is where MFA comes into play.) 5. Attempt to complete the second factor verification. 6. If the verification is successful, set the newly created session as the active session. > \[!TIP] > For this example to work, the user must have MFA enabled on their account. You need to add the ability for your users to manage their MFA settings. See the [manage SMS-based MFA](/docs/guides/development/custom-flows/account-updates/manage-sms-based-mfa) or the [manage TOTP-based MFA](/docs/guides/development/custom-flows/account-updates/manage-totp-based-mfa) guide, depending on your needs. ```tsx {{ filename: 'app/sign-in/[[...sign-in]]/page.tsx', collapsible: true }} 'use client' import * as React from 'react' import { useSignIn } from '@clerk/nextjs' import { useRouter } from 'next/navigation' export default function SignInForm() { const { isLoaded, signIn, setActive } = useSignIn() const [email, setEmail] = React.useState('') const [password, setPassword] = React.useState('') const [code, setCode] = React.useState('') const [useBackupCode, setUseBackupCode] = React.useState(false) const [displayTOTP, setDisplayTOTP] = React.useState(false) const router = useRouter() // Handle user submitting email and pass and swapping to TOTP form const handleFirstStage = (e: React.FormEvent) => { e.preventDefault() setDisplayTOTP(true) } // Handle the submission of the TOTP of Backup Code submission const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!isLoaded) return // Start the sign-in process using the email and password provided try { await signIn.create({ identifier: email, password, }) // Attempt the TOTP or backup code verification const signInAttempt = await signIn.attemptSecondFactor({ strategy: useBackupCode ? 'backup_code' : 'totp', code: code, }) // If verification was completed, set the session to active // and redirect the user if (signInAttempt.status === 'complete') { await setActive({ session: signInAttempt.createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } await router.push('/') }, }) } else { // If the status is not complete, check why. User may need to // complete further steps. console.log(signInAttempt) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error('Error:', JSON.stringify(err, null, 2)) } } if (displayTOTP) { return (

    Verify your account

    handleSubmit(e)}>
    setCode(e.target.value)} id="code" name="code" type="text" value={code} />
    setUseBackupCode((prev) => !prev)} id="backupcode" name="backupcode" type="checkbox" checked={useBackupCode} />
    ) } return ( <>

    Sign in

    handleFirstStage(e)}>
    setEmail(e.target.value)} id="email" name="email" type="email" value={email} />
    setPassword(e.target.value)} id="password" name="password" type="password" value={password} />
    ) } ```
    ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Sign in

    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Mount user button component document.getElementById('signed-in').innerHTML = `
    ` const userbuttonDiv = document.getElementById('user-button') clerk.mountUserButton(userbuttonDiv) } else if (clerk.session?.currentTask) { // Check for pending tasks and display custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks switch (clerk.session.currentTask.key) { case 'choose-organization': { document.getElementById('app').innerHTML = `
    ` const taskDiv = document.getElementById('task') clerk.mountTaskChooseOrganization(taskDiv) } } } else { // Handle the sign-in form document.getElementById('sign-in-form').addEventListener('submit', async (e) => { e.preventDefault() const formData = new FormData(e.target) const emailAddress = formData.get('email') const password = formData.get('password') try { // Start the sign-in process await clerk.client.signIn.create({ identifier: emailAddress, password, }) // Hide sign-in form document.getElementById('sign-in').setAttribute('hidden', '') // Show verification form document.getElementById('verifying').removeAttribute('hidden') } catch (error) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(error) } }) // Handle the verification form document.getElementById('verifying').addEventListener('submit', async (e) => { const formData = new FormData(e.target) const totp = formData.get('totp') const backupCode = formData.get('backupCode') try { const useBackupCode = backupCode ? true : false const code = backupCode ? backupCode : totp // Attempt the TOTP or backup code verification const signInAttempt = await clerk.client.signIn.attemptSecondFactor({ strategy: useBackupCode ? 'backup_code' : 'totp', code: code, }) // If verification was completed, set the session to active // and redirect the user if (signInAttempt.status === 'complete') { await clerk.setActive({ session: signInAttempt.createdSessionId }) location.reload() } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(signInAttempt) } } catch (error) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(error) } }) } ```
    ### Before you start Install `expo-checkbox` for the UI. ```npm npm install expo-checkbox ``` ### Build the flow 1. Create the `(auth)` route group. This groups your sign-up and sign-in pages. 2. In the `(auth)` group, create a `_layout.tsx` file with the following code. The useAuth() hook is used to access the user's authentication state. If the user's already signed in, they'll be redirected to the home page. ```tsx {{ filename: 'app/(auth)/_layout.tsx' }} import { Redirect, Stack } from 'expo-router' import { useAuth } from '@clerk/clerk-expo' export default function AuthenticatedLayout() { const { isSignedIn } = useAuth() if (isSignedIn) { return } return } ``` In the `(auth)` group, create a `sign-in.tsx` file with the following code. The useSignIn() hook is used to create a sign-in flow. The user can sign in using their email and password and will be prompted to verify their account with a code from their authenticator app or with a backup code. ```tsx {{ filename: 'app/(auth)/sign-in.tsx', collapsible: true }} import React from 'react' import { useSignIn } from '@clerk/clerk-expo' import { useRouter } from 'expo-router' import { Text, TextInput, Button, View } from 'react-native' import Checkbox from 'expo-checkbox' export default function Page() { const { signIn, setActive, isLoaded } = useSignIn() const [email, setEmail] = React.useState('') const [password, setPassword] = React.useState('') const [code, setCode] = React.useState('') const [useBackupCode, setUseBackupCode] = React.useState(false) const [displayTOTP, setDisplayTOTP] = React.useState(false) const router = useRouter() // Handle user submitting email and pass and swapping to TOTP form const handleFirstStage = async () => { if (!isLoaded) return // Attempt to sign in using the email and password provided try { const attemptFirstFactor = await signIn.create({ identifier: email, password, }) // If the sign-in was successful, set the session to active // and redirect the user if (attemptFirstFactor.status === 'complete') { await setActive({ session: attemptFirstFactor.createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } await router.push('/') }, }) } else if (attemptFirstFactor.status === 'needs_second_factor') { // If the sign-in requires a second factor, display the TOTP form setDisplayTOTP(true) } else { // If the sign-in failed, check why. User might need to // complete further steps. console.error(JSON.stringify(attemptFirstFactor, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } // Handle the submission of the TOTP or backup code const onPressTOTP = React.useCallback(async () => { if (!isLoaded) return try { // Attempt the TOTP or backup code verification const attemptSecondFactor = await signIn.attemptSecondFactor({ strategy: useBackupCode ? 'backup_code' : 'totp', code: code, }) // If verification was completed, set the session to active // and redirect the user if (attemptSecondFactor.status === 'complete') { await setActive({ session: attemptSecondFactor.createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } await router.push('/') }, }) } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(JSON.stringify(attemptSecondFactor, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } }, [isLoaded, email, password, code, useBackupCode]) if (displayTOTP) { return ( Verify your account setCode(c)} /> Check if this code is a backup code setUseBackupCode((prev) => !prev)} /> ) } // Display the initial sign-up form to capture the email and password return ( <>

    Sign up

    setEmailAddress(e.target.value)} />
    setPassword(e.target.value)} />
    {/* Required for sign-up flows Clerk's bot sign-up protection is enabled by default */}
    ) } ``` ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Sign up

    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Mount user button component document.getElementById('signed-in').innerHTML = `
    ` const userbuttonDiv = document.getElementById('user-button') clerk.mountUserButton(userbuttonDiv) } else { // Handle the sign-up form document.getElementById('sign-up-form').addEventListener('submit', async (e) => { e.preventDefault() const formData = new FormData(e.target) const emailAddress = formData.get('email') const password = formData.get('password') try { // Start the sign-up process using the email and password provided await clerk.client.signUp.create({ emailAddress, password }) await clerk.client.signUp.prepareEmailAddressVerification() // Hide sign-up form document.getElementById('sign-up').setAttribute('hidden', '') // Show verification form document.getElementById('verifying').removeAttribute('hidden') } catch (error) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(error) } }) // Handle the verification form document.getElementById('verifying').addEventListener('submit', async (e) => { const formData = new FormData(e.target) const code = formData.get('code') try { // Use the code the user provided to attempt verification const signUpAttempt = await clerk.client.signUp.attemptEmailAddressVerification({ code, }) // Now that the user is created, set the session to active. await clerk.setActive({ session: signUpAttempt.createdSessionId }) } catch (error) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(error) } }) } ```
    1. Create the `(auth)` route group. This groups your sign-up and sign-in pages. 2. In the `(auth)` group, create a `_layout.tsx` file with the following code. The useAuth() hook is used to access the user's authentication state. If the user's already signed in, they'll be redirected to the home page. ```tsx {{ filename: 'app/(auth)/_layout.tsx' }} import { Redirect, Stack } from 'expo-router' import { useAuth } from '@clerk/clerk-expo' export default function GuestLayout() { const { isSignedIn } = useAuth() if (isSignedIn) { return } return } ``` In the `(auth)` group, create a `sign-up.tsx` file with the following code. The useSignUp() hook is used to create a sign-up flow. The user can sign up using their email and password and will receive an email verification code to confirm their email. ```tsx {{ filename: 'app/(auth)/sign-up.tsx', collapsible: true }} import * as React from 'react' import { Text, TextInput, Button, View } from 'react-native' import { useSignUp } from '@clerk/clerk-expo' import { Link, useRouter } from 'expo-router' export default function Page() { const { isLoaded, signUp, setActive } = useSignUp() const router = useRouter() const [emailAddress, setEmailAddress] = React.useState('') const [password, setPassword] = React.useState('') const [pendingVerification, setPendingVerification] = React.useState(false) const [code, setCode] = React.useState('') // Handle submission of sign-up form const onSignUpPress = async () => { if (!isLoaded) return // Start sign-up process using email and password provided try { await signUp.create({ emailAddress, password, }) // Send user an email with verification code await signUp.prepareEmailAddressVerification({ strategy: 'email_code' }) // Set 'pendingVerification' to true to display second form // and capture OTP code setPendingVerification(true) } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } // Handle submission of verification form const onVerifyPress = async () => { if (!isLoaded) return try { // Use the code the user provided to attempt verification const signUpAttempt = await signUp.attemptEmailAddressVerification({ code, }) // If verification was completed, set the session to active // and redirect the user if (signUpAttempt.status === 'complete') { await setActive({ session: signUpAttempt.createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } router.replace('/') }, }) } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(JSON.stringify(signUpAttempt, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } } if (pendingVerification) { return ( <> Verify your email setCode(code)} /> ) } ``` ```html {{ filename: 'index.html', collapsible: true }} Clerk + JavaScript App

    Sign in

    ``` ```js {{ filename: 'main.js', collapsible: true }} import { Clerk } from '@clerk/clerk-js' const pubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY const clerk = new Clerk(pubKey) await clerk.load() if (clerk.isSignedIn) { // Mount user button component document.getElementById('signed-in').innerHTML = `
    ` const userbuttonDiv = document.getElementById('user-button') clerk.mountUserButton(userbuttonDiv) } else if (clerk.session?.currentTask) { // Check for pending tasks and display custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks switch (clerk.session.currentTask.key) { case 'choose-organization': { document.getElementById('app').innerHTML = `
    ` const taskDiv = document.getElementById('task') clerk.mountTaskChooseOrganization(taskDiv) } } } else { // Handle the sign-in form document.getElementById('sign-in-form').addEventListener('submit', async (e) => { e.preventDefault() const formData = new FormData(e.target) const emailAddress = formData.get('email') const password = formData.get('password') try { // Start the sign-in process const signInAttempt = await clerk.client.signIn.create({ identifier: emailAddress, password, }) // If the sign-in is complete, set the user as active if (signInAttempt.status === 'complete') { await clerk.setActive({ session: signInAttempt.createdSessionId }) location.reload() } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(JSON.stringify(signInAttempt, null, 2)) } } catch (error) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(error) } }) } ```
    In the `(auth)` group, create a `sign-in.tsx` file with the following code. The useSignIn() hook is used to create a sign-in flow. The user can sign in using email address and password, or navigate to the sign-up page. ```tsx {{ filename: 'app/(auth)/sign-in.tsx', collapsible: true }} import { useSignIn } from '@clerk/clerk-expo' import { Link, useRouter } from 'expo-router' import { Text, TextInput, Button, View } from 'react-native' import React from 'react' export default function Page() { const { signIn, setActive, isLoaded } = useSignIn() const router = useRouter() const [emailAddress, setEmailAddress] = React.useState('') const [password, setPassword] = React.useState('') // Handle the submission of the sign-in form const onSignInPress = React.useCallback(async () => { if (!isLoaded) return // Start the sign-in process using the email and password provided try { const signInAttempt = await signIn.create({ identifier: emailAddress, password, }) // If sign-in process is complete, set the created session as active // and redirect the user if (signInAttempt.status === 'complete') { await setActive({ session: signInAttempt.createdSessionId, navigate: async ({ session }) => { if (session?.currentTask) { // Check for tasks and navigate to custom UI to help users resolve them // See https://clerk.com/docs/guides/development/custom-flows/overview#session-tasks console.log(session?.currentTask) return } router.replace('/') }, }) } else { // If the status is not complete, check why. User may need to // complete further steps. console.error(JSON.stringify(signInAttempt, null, 2)) } } catch (err) { // See https://clerk.com/docs/guides/development/custom-flows/error-handling // for more info on error handling console.error(JSON.stringify(err, null, 2)) } }, [isLoaded, emailAddress, password]) return ( Sign in setEmailAddress(emailAddress)} /> setPassword(password)} />
    ) } ```
    The following example uses the Next.js SDK to demonstrate how to integrate Supabase with Clerk in a **server-side rendered** application. The `createServerSupabaseClient()` function is stored in a separate file so that it can be re-used in multiple places, such as within `page.tsx` or a Server Action file. This function uses the auth().getToken() method to pass the Clerk session token to the Supabase client. ```ts {{ filename: 'app/ssr/client.ts' }} import { auth } from '@clerk/nextjs/server' import { createClient } from '@supabase/supabase-js' export function createServerSupabaseClient() { return createClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_KEY!, { async accessToken() { return (await auth()).getToken() }, }, ) } ``` The following files render the `/ssr` page and handle the "Add task" form submission. Use the following tabs to view the code for each page. ```tsx {{ filename: 'app/ssr/page.tsx' }} import AddTaskForm from './AddTaskForm' import { createServerSupabaseClient } from './client' export default async function Home() { // Use the custom Supabase client you created const client = createServerSupabaseClient() // Query the 'tasks' table to render the list of tasks const { data, error } = await client.from('tasks').select() if (error) { throw error } const tasks = data return (

    Tasks

    {tasks?.map((task: any) =>

    {task.name}

    )}
    ) } ``` ```ts {{ filename: 'app/ssr/actions.ts' }} 'use server' import { createServerSupabaseClient } from './client' export async function addTask(name: string) { const client = createServerSupabaseClient() try { const response = await client.from('tasks').insert({ name, }) console.log('Task successfully added!', response) } catch (error: any) { console.error('Error adding task:', error.message) throw new Error('Failed to add task') } } ``` ```ts {{ filename: 'app/ssr/AddTaskForm.tsx' }} 'use client' import React, { useState } from 'react' import { addTask } from './actions' import { useRouter } from 'next/navigation' function AddTaskForm() { const [taskName, setTaskName] = useState('') const router = useRouter() async function onSubmit() { await addTask(taskName) setTaskName('') router.refresh() } return (
    setTaskName(e.target.value)} value={taskName} />
    ) } export default AddTaskForm ```
    ## Test your integration Run your project and sign in. Test creating and viewing tasks. Sign out and sign in as a different user, and repeat. If you have the same tasks across multiple accounts, double check that RLS is enabled, or that the RLS policies were properly created. Check the table in the Supabase dashboard. You should see all the tasks between both users, but with differing values in the `user_id` column.
    ## What does the Clerk Supabase integration do? Requests to Supabase's APIs require that authenticated users have a `"role": "authenticated"` JWT claim. When enabled, the Clerk Supabase integration adds this claim to your instance's generated session tokens. ## Supabase JWT template deprecation As of April 1st, 2025, the Clerk Supabase JWT template is considered deprecated. Going forward, the native Supabase integration is the recommended way to integrate Clerk with Supabase. The native integration has a number of benefits over the JWT template: * No need to fetch a new token for each Supabase request * No need to share your Supabase JWT secret key with Clerk For more information on the benefits of the native integration, see [Supabase's documentation on third-party auth providers](https://supabase.com/docs/guides/auth/third-party/overview). --- title: Integrate Hasura with Clerk description: Learn how to integrate Clerk into your Hasura application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/integrations/databases/hasura sourceFile: /docs/guides/development/integrations/databases/hasura.mdx --- The first step is to create a new Clerk application from the Clerk Dashboard if you haven’t done so already. You can choose whichever authentication strategy and social sign-in providers you prefer. For more information, see the [setup guide](/docs/getting-started/quickstart/setup-clerk). After your Clerk application has been created, navigate to the [**JWT templates**](https://dashboard.clerk.com/~/jwt-templates) page in the Clerk Dashboard. Select **New template** to create a new template based on Hasura. ![The JWT templates page in the Clerk Dashboard. The 'New template' button was clicked, and a pop up titled 'New JWT template' is shown. The 'Hasura' template is hovered over](/docs/images/integrations/hasura/jwt-template.webp) Once the Hasura template is created, you will be redirected to the template's page. You can now configure the template to your needs. ![The 'Create new template' page of the JWT templates page in the Clerk Dashboard](/docs/images/integrations/hasura/create-template.webp) The Hasura template will pre-populate the default claims required by Hasura. You can include additional claims as necessary. [Shortcodes](/docs/guides/sessions/jwt-templates#shortcodes) are available to make adding dynamic user values easy. ![The 'Create new template' page of the JWT templates page in the Clerk Dashboard. The page is scrolled down to the 'Claims' section](/docs/images/integrations/hasura/template-shortcodes.webp) By default, Clerk will sign the JWT with a private key automatically generated for your application, which is what most developers use for Hasura. If you so choose, you can customize this key. ## Configure Hasura The next step is to provide Hasura with the public keys used to verify the JWT issued by Clerk. Assuming you didn’t use a custom signing key, set the **JWKS Endpoint** field to the JSON Web Key Set (JWKS) URL Clerk automatically created with your Frontend API at `https:///.well-known/jwks.json` You can find the **JWKS URL** on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. You can set up your project either with Hasura Cloud or you can [run the Hasura GraphQL engine locally using Docker Compose](https://hasura.io/docs/2.0/getting-started/docker-simple). ### Set up with Hasura Cloud Go to your project settings, select **Env vars**, and then add **New Env Var**. Set the key to `HASURA_GRAPHQL_JWT_SECRET` and the value to the following: ```json { "jwk_url": "https://{{fapi}}/.well-known/jwks.json" } ``` ### Set up with Hasura Core To add the JWT secret locally with Hasura Core, you need to set both the `HASURA_GRAPHQL_ADMIN_SECRET` and `HASURA_GRAPHQL_JWT_SECRET` in the `docker-compose.yml` file. `HASURA_GRAPHQL_ADMIN_SECRET` can be set to any text string. `HASURA_GRAPHQL_JWT_SECRET` should be set to a stringified JSON object of the JWT secret which contains the JWKS Endpoint as the value of `jwk_url`. ```yaml HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey HASURA_GRAPHQL_JWT_SECRET: '{"jwk_url":"https://{{fapi}}/.well-known/jwks.json"}' ``` Replace `` with the Frontend API value. This value can be found on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. ### With custom signing key If you did use a custom signing key, instead of providing the `jwk_url` you need to provide the algorithm type and key in the stringified JSON object as the `HASURA_GRAPHQL_JWT_SECRET` in the Hasura Cloud Env Vars or in the `docker-compose.yml` file. ```yaml HASURA_GRAPHQL_JWT_SECRET: '{"type": "HS256", "key": "" }' ``` ## Configure your GraphQL client GraphQL clients (such as [Apollo Client](https://github.com/apollographql/apollo-client) and [Relay](https://github.com/facebook/relay)) can help with querying and caching your data. They can also manage UI state, keep data in sync, and boost performance. GraphQL requests can be to the Hasura backend using different clients. The last step of integrating Clerk as the modern web authentication solution for Hasura is to pass the JWT in the `Authorization` header with your requests. You can access the token generated with the Hasura claims by calling `getToken({ template: })` on the `Session` object with the name of your template. Even if you don’t have a database table set up yet, we can make use of the [built-in GraphQL introspection system](https://graphql.org/learn/introspection/) to validate that the authenticated requests are working properly. Here is an example of using [Apollo Client](https://github.com/apollographql/apollo-client) in conjunction with the useAuth hook in a Next.js application to make a request to the Hasura GraphQL endpoint: ```jsx import { ApolloProvider, ApolloClient, HttpLink, from, InMemoryCache } from '@apollo/client' import { setContext } from '@apollo/client/link/context' import { useAuth } from '@clerk/nextjs' export const ApolloProviderWrapper = ({ children }) => { const { getToken } = useAuth() const apolloClient = useMemo(() => { const authMiddleware = setContext(async (req, { headers }) => { const token = await getToken({ template: 'template' }) return { headers: { ...headers, authorization: `Bearer ${token}`, }, } }) const httpLink = new HttpLink({ uri: process.env.GRAPHQL_URI, }) return new ApolloClient({ link: from([authMiddleware, httpLink]), cache: new InMemoryCache(), }) }, [getToken]) return {children} } ``` As an alternative, here is an example of using [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) in conjunction with the [useSWR](https://swr.vercel.app/) hook in a Next.js application to make a request to the Hasura GraphQL endpoint: ```jsx import { useAuth } from '@clerk/nextjs' import useSWR from 'swr' // This component needs to be a child of and // in order to access the authenticated session object const Main = () => { const { getToken } = useAuth() const endpoint = process.env.NEXT_PUBLIC_HASURA_GRAPHQL_API const query = `query { __schema { types { name } } }` const fetcher = async (...args) => fetch(...args, { method: 'POST', headers: { 'Content-Type': 'application/json', Accept: 'application/json', Authorization: `Bearer ${await getToken({ template: 'hasura' })}`, }, body: JSON.stringify({ query }), }).then((res) => res.json()) const { data } = useSWR(endpoint, fetcher) return

    GraphQL schema has {data?.data?.__schema.types.length} types

    } export default Main ``` Note that the `getToken({ template: })` call is asynchronous and returns a Promise that needs to be resolved before accessing the token value. This token is short-lived for better security and should be called before every request to your GraphQL API. The caching and refreshing of the token is handled automatically by Clerk. --- title: Integrate Convex with Clerk description: Learn how to integrate Clerk into your Convex application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/integrations/databases/convex sourceFile: /docs/guides/development/integrations/databases/convex.mdx --- * Create a JWT template in Clerk to generate Convex JWTs * Configure Convex to accept JWTs from Clerk * Configure the Clerk and Convex providers to work together With [Convex](https://www.convex.dev/), you can build a backend with a provided realtime database, file storage, text search, scheduling and more. Paired with Clerk's user authentication and management features, you can build a powerful application with minimal effort. This tutorial will show you how to integrate Clerk into your Convex application. It assumes that you have already integrated both Convex and one of Clerk's SDKs into your app. ## Create a JWT template based on Convex 1. In the Clerk Dashboard, navigate to the [**JWT templates**](https://dashboard.clerk.com/~/jwt-templates) page. 2. Select **New template** and then from the list of templates, select **Convex**. You'll be redirected to the template's settings page. 3. Copy and save the **Issuer** URL somewhere secure. This URL is the issuer domain for Clerk's JWT templates, which is your application's **Frontend API URL**. In development, it's format will be `https://verb-noun-00.clerk.accounts.dev`. In production, it's format will be `https://clerk..com`. ## Map additional claims (optional) In the **Claims** section, the default audience (`aud`) claim required by Convex is pre-mapped, as well as some other helpful claims like Convex's `name` claim to Clerk's `user.full_name` claim. You can include additional claims as necessary. [Shortcodes](/docs/guides/sessions/jwt-templates#shortcodes) are available to make adding dynamic user values easy. ## Configure Convex with the Clerk issuer domain 1. In your `env` file, add your **Issuer** URL as the `CLERK_FRONTEND_API_URL` environment variable. If you already have it set, great! ```env {{ filename: '.env' }} CLERK_FRONTEND_API_URL={{fapi_url}} ``` 2. In your app's `convex` folder, create a `auth.config.js` file with the following configuration: ```ts {{ filename: 'convex/auth.config.js' }} export default { providers: [ { domain: process.env.CLERK_FRONTEND_API_URL, applicationID: 'convex', }, ], } ``` ## Deploy your changes to Convex Run `npx convex dev` to automatically sync your configuration to your backend. ## Configure the Clerk and Convex providers Both Clerk and Convex have provider components that are required to provide authentication and client context. You should already have Clerk's provider component, ``, in your app. Convex offers a provider that is specifically for integrating with Clerk called ``. `` calls `ConvexReactClient()` to get Convex's client, so it must be used in a Client Component. Your `app/layout.tsx`, where you would use ``, is a Server Component, and a Server Component cannot contain Client Component code. To solve this, you must first create a *wrapper* Client Component around ``. ```tsx {{ filename: 'components/ConvexClientProvider.tsx' }} 'use client' import { ReactNode } from 'react' import { ConvexReactClient } from 'convex/react' import { ConvexProviderWithClerk } from 'convex/react-clerk' import { useAuth } from '@clerk/nextjs' if (!process.env.NEXT_PUBLIC_CONVEX_URL) { throw new Error('Missing NEXT_PUBLIC_CONVEX_URL in your .env file') } const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL) export default function ConvexClientProvider({ children }: { children: ReactNode }) { return ( {children} ) } ``` Now, your Server Component, `app/layout.tsx`, can use the wrapper component, ``. It's important that `` wraps ``, and not the other way around, as Convex needs to be able to access the Clerk context. ```tsx {{ filename: 'app/layout.tsx', mark: [5, 31] }} import type { Metadata } from 'next' import { Geist, Geist_Mono } from 'next/font/google' import './globals.css' import { ClerkProvider } from '@clerk/nextjs' import ConvexClientProvider from '@/components/ConvexClientProvider' const geistSans = Geist({ variable: '--font-geist-sans', subsets: ['latin'], }) const geistMono = Geist_Mono({ variable: '--font-geist-mono', subsets: ['latin'], }) export const metadata: Metadata = { title: 'Clerk Next.js Quickstart', description: 'Generated by create next app', } export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { return ( {children} ) } ``` The following example demonstrates how to configure Clerk and Convex's providers. Clerk's useAuth() hook must be passed to Convex's `` and Clerk's `` must be wrapped around it. ```ts {{ filename: 'src/main.tsx', mark: [[5, 7], 25, 27] }} import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' import './index.css' import { ClerkProvider, useAuth } from '@clerk/clerk-react' import { ConvexProviderWithClerk } from 'convex/react-clerk' import { ConvexReactClient } from 'convex/react' // Import your Publishable Key const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!PUBLISHABLE_KEY) { throw new Error('Add your Clerk Publishable Key to the .env file') } if (!process.env.VITE_CONVEX_URL) { throw new Error('Missing VITE_CONVEX_URL in your .env file') } const convex = new ConvexReactClient(process.env.VITE_CONVEX_URL) ReactDOM.createRoot(document.getElementById('root')!).render( , ) ``` ## Show UI based on auth state You can control which UI is shown when the user is signed in or signed out using Convex's ``, `` and `` helper components. These should be used instead of Clerk's ``, `` and `` components, respectively. It's important to use the [`useConvexAuth()`](https://docs.convex.dev/api/modules/react#useconvexauth) hook instead of Clerk's `useAuth()` hook when you need to check whether the user is logged in or not. The `useConvexAuth()` hook makes sure that the browser has fetched the auth token needed to make authenticated requests to your Convex backend, and that the Convex backend has validated it. In the following example, the `` component is a child of ``, so its content and any of its child components are guaranteed to have an authenticated user, and Convex queries can require authentication. ```tsx title="app/page.tsx" 'use client' import { Authenticated, Unauthenticated } from 'convex/react' import { SignInButton, UserButton } from '@clerk/nextjs' import { useQuery } from 'convex/react' import { api } from '../convex/_generated/api' export default function Home() { return ( <> ) } function Content() { const messages = useQuery(api.messages.getForCurrentUser) return
    Authenticated content: {messages?.length}
    } ```
    ```tsx title="src/App.tsx" import { SignInButton, UserButton } from '@clerk/clerk-react' import { Authenticated, Unauthenticated, AuthLoading, useQuery } from 'convex/react' import { api } from '../convex/_generated/api' function App() { return (

    Still loading

    ) } function Content() { const messages = useQuery(api.messages.getForCurrentUser) return
    Authenticated content: {messages?.length}
    } export default App ```
    ## Use auth state in your Convex functions If the client is authenticated, you can access the information stored in the JWT via `ctx.auth.getUserIdentity`. If the client isn't authenticated, `ctx.auth.getUserIdentity` will return `null`. **Make sure that the component calling this query is a child of `` from `convex/react`**. Otherwise, it will throw on page load. ```ts {{ filename: 'convex/messages.ts' }} import { query } from './_generated/server' export const getForCurrentUser = query({ args: {}, handler: async (ctx) => { const identity = await ctx.auth.getUserIdentity() if (identity === null) { throw new Error('Not authenticated') } return await ctx.db .query('messages') .filter((q) => q.eq(q.field('author'), identity.email)) .collect() }, }) ```
    ## Next steps Be aware that Convex may require usage of their custom hooks and methods rather than Clerk's, such as using Convex's `useConvexAuth()` hook instead of Clerk's `useAuth()` hook in some cases. For more information on how to use Convex with Clerk, see the [Convex docs](https://docs.convex.dev/auth/clerk). --- title: Integrate InstantDB with Clerk description: Learn how to integrate Clerk into your InstantDB application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/integrations/databases/instantdb sourceFile: /docs/guides/development/integrations/databases/instantdb.mdx --- Integrating [InstantDB](https://www.instantdb.com/) with Clerk gives you the benefits of using an InstantDB database while leveraging Clerk's authentication features. This tutorial will walk you through the steps to integrate InstantDB with Clerk in your Next.js app. If you're using a different framework, the steps are the same and the code can be adapted for any React-based framework. ## Configure your Clerk session token InstantDB uses Clerk's [session token](/docs/guides/sessions/session-tokens) to authenticate users. To use InstantDB with Clerk, you need to include the `email` claim in your Clerk session token. 1. In the Clerk Dashboard, navigate to the [**Sessions**](https://dashboard.clerk.com/~/sessions) page. 2. Under **Customize session token**, in the **Claims** editor, enter the following JSON and select **Save**. If you have already customized your session token, you may need to merge this with what you currently have. ```json { "email": "{{user.primary_email_address}}" } ``` You can have additional claims as long as the `email` claim is set to `{{user.primary_email_address}}`. ## Get your Clerk Publishable Key 1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page. 2. In the **Quick Copy** section, copy your Clerk Publishable Key. ## Configure InstantDB 1. In the InstantDB dashboard, navigate to the [**Auth**](https://www.instantdb.com/dash?t=auth) tab. 2. At the top of the page, save the **Public App ID** somewhere as you'll need this later. 3. Select **Setup Clerk**. 4. Add the Clerk Publishable Key you copied in the previous step. 5. Confirm the **The session token has the "email" claim.** message. 6. Select **Add Clerk app**. Save the **Client Name** somewhere as you'll need this later. ## Install the InstantDB library If you haven't already added InstantDB to your app, run the following command to install it: ```npm npm install @instantdb/react ``` ## Set your InstantDB credentials In your `.env` file, set the following environment variables to your InstantDB App ID and Clerk Client Name that you saved earlier: ```env {{ filename: '.env' }} NEXT_PUBLIC_INSTANTDB_APP_ID= NEXT_PUBLIC_CLERK_CLIENT_NAME= ``` ## Initialize InstantDB in your app To [initialize InstantDB](https://www.instantdb.com/docs/init) in your app: 1. Create a `db` directory. 2. In the `db` directory, create a `instant.ts` file with the following code. It initializes InstantDB with your App ID and schema. The schema used below is necessary for this tutorial, but you can customize it as needed. Read more about InstantDB schemas in the [InstantDB docs](https://www.instantdb.com/docs/modeling-data). ```tsx {{ filename: 'db/instant.ts' }} import { i, init } from '@instantdb/react' const APP_ID = process.env.NEXT_PUBLIC_INSTANTDB_APP_ID if (!APP_ID) { throw new Error('Missing NEXT_PUBLIC_INSTANTDB_APP_ID in your .env file') } // Optional: Declare your schema export const schema = i.schema({ entities: { todos: i.entity({ text: i.string(), done: i.boolean(), createdAt: i.number(), }), }, }) export const db = init({ appId: APP_ID, schema }) ``` ## Manage the Clerk and InstantDB auth sessions Integrating InstantDB with Clerk means that your users will sign in to your app using Clerk, and then Clerk's session token will be used to sign the user in to InstantDB. This means that your user will have two sessions: one with Clerk and one with InstantDB. In order to handle both sessions, the following component uses Clerk to check if the user is signed in, and if they are, it uses Clerk's session token to sign the user in to InstantDB. If the user is not signed in to Clerk, it signs them out of InstantDB, ensuring that if the Clerk session ends, the InstantDB session will end as well. ```tsx {{ filename: 'components/InstantDBAuthSync.tsx', collapsible: true }} 'use client' import { db } from '@/db/instant' import { useAuth, useUser } from '@clerk/nextjs' import { useEffect } from 'react' // If a user is signed in with Clerk, sign them in with InstantDB export default function InstantDBAuthSync() { const { isSignedIn } = useUser() const { getToken } = useAuth() useEffect(() => { if (isSignedIn) { getToken() .then((token) => { // Create a long-lived session with Instant for your Clerk user // It will look up the user by email or create a new user with // the email address in the session token. db.auth.signInWithIdToken({ clientName: process.env.NEXT_PUBLIC_CLERK_CLIENT_NAME as string, idToken: token as string, }) }) .catch((error) => { console.error('Error signing in with Instant', error) }) } else { db.auth.signOut() } }, [isSignedIn]) return null } ``` It's important to use this component in your **root** `layout.tsx` file because the `useEffect()` hook that syncs the Clerk and InstantDB sessions needs to run on every page load in order to manage the sessions properly. ```tsx {{ filename: 'app/layout.tsx', collapsible: true }} import type { Metadata } from 'next' import { ClerkProvider, SignInButton, SignUpButton, SignedIn, SignedOut, UserButton, } from '@clerk/nextjs' import { Geist, Geist_Mono } from 'next/font/google' import './globals.css' import InstantDBAuthSync from '@/component/InstantDBAuthSync' const geistSans = Geist({ variable: '--font-geist-sans', subsets: ['latin'], }) const geistMono = Geist_Mono({ variable: '--font-geist-mono', subsets: ['latin'], }) export const metadata: Metadata = { title: 'Clerk Next.js Quickstart', description: 'Generated by create next app', } export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { return (
    {children}
    ) } ``` ## Update your homepage Update your `page.tsx` file with the following code to see InstantDB in action. This code was copied from the [InstantDB quickstart](https://www.instantdb.com/docs#quick-start). The only difference is that the initialization code was moved to `/db/instant.ts` so that the InstantDB connection could be reused across the app. ```tsx {{ filename: 'app/page.tsx', collapsible: true }} 'use client' import { id, InstaQLEntity } from '@instantdb/react' import { db, schema } from '@/db/instant' type Todo = InstaQLEntity function App() { // Use Instant's `useQuery()` hook to get the todos const { isLoading, error, data } = db.useQuery({ todos: {} }) if (isLoading) { return (
    Loading...
    ) } if (error) { return (
    Error: {error.message}
    ) } const { todos } = data return (

    todos

    Open another tab to see todos update in realtime!
    ) } // Write Data // --------- function addTodo(text: string) { db.transact( db.tx.todos[id()].update({ text, done: false, createdAt: Date.now(), }), ) } function deleteTodo(todo: Todo) { db.transact(db.tx.todos[todo.id].delete()) } function toggleDone(todo: Todo) { db.transact(db.tx.todos[todo.id].update({ done: !todo.done })) } function deleteCompleted(todos: Todo[]) { const completed = todos.filter((todo) => todo.done) const txs = completed.map((todo) => db.tx.todos[todo.id].delete()) db.transact(txs) } function toggleAll(todos: Todo[]) { const newVal = !todos.every((todo) => todo.done) db.transact(todos.map((todo) => db.tx.todos[todo.id].update({ done: newVal }))) } // Components // ---------- function ChevronDownIcon() { return ( ) } function TodoForm({ todos }: { todos: Todo[] }) { return (
    { e.preventDefault() const input = e.currentTarget.input as HTMLInputElement addTodo(input.value) input.value = '' }} >
    ) } function TodoList({ todos }: { todos: Todo[] }) { return (
    {todos.map((todo) => (
    toggleDone(todo)} />
    {todo.done ? ( {todo.text} ) : ( {todo.text} )}
    ))}
    ) } function ActionBar({ todos }: { todos: Todo[] }) { return (
    Remaining todos: {todos.filter((todo) => !todo.done).length}
    ) } export default App ```
    --- title: Integrate Nhost with Clerk description: Learn how to integrate Clerk into your Nhost project. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/integrations/databases/nhost sourceFile: /docs/guides/development/integrations/databases/nhost.mdx --- The first step is to create a new Clerk application from the Clerk Dashboard if you haven’t done so already. You can choose whichever authentication strategy and social sign-in providers you prefer. For more information, see the [setup guide](/docs/getting-started/quickstart/setup-clerk). After your Clerk application has been created, navigate to the [**JWT templates**](https://dashboard.clerk.com/~/jwt-templates) page in the Clerk Dashboard. Select **New template** to create a new template based on Nhost. ![The JWT templates page in the Clerk Dashboard. The 'New template' button was clicked, and a pop up titled 'New JWT template' is shown. The 'Nhost' template is hovered over](/docs/images/integrations/nhost/jwt-template.webp) Once the Nhost template is created, you will be redirected to the template's page. You can now configure the template to your needs. ![The 'Create new template' page of the JWT templates page in the Clerk Dashboard](/docs/images/integrations/nhost/create-template.webp) The Nhost template will pre-populate the default claims required by Nhost and Hasura. You can include additional claims as necessary. [Shortcodes](/docs/guides/sessions/jwt-templates#shortcodes) are available to make adding dynamic user values easy. ![The 'Create new template' page of the JWT templates page in the Clerk Dashboard. The page is scrolled down to the 'Claims' section](/docs/images/integrations/nhost/template-shortcodes.webp) ## Configure Nhost The next step is to provide Nhost with the public keys used to verify the JWT issued by Clerk. Assuming you didn’t use a custom signing key, set the **JWKS Endpoint** field to the JSON Web Key Set (JWKS) URL Clerk automatically created with your Frontend API at `https:///.well-known/jwks.json` You can find the **JWKS URL** on the [**API keys**](https://dashboard.clerk.com/~/api-keys) page in the Clerk Dashboard. From your Nhost dashboard, navigate to **Settings** --> **Environment variables**. ![The Environment variables page in the Nhost dashboard](/docs/images/integrations/nhost/nhost-env-var.webp) Next to the **NHOST\_JWT\_SECRET**, select **Edit** and paste in the **JWKS URL** that you copied from the Clerk Dashboard. ### With custom signing key If you used a custom signing key, instead of providing the `jwk_url`, you need to provide the algorithm `type` and `key` as a JSON object in the `NHOST_JWT_SECRET` field. ```json { "type": "HS256", "key": "" } ``` ## Configure the providers Both Nhost and Clerk have Provider components that are required to wrap your React application to provide the authentication context. This is how you would set up a Next.js application using both Providers: ```jsx import { NhostNextProvider, NhostClient } from '@nhost/nextjs' import { ClerkProvider, RedirectToSignIn, SignedIn, SignedOut } from '@clerk/nextjs' const nhost = new NhostClient({ subdomain: process.env.NEXT_PUBLIC_NHOST_SUBDOMAIN || '', region: process.env.NEXT_PUBLIC_NHOST_REGION || '', }) function MyApp({ Component, pageProps }) { return ( ) } export default MyApp ``` ## Configure your GraphQL client GraphQL clients (such as [Apollo Client](https://github.com/apollographql/apollo-client) and [Relay](https://github.com/facebook/relay)) can help with querying and caching your data. They can also manage UI state, keep data in sync, and boost performance. GraphQL requests can be to the Hasura backend using different clients. The last step of integrating Clerk as the modern web authentication solution for Hasura is to pass the JWT in the `Authorization` header with your requests. You can access the token generated with the Hasura claims by calling `getToken({ template: })` on the `Session` object with the name of your template. Even if you don’t have a database table set up yet, we can make use of the [built-in GraphQL introspection system](https://graphql.org/learn/introspection/) to validate that the authenticated requests are working properly. Here is an example of using [Apollo Client](https://github.com/apollographql/apollo-client) in conjunction with the useAuth() hook in a Next.js application to make a request to the Hasura GraphQL endpoint: ```jsx import { ApolloProvider, ApolloClient, HttpLink, from, InMemoryCache } from '@apollo/client' import { setContext } from '@apollo/client/link/context' import { useAuth } from '@clerk/nextjs' export const ApolloProviderWrapper = ({ children }) => { const { getToken } = useAuth() const apolloClient = useMemo(() => { const authMiddleware = setContext(async (req, { headers }) => { const token = await user.getToken({ template: 'template' }) return { headers: { ...headers, authorization: `Bearer ${token}`, }, } }) const httpLink = new HttpLink({ uri: process.env.GRAPHQL_URI, }) return new ApolloClient({ link: from([authMiddleware, httpLink]), cache: new InMemoryCache(), }) }, [getToken]) return {children} } ``` As an alternative, here is an example of using [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) in conjunction with the [useSWR](https://swr.vercel.app/) hook in a Next.js application to make a request to the Hasura GraphQL endpoint: ```jsx import { useAuth } from '@clerk/nextjs' import useSWR from 'swr' export default function Home() { const { getToken } = useAuth() const subdomain = process.env.NEXT_PUBLIC_NHOST_SUBDOMAIN const endpoint = `https://${subdomain}.nhost.run/v1/graphql` const query = `query { __schema { types { name } } }` const fetcher = async (...args) => fetch(...args, { method: 'POST', headers: { 'Content-Type': 'application/json', Accept: 'application/json', Authorization: `Bearer ${await getToken({ template: 'nhost' })}`, }, body: JSON.stringify({ query }), }).then((res) => res.json()) const { data } = useSWR(endpoint, fetcher) return

    GraphQL schema has {data?.data?.__schema.types.length} types

    } ``` Note that the `getToken({ template: })` call is asynchronous and returns a Promise that needs to be resolved before accessing the token value. This token is short-lived for better security and should be called before every request to your GraphQL API. The caching and refreshing of the token is handled automatically by Clerk. --- title: Integrate Neon Postgres with Clerk description: Learn how to integrate Clerk into your Neon application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/integrations/databases/neon sourceFile: /docs/guides/development/integrations/databases/neon.mdx --- This tutorial demonstrates how to integrate Neon Postgres with Clerk in a Next.js application, using `drizzle-orm` and `drizzle-kit` to interact with the database. The tutorial guides you through setting up a simple application that enables users to add, view, and delete messages using Server Actions and Middleware with Clerk. ## Create a new Next.js project 1. Create a new Next.js project using the following command: ```sh {{ filename: 'terminal' }} npx create-next-app clerk-neon-example --typescript --eslint --tailwind --use-npm --no-src-dir --app --import-alias "@/*" ``` 2. Navigate to the project directory and install the required dependencies: ```sh {{ filename: 'terminal' }} cd clerk-neon-example npm install @neondatabase/serverless npm install drizzle-orm --legacy-peer-deps npm install -D drizzle-kit ``` ## Integrate the Next.js Clerk SDK Follow the Next.js quickstart to integrate the Clerk Next.js SDK into your application. ## Protect your application routes To ensure that only authenticated users can access your application, modify clerkMiddleware to require authentication for every route. > \[!IMPORTANT] > > If you're using Next.js ≤15, name your file `middleware.ts` instead of `proxy.ts`. The code itself remains the same; only the filename changes. ```typescript {{ filename: 'proxy.ts', mark: [[3, 5]] }} import { clerkMiddleware } from '@clerk/nextjs/server' export default clerkMiddleware(async (auth) => { await auth.protect() }) export const config = { matcher: [ // Skip Next.js internals and all static files, unless found in search params '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', // Always run for API routes '/(api|trpc)(.*)', ], } ``` ## Set your neon connection string Add the Neon connection string to your project's environment variables. You can find the Neon connection string in the [Neon console](https://console.neon.tech/) - see the [Neon docs](https://neon.tech/docs/connect/connect-from-any-app) for more information. Your environment variable file should have the following values: ```env {{ filename: '.env' }} DATABASE_URL=NEON_DB_CONNECTION_STRING NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY={{pub_key}} CLERK_SECRET_KEY={{secret}} ``` ## Set up the application schema and database connection 1. Inside the `app/`, create a `db/` directory. 2. Create a `schema.ts` file in the `db/` directory that defines the database schema. The schema will include a table called `user_messages` with the columns `user_id`, `create_ts`, and `message`.The `user_id` column will be used to store the user's Clerk ID. ```typescript {{ filename: 'app/db/schema.ts', mark: [4] }} import { pgTable, text, timestamp } from 'drizzle-orm/pg-core' export const UserMessages = pgTable('user_messages', { user_id: text('user_id').primaryKey().notNull(), createTs: timestamp('create_ts').defaultNow().notNull(), message: text('message').notNull(), }) ``` 3. Create an `index.ts` file in the `db` directory to set up the database connection. ```typescript {{ filename: 'app/db/index.ts' }} import { loadEnvConfig } from '@next/env' import { neon } from '@neondatabase/serverless' import { drizzle } from 'drizzle-orm/neon-http' import { UserMessages } from './schema' loadEnvConfig(process.cwd()) if (!process.env.DATABASE_URL) { throw new Error('DATABASE_URL must be a Neon postgres connection string') } const sql = neon(process.env.DATABASE_URL) export const db = drizzle(sql, { schema: { UserMessages }, }) ``` ## Push the schema to the database 1. To load the schema into the database, create a `drizzle.config.ts` file at the root of your project and add the following configuration: ```typescript {{ filename: 'drizzle.config.ts' }} import { defineConfig } from 'drizzle-kit' import { loadEnvConfig } from '@next/env' loadEnvConfig(process.cwd()) if (!process.env.DATABASE_URL) { throw new Error('DATABASE_URL must be a Neon postgres connection string') } export default defineConfig({ dialect: 'postgresql', dbCredentials: { url: process.env.DATABASE_URL, }, schema: './app/db/schema.ts', }) ``` 2. Run the following command to push the schema to the database: ```sh {{ filename: 'terminal' }} npx drizzle-kit push ``` ## Create Server Actions to handle user interactions To handle form submissions for adding and deleting user messages, create two Server Actions in `app/actions.ts`. Use Clerk's auth() helper to obtain the user ID, which will be used to interact with the database. ```typescript {{ filename: 'app/actions.ts' }} 'use server' import { auth } from '@clerk/nextjs/server' import { UserMessages } from './db/schema' import { db } from './db' import { eq } from 'drizzle-orm' export async function createUserMessage(formData: FormData) { const { isAuthenticated, userId } = await auth() if (!isAuthenticated) throw new Error('User not found') const message = formData.get('message') as string await db.insert(UserMessages).values({ user_id: userId, message, }) } export async function deleteUserMessage() { const { isAuthenticated, userId } = await auth() if (!isAuthenticated) throw new Error('User not found') await db.delete(UserMessages).where(eq(UserMessages.user_id, userId)) } ``` ## Create the UI for the Home Page In your `app/page.tsx` file, add the following code to create the UI for the home page. If a message exists, the user can view and delete it; otherwise, they can add a new message. To retrieve the user's messages, use Clerk's auth() helper to obtain the user's ID. Then, use this ID to query the database for the user's messages. To enable the user to delete or add a message, use the `deleteUserMessage()` and `createUserMessage()` actions created in the previous step. ```tsx {{ filename: 'app/page.tsx' }} import { createUserMessage, deleteUserMessage } from './actions' import { db } from './db' import { auth } from '@clerk/nextjs/server' export default async function Home() { const { isAuthenticated, userId } = await auth() if (!isAuthenticated) throw new Error('User not found') const existingMessage = await db.query.UserMessages.findFirst({ where: (messages, { eq }) => eq(messages.user_id, userId), }) return (

    Neon + Clerk Example

    {existingMessage ? (

    {existingMessage.message}

    ) : (
    )}
    ) } ``` ## Run the application Run your application and open `http://localhost:3000` in your browser. Sign in with Clerk and interact with the application to add and delete user messages.
    --- title: Integrate Firebase with Clerk description: Learn how to integrate Clerk into your Firebase application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/integrations/databases/firebase sourceFile: /docs/guides/development/integrations/databases/firebase.mdx --- > \[!WARNING] > The Firebase integration is no longer supported and maintained. For new applications, you **cannot** enable the integration. However, existing applications with the integration previously enabled will continue to function and can still be configured, but once disabled, **it cannot be re-enabled**. Integrating Firebase with Clerk gives you the benefits of using Firebase's features while leveraging Clerk's authentication, prebuilt components, and webhooks. ## Configure the integration The Firebase integration enables you to use Clerk to generate a valid authentication token to send to Firebase Auth. This enables you to leverage Clerk's prebuilt components, auth provider options, and more, while accessing Firebase products like Firestore with a session validated by Firebase Auth. To get started, enable the integration: 1. In the Clerk Dashboard, navigate to the [**Integrations**](https://dashboard.clerk.com/~/integrations) page. 2. Toggle the **Firebase** integration on. The configuration modal will appear. Keep this open while you configure your Firebase project. Next, configure your integration. The recommended way to configure your integration is to use a service account key provided by Firebase in order to configure the integration *automatically*. To do so: 1. In your Firebase project, visit [the Service Accounts settings](https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk). 2. Near the bottom of the page, select the **Generate new private key** button. 3. In the modal that pops up, select the **Generate key** button to download the JSON file that contains your service account key. 4. In the Clerk Dashboard, the Firebase configuration modal should still be open. Select the **Upload service account key** button and upload the JSON file you downloaded. 5. The appropriate fields in the configuration modal will be filled in automatically. Select **Apply changes** to save your configuration. Select the **Configure manually** tab above these instructions if you do not want to use a service account key. If you want to manually configure your Firebase integration, you must provide Clerk with the following information about your Firebase project: * **Service account email** – Find this in your Firebase project's [Google Cloud Console](https://console.cloud.google.com/projectselector2/iam-admin/serviceaccounts?consoleUI=FIREBASE\&hl=fi\&supportedpurview=project), or in the `client_email` field of your service account key JSON file. * **Firestore project ID** – Find this under **Project Settings** in the Firebase dashboard, or in the `project_id` field of your service account key JSON file. * **Private Key** – You can [generate this manually](https://firebase.google.com/docs/cloud-messaging/auth-server#:~:text=In%20the%20Firebase%20console%2C%20open,confirm%20by%20clicking%20Generate%20Key.), or find it in the `private_key` field of your service account key JSON file. * **Firebase database URL** *(Optional)* – To find this: * In the Firebase dashboard, select **Realtime Database** * Select the **Data** tab, and select the copy button to add the database URL to your clipboard. ## Enable authentication in Firebase To use Firebase auth, ensure authentication is enabled in your Firebase dashboard. To do so: 1. Navigate to your Firebase dashboard. 2. In the navigation sidenav, select the **Build** dropdown and select [**Authentication**](https://console.firebase.google.com/u/0/project/_/authentication). 3. Select **Get started**. 4. Enable any sign-in method you want, such as **Email/Password**. ## Add a Security Rule to your Firestore database (optional) Adding the [Cloud Firestore](https://firebase.google.com/docs/firestore/quickstart) feature in your Firebase application is optional. To use Firestore with Clerk, ensure that you have defined [Security Rules](https://firebase.google.com/docs/firestore/security/get-started) that allow authenticated requests to access your database. For example: ```bash service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth != null; } } } ``` ## Get your Firebase config object To connect to your Firebase app in your code, you need a config object from your Firebase project. To find it: 1. Visit [your Firebase project settings](https://console.firebase.google.com/project/_/settings/general/). 2. In the **Your apps** section, there should be a code snippet that includes the `firebaseConfig` object. Copy this object. It should look similar to the following: ```ts const firebaseConfig = { apiKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', authDomain: 'clerk-example-xxxxx.firebaseapp.com', databaseURL: 'https://clerk-example-xxxxx-default-xxxx.firebaseio.com', projectId: 'clerk-test-xxxx', storageBucket: 'clerk-test-xxxx.appspot.com', messagingSenderId: '012345678910', appId: '1:012345678:web:abcdef123456hijklm', measurementId: 'G-ABC123DEF', } ``` 3. Save this information somewhere secure. You'll need it to connect to your Firebase app. See [Google's Firebase documentation](https://support.google.com/firebase/answer/7015592) for more information on the config object. ## Use Firebase with Clerk in your code Now that you have configured the integration, and you have retrieved your Firebase config object, it's time to use Firebase with Clerk in your code. The following example: * Expects the user to be signed into the app with Clerk. * Creates a button for signing into your Firebase app, which uses Clerk to generate an authentication token for Firebase's API. * Creates a button for fetching example data from your Firestore database. This example is written for Next.js App Router, but it can be adapted to any React-based framework. ```tsx {{ filename: 'app/firebase/page.tsx' }} 'use client' import { useAuth } from '@clerk/nextjs' import { initializeApp } from 'firebase/app' import { getAuth, signInWithCustomToken } from 'firebase/auth' import { getFirestore } from 'firebase/firestore' import { doc, getDoc } from 'firebase/firestore' // Add your Firebase config object const firebaseConfig = { apiKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', authDomain: 'clerk-example-xxxxx.firebaseapp.com', databaseURL: 'https://clerk-example-xxxxx-default-xxxx.firebaseio.com', projectId: 'clerk-test-xxxx', storageBucket: 'clerk-test-xxxx.appspot.com', messagingSenderId: '012345678910', appId: '1:012345678:web:abcdef123456hijklm', measurementId: 'G-ABC123DEF', } // Connect to your Firebase app const app = initializeApp(firebaseConfig) // Connect to your Firestore database const db = getFirestore(app) // Connect to Firebase auth const auth = getAuth(app) // Remove this if you do not have Firestore set up // for your Firebase app const getFirestoreData = async () => { const docRef = doc(db, 'example', 'example-document') const docSnap = await getDoc(docRef) if (docSnap.exists()) { console.log('Document data:', docSnap.data()) } else { // docSnap.data() will be undefined in this case console.log('No such document!') } } export default function FirebaseUI() { const { getToken, isSignedIn } = useAuth() // Handle if the user is not signed in // You could display content, or redirect them to a sign-in page if (!isSignedIn) { return

    You need to sign in with Clerk to access this page.

    } const signIntoFirebaseWithClerk = async () => { const token = await getToken({ template: 'integration_firebase' }) const userCredentials = await signInWithCustomToken(auth, token || '') // The userCredentials.user object can call the methods of // the Firebase platform as an authenticated user. console.log('User:', userCredentials.user) } return (
    {/* Remove this button if you do not have Firestore set up */}
    ) } ```
    ## Next steps * [Use webhooks to sync Firebase data with Clerk](/docs/guides/development/webhooks/syncing) * Learn how to sync Firebase auth or Firestore data with Clerk data using webhooks. *** * [Create a custom sign-in-or-up page in your Next.js app](/docs/nextjs/guides/development/custom-sign-in-or-up-page) * Learn how add custom sign-up and sign-in pages with Clerk components in your Next.js application. *** * [Deploy to production](/docs/guides/development/deployment/production) * Learn how to deploy your Clerk app to production. *** * [Deploy to Vercel](/docs/guides/development/deployment/vercel) * Learn how to deploy your Clerk app to production on Vercel. --- title: Integrate Prisma Postgres with Clerk description: Learn how to integrate Clerk into your Prisma Postgres application. lastUpdated: 2025-11-19T22:57:21.000Z sdkScoped: "false" canonical: /docs/guides/development/integrations/databases/prisma-postgres sourceFile: /docs/guides/development/integrations/databases/prisma-postgres.mdx --- Integrating Prisma Postgres with Clerk gives you the benefits of using a Prisma Postgres database while leveraging Clerk's authentication, prebuilt components, and webhooks. This guide will show you how to create a simple blog application that allows users to create and read posts using Prisma Postgres and Clerk. This guide uses Next.js App Router but the same principles can be applied to other SDKs. ## Install Prisma Run the following command to install Prisma: ```sh {{ filename: 'terminal' }} npm install prisma tsx --save-dev ``` ## Initialize Prisma Run the following command to initialize Prisma: ```sh {{ filename: 'terminal' }} npx prisma init --output ../app/generated/prisma ``` This will: * Create a new `prisma/` directory in your project, with a `schema.prisma` file inside of it. The `schema.prisma` file is where you will define your database models. * Create a `prisma.config.ts` file in the root of your project. * Update your `.env` file to include a `DATABASE_URL` environment variable, which is used to store your database connection string for your Prisma Postgres database. ## Update the Prisma configuration Inside the `prisma.config.ts` file, add `import "dotenv/config";` so that it can load the `DATABASE_URL` environment variable from your `.env` file. ```ts {{ filename: 'prisma.config.ts', mark: [1] }} import 'dotenv/config' import { defineConfig, env } from 'prisma/config' export default defineConfig({ schema: 'prisma/schema.prisma', migrations: { path: 'prisma/migrations', }, engine: 'classic', datasource: { url: env('DATABASE_URL'), }, }) ``` ## Update the database schema In the `prisma/schema.prisma` file, update the schema to include a new model called `Post` with the columns `id`, `title`, `content`, `published`, and `authorId`. The `id` column will be used as the post's primary key, and the `authorId` column will be used to store the user's Clerk ID. ```prisma {{ filename: 'prisma/schema.prisma', mark: [[11, 17]] }} generator client { provider = "prisma-client" output = "../app/generated/prisma" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Post { id Int @id @default(autoincrement()) title String content String? published Boolean @default(false) authorId String } ``` ## Push the schema to the database Run the following command to push the updated schema to the database: ```sh {{ filename: 'terminal' }} npx prisma db push ``` ## Create a reusable Prisma Client instance At the root of your project, create a folder called `lib`. Inside of it, create a new file called `prisma.ts` and add the following code to it. This will set up a single Prisma Client instance, which is used to interact with your database, and bind it to the global object so that only one instance of the client is created in your application. This helps resolve issues with hot reloading that can occur when using Prisma with Next.js in development mode. ```typescript {{ filename: 'lib/prisma.ts' }} import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient() const globalForPrisma = global as unknown as { prisma: typeof prisma } if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma export default prisma ``` ## Create the UI for the homepage Now that all of the set up is complete, it's time to start building out your app. Replace the contents of `app/page.tsx` with the following code. This page fetches all posts from your database and displays them on the homepage, showing the title and author ID for each post. It uses the [`prisma.post.findMany()`](https://www.prisma.io/docs/orm/reference/prisma-client-reference?utm_source=docs#findmany) method, which is a Prisma Client method that retrieves all records from the database. ```tsx {{ filename: 'app/page.tsx' }} import Link from 'next/link' import prisma from '@/lib/prisma' export default async function Page() { const posts = await prisma.post.findMany() // Query the `Post` model for all posts return (

    Posts

    {posts.map((post) => ( {post.title} by {post.authorId} ))}
    Create New Post
    ) } ``` ## Create a new post Create a new file called `app/posts/create/page.tsx` and add the following code to it. This page allows users to create new posts. It uses Clerk's auth object to get the user's ID. * If there is no user ID, the user is not signed in, so a sign in button is displayed. * If the user is signed in, the "Create New Post" form is displayed. When the form is submitted, the `createPost()` function is called. This function creates a new post in the database using the [`prisma.post.create()`](https://www.prisma.io/docs/orm/reference/prisma-client-reference?utm_source=docs#create) method, which is a Prisma Client method that creates a new record in the database. ```tsx {{ filename: 'app/posts/create/page.tsx' }} import Form from 'next/form' import prisma from '@/lib/prisma' import { redirect } from 'next/navigation' import { SignInButton, useAuth } from '@clerk/nextjs' import { revalidatePath } from 'next/cache' import { auth } from '@clerk/nextjs/server' export default async function NewPost() { // The `Auth` object gives you access to properties like `userId` // Accessing the `Auth` object differs depending on the SDK you're using // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object const { userId } = await auth() // Protect this page from unauthenticated users if (!userId) { return (

    You must be signed in to create a post.

    ) } async function createPost(formData: FormData) { 'use server' // Type check if (!userId) return const title = formData.get('title') as string const content = formData.get('content') as string await prisma.post.create({ data: { title, content, authorId: userId, }, }) revalidatePath('/') redirect('/') } return (

    Create New Post