useOAuthConsent()
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 <OAuthConsent /> component, this hook doesn't read values from the current URL. Pass the oauthClientId explicitly. Optionally pass scope if you want Clerk to scope the request to a specific space-delimited scope string, and pass redirectUri when you need a public-suffix-aware redirectDomain for presenting the redirect destination.
Building a low-level custom consent flow is security-sensitive. For setup guidance, redirect URL presentation requirements, and a safer prebuilt component option, see Set up a custom OAuth consent page.
Parameters
useOAuthConsent() accepts a single object with the following properties:
- Name
-
data - Type
undefined | OAuthConsentInfo- Description
The OAuth consent screen metadata returned by Clerk, or
undefinedbefore the first successful fetch.
- Name
-
error - Type
null | ClerkAPIResponseError- Description
Any error that occurred during the data fetch, or
nullif no error occurred.
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, client_id and redirect_uri are read from the current URL and passed to the hook, and the form submits to the URL generated by the buildConsentActionUrl() method. The example intentionally focuses on the hook API; production consent pages must also clearly present the redirect destination and other security context described in Set up a custom OAuth consent page.
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 redirectUri = params.get('redirect_uri') ?? ''
const scope = params.get('scope') ?? undefined
const { data, isLoading, error } = useOAuthConsent({
oauthClientId: clientId,
scope,
redirectUri,
})
if (!clientId) return <div>Missing OAuth client ID.</div>
if (isLoading) return <div>Loading...</div>
if (error || !data) return <div>Something went wrong.</div>
const actionUrl = clerk.oauthApplication.buildConsentActionUrl({ clientId })
return (
<form method="POST" action={actionUrl}>
<h1>{data.oauthApplicationName} wants access to your account</h1>
<p>
Redirect destination:{' '}
<strong>{data.redirectDomain || new URL(redirectUri).hostname}</strong>
</p>
<ul>
{data.scopes.map((scope) => (
<li key={scope.scope}>{scope.description || scope.scope}</li>
))}
</ul>
<button type="submit" name="consented" value="false">
Deny
</button>
<button type="submit" name="consented" value="true">
Allow
</button>
{/* Forward the original OAuth parameters, except fields set by this form. */}
{Array.from(params.entries())
.filter(([key]) => key !== 'consented' && key !== 'organization_id')
.map(([key, value], index) => (
<input key={`${key}:${index}`} type="hidden" name={key} value={value} />
))}
</form>
)
}Feedback
Last updated on