` element with a rendered `
` component instance.
+
+
+ #### `unmountOAuthConsent()` usage
+
+ ```js {{ filename: 'main.js', mark: [19] }}
+ 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 oauthConsentDiv = document.getElementById('oauth-consent')
+
+ clerk.mountOAuthConsent(oauthConsentDiv)
+
+ // ...
+
+ clerk.unmountOAuthConsent(oauthConsentDiv)
+ ```
+
+
+## Properties
+
+All props are optional.
+
+
+ - `appearance?`
+ - [Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined
+
+ An object to style your components. Will only affect [Clerk components](/docs/reference/components/overview) and not [Account Portal](/docs/guides/account-portal/overview) pages.
+
+ ---
+
+ - `fallback?`
+ - `ReactNode`
+
+ An element to be rendered while the component is mounting.
+
+ ---
+
+ - `oauthClientId?`
+ - `string`
+
+ Override the OAuth client ID. By default, Clerk reads this from the `client_id` query parameter in the current URL.
+
+ ---
+
+ - `scope?`
+ - `string`
+
+ Override the OAuth scope. By default, Clerk reads this from the `scope` query parameter in the current URL.
+
diff --git a/docs/reference/components/overview.mdx b/docs/reference/components/overview.mdx
index 28235d2994..0f8d2e8a5d 100644
--- a/docs/reference/components/overview.mdx
+++ b/docs/reference/components/overview.mdx
@@ -11,6 +11,7 @@ Clerk offers a comprehensive suite of components designed to seamlessly integrat
- [`
`](/docs/reference/components/authentication/sign-in)
- [`
`](/docs/reference/components/authentication/sign-up)
- [`
`](/docs/reference/components/authentication/google-one-tap)
+- [`
`](/docs/reference/components/authentication/oauth-consent)
- [`
`](/docs/reference/components/authentication/task-choose-organization)
- [`
`](/docs/reference/components/authentication/task-reset-password)
- [`
`](/docs/reference/components/authentication/task-setup-mfa)
diff --git a/docs/reference/hooks/use-oauth-consent.mdx b/docs/reference/hooks/use-oauth-consent.mdx
new file mode 100644
index 0000000000..b5d24e8deb
--- /dev/null
+++ b/docs/reference/hooks/use-oauth-consent.mdx
@@ -0,0 +1,245 @@
+---
+title: useOAuthConsent()
+description: Load OAuth consent metadata for an authenticated user with Clerk's useOAuthConsent() hook.
+sdk: nextjs, react, react-router, tanstack-react-start
+---
+
+The `useOAuthConsent()` hook loads OAuth consent metadata for an authenticated user. You can use it to build a custom OAuth consent page that fetches the OAuth application's name, logo, URL, requested scopes, and related loading state.
+
+Unlike the [`
`](/docs/reference/components/authentication/oauth-consent) component, this hook doesn't read values from the current URL. Pass the `oauthClientId` explicitly, and optionally pass `scope` if you want Clerk to scope the request to a specific space-delimited scope string.
+
+## Parameters
+
+`useOAuthConsent()` accepts a single object with the following properties:
+
+
+
+## Returns
+
+
+
+
+
+## Example
+
+The following example demonstrates how to use the `useOAuthConsent()` hook to fetch OAuth consent metadata and build a custom consent form. In this example, the `client_id` is read from the current URL and passed to the hook, and the form submits to the URL generated by the [`buildConsentActionUrl()`](/docs/reference/types/oauth-application) method.
+
+
+ ```tsx {{ filename: 'src/routes/oauth-consent.tsx' }}
+ import { useClerk, useOAuthConsent } from '@clerk/react'
+
+ export const meta = () => [
+ {
+ name: 'referrer',
+ content: 'strict-origin-when-cross-origin',
+ },
+ ]
+
+ export default function OAuthConsentPage() {
+ const clerk = useClerk()
+ const params = new URLSearchParams(window.location.search)
+ const clientId = params.get('client_id') ?? ''
+ const scope = params.get('scope') ?? undefined
+
+ const { data, isLoading, error } = useOAuthConsent({
+ oauthClientId: clientId,
+ scope,
+ })
+
+ const actionUrl = clerk.oauthApplication.buildConsentActionUrl({ clientId })
+
+ if (isLoading) return Loading...
+ if (error) return Something went wrong.
+
+ return (
+
+ )
+ }
+ ```
+
+
+
+ ```tsx {{ filename: 'app/oauth-consent/page.tsx' }}
+ 'use client'
+
+ import { useClerk, useOAuthConsent } from '@clerk/nextjs'
+ import { useSearchParams } from 'next/navigation'
+
+ export const metadata: Metadata = {
+ referrer: 'strict-origin-when-cross-origin',
+ }
+
+ export default function Page() {
+ const clerk = useClerk()
+ const params = useSearchParams()
+ const clientId = params.get('client_id') ?? ''
+ const scope = params.get('scope') ?? undefined
+
+ const { data, isLoading, error } = useOAuthConsent({
+ oauthClientId: clientId,
+ scope,
+ })
+
+ const actionUrl = clerk.oauthApplication.buildConsentActionUrl({ clientId })
+
+ if (isLoading) return Loading...
+ if (error) return Something went wrong.
+
+ return (
+
+ )
+ }
+ ```
+
+
+
+ ```tsx {{ filename: 'app/routes/oauth-consent.tsx' }}
+ import type { Route } from './+types/oauth-consent'
+ import { useClerk, useOAuthConsent } from '@clerk/react-router'
+ import { useSearchParams } from 'react-router'
+
+ export const meta: Route.MetaFunction = () => [
+ {
+ name: 'referrer',
+ content: 'strict-origin-when-cross-origin',
+ },
+ ]
+
+ export default function OAuthConsentPage() {
+ const clerk = useClerk()
+ const [params] = useSearchParams()
+ const clientId = params.get('client_id') ?? ''
+ const scope = params.get('scope') ?? undefined
+
+ const { data, isLoading, error } = useOAuthConsent({
+ oauthClientId: clientId,
+ scope,
+ })
+
+ const actionUrl = clerk.oauthApplication.buildConsentActionUrl({ clientId })
+
+ if (isLoading) return Loading...
+ if (error) return Something went wrong.
+
+ return (
+
+ )
+ }
+ ```
+
+
+
+ ```tsx {{ filename: 'app/routes/oauth-consent.tsx' }}
+ import { useClerk, useOAuthConsent } from '@clerk/tanstack-react-start'
+ import { createFileRoute } from '@tanstack/react-router'
+
+ export const Route = createFileRoute('/oauth-consent')({
+ head: () => ({
+ meta: [
+ {
+ name: 'referrer',
+ content: 'strict-origin-when-cross-origin',
+ },
+ ],
+ }),
+ validateSearch: (search: Record) => ({
+ client_id: typeof search.client_id === 'string' ? search.client_id : '',
+ scope: typeof search.scope === 'string' ? search.scope : undefined,
+ }),
+ component: OAuthConsentPage,
+ })
+
+ function OAuthConsentPage() {
+ const clerk = useClerk()
+ const params = Route.useSearch()
+ const clientId = params.client_id
+ const scope = params.scope
+
+ const { data, isLoading, error } = useOAuthConsent({
+ oauthClientId: clientId,
+ scope,
+ })
+
+ const actionUrl = clerk.oauthApplication.buildConsentActionUrl({ clientId })
+
+ if (isLoading) return Loading...
+ if (error) return Something went wrong.
+
+ return (
+
+ )
+ }
+ ```
+
diff --git a/docs/reference/objects/clerk.mdx b/docs/reference/objects/clerk.mdx
index 8bf3f82f75..d8889848a3 100644
--- a/docs/reference/objects/clerk.mdx
+++ b/docs/reference/objects/clerk.mdx
@@ -115,6 +115,13 @@ The `Clerk` class serves as the central interface for working with Clerk's authe
---
+ - `oauthApplication`
+ - [`OAuthApplication`][oauth-application-ref]
+
+ The `OAuthApplication` object used for building custom OAuth consent flows.
+
+ ---
+
- `proxyUrl`
- `string | undefined`
@@ -1433,6 +1440,11 @@ The `Clerk` class also contains a number of methods for interacting with prebuil
- [`mountOrganizationList`](/docs/reference/components/organization/organization-list#mount-organization-list)
- [`unmountOrganizationList`](/docs/reference/components/organization/organization-list#unmount-organization-list)
+### `
`
+
+- [`mountOAuthConsent`](/docs/reference/components/authentication/oauth-consent#mount-o-auth-consent)
+- [`unmountOAuthConsent`](/docs/reference/components/authentication/oauth-consent#unmount-o-auth-consent)
+
### `
`
- [`mountWaitlist()`](/docs/reference/components/authentication/waitlist#mount-waitlist)
@@ -1476,6 +1488,8 @@ The `Clerk` class also contains a number of methods for interacting with prebuil
[organization-ref]: /docs/reference/objects/organization
+[oauth-application-ref]: /docs/reference/types/oauth-application
+
[api-ref]: /docs/reference/objects/api-keys
[billing-ref]: /docs/reference/objects/billing
diff --git a/docs/reference/types/oauth-application.mdx b/docs/reference/types/oauth-application.mdx
new file mode 100644
index 0000000000..1c8dbaaadd
--- /dev/null
+++ b/docs/reference/types/oauth-application.mdx
@@ -0,0 +1,71 @@
+---
+title: '`OAuthApplication`'
+description: The OAuthApplication object provides helpers for building custom OAuth consent flows in Clerk.
+sdk: js-frontend, astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start, nuxt, vue
+---
+
+The `OAuthApplication` object provides helpers for building custom OAuth consent flows in Clerk.
+
+Use this object together with the [`useOAuthConsent()`](/docs/reference/hooks/use-oauth-consent) hook or the [`
`](/docs/reference/components/authentication/oauth-consent) component when you need to render a custom consent page for an OAuth application.
+
+## Methods
+
+### `buildConsentActionUrl()`
+
+Returns the URL to use as the `action` attribute of your consent form. Clerk includes the current session context automatically, including `_clerk_session_id` and, in development, the dev browser JWT.
+
+```typescript
+function buildConsentActionUrl(params: { clientId: string }): string
+```
+
+#### Parameters
+
+
+ - `clientId`
+ - `string`
+
+ The OAuth `client_id` from the authorize request.
+
+
+#### Example
+
+```tsx
+const actionUrl = clerk.oauthApplication.buildConsentActionUrl({
+ clientId,
+})
+```
+
+### `getConsentInfo()`
+
+Loads the consent metadata for a signed-in user and OAuth application. Returns a [`OAuthConsentInfo`](/docs/reference/types/oauth-consent-info) object.
+
+Use this method when you want to build your own consent UI without the [`useOAuthConsent()`](/docs/reference/hooks/use-oauth-consent) hook.
+
+```typescript
+function getConsentInfo(params: GetOAuthConsentInfoParams): Promise
+```
+
+#### `GetOAuthConsentInfoParams`
+
+
+ - `oauthClientId`
+ - `string`
+
+ The OAuth `client_id` from the authorize request.
+
+ ---
+
+ - `scope?`
+ - `string`
+
+ A space-delimited scope string from the authorize request.
+
+
+#### Example
+
+```tsx
+const consentInfo = await clerk.oauthApplication.getConsentInfo({
+ oauthClientId: clientId,
+ scope,
+})
+```
diff --git a/docs/reference/types/oauth-consent-info.mdx b/docs/reference/types/oauth-consent-info.mdx
new file mode 100644
index 0000000000..31cb85498a
--- /dev/null
+++ b/docs/reference/types/oauth-consent-info.mdx
@@ -0,0 +1,7 @@
+---
+title: '`OAuthConsentInfo`'
+description: An interface representing OAuth consent information.
+sdk: js-frontend, astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start, nuxt, vue
+---
+
+
diff --git a/docs/reference/types/oauth-consent-scope.mdx b/docs/reference/types/oauth-consent-scope.mdx
new file mode 100644
index 0000000000..b1c313f1f2
--- /dev/null
+++ b/docs/reference/types/oauth-consent-scope.mdx
@@ -0,0 +1,7 @@
+---
+title: '`OAuthConsentScope`'
+description: An interface representing a single OAuth scope with its description and whether it requires consent.
+sdk: js-frontend, astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start, nuxt, vue
+---
+
+
diff --git a/scripts/build-docs.ts b/scripts/build-docs.ts
index d695ded7b0..7bdafc126c 100644
--- a/scripts/build-docs.ts
+++ b/scripts/build-docs.ts
@@ -197,11 +197,7 @@ async function main() {
'guides/development/webhooks/inngest.mdx': ['doc-not-in-manifest'],
'guides/development/webhooks/loops.mdx': ['doc-not-in-manifest'],
},
- typedoc: {
- 'shared/o-auth-application-namespace.mdx': ['link-doc-not-found'],
- 'shared/o-auth-consent-info.mdx': ['link-doc-not-found'],
- 'shared/use-o-auth-consent-return.mdx': ['link-doc-not-found'],
- },
+ typedoc: {},
partials: {},
tooltips: {},
},