After-auth flows
You can configure your application to require users to complete specific actions after signing in or signing up. Users who don't complete these required actions will have their session remain in a pending
status, which is treated as a signed-out state by default.
Currently available configurations include:
With <SignIn />
and <SignUp>
After-auth flows are embedded within <SignIn />
and <SignUp>
by default. Currently, you cannot eject from these components to custom pages, but we're working on adding this capability.
Protections against pending
sessions
By default, pending
sessions are treated as signed-out state by default across utilities and control components.
Control components
import { Protect } from '@clerk/clerk-react'
export default function Page() {
return (
<Protect>
<p>User has no session or a pending session</p>
</Protect>
)
}
import { SignedOut } from '@clerk/clerk-react'
export default function Page() {
return (
<SignedOut>
<p>User has no session or a pending session</p>
</SignedOut>
)
}
import { SignedIn } from '@clerk/clerk-react'
export default function Page() {
return (
<SignedIn>
<p>User has a session that has fullfilled all after-auth actions</p>
</SignedIn>
)
}
Control components have treatPendingAsSignedOut
prop that defaults to true
, but you can opt-out of that behavior.
import { Protect } from '@clerk/clerk-react'
export default function Page() {
return (
<Protect treatPendingAsSignedOut={false}>
<p>User has no session</p>
</Protect>
)
}
import { SignedOut } from '@clerk/clerk-react'
export default function Page() {
return (
<SignedOut treatPendingAsSignedOut={false}>
<p>User has no session</p>
</SignedOut>
)
}
Server-side protections
Once a session is on a pending
status, then server utilities such as auth()
treat it as signed-out state by default.
Those utilities also accept a treatPendingAsSignedOut
option that defaults to true
, but you can opt-out of that behavior.
Taking disabling personal workspace as example:
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)'])
export default clerkMiddleware(async (auth, req) => {
// `auth.protect` will redirect users to select an organization
// if they don't have one, preventing access to protected pages
if (isProtectedRoute(req)) await auth.protect()
})
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)'])
export default clerkMiddleware(async (auth, req) => {
const { userId, redirectToSignIn } = await auth()
// `userId` won't be available if the user has a pending session
// without an organization
if (!userId && isProtectedRoute(req)) {
return redirectToSignIn()
}
})
import { auth } from '@clerk/nextjs/server'
export default async function Page() {
const { userId, orgId } = await auth()
if (!userId) {
return (
<p>
User has no session or a pending session meaning that it might not have an organization
selected
</p>
)
}
return (
<p>
<p>User has a valid session and {orgId} is defined</p>
</p>
)
}
Feedback
Last updated on