Build a sign-in flow with Clerk Elements
You will learn the following:
- Build out different steps of an authentication flow
- Accept user input through form fields
- Verify a user's identity during a sign-in attempt
- Support various password-related features
Add a sign-in route
Create a new route in your Next.js application. The route needs to be an optional catch-all route so the sign-in flow can handled nested paths, as shown in the following example:
'use client'
import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'
export default function SignInPage() {
return <SignIn.Root>[Sign In Root]</SignIn.Root>
}
You will use these two imports to build out the rest of the flow. <SignIn.Root>
manages the sign-in state and handles connecting the components to Clerk's APIs.
Add the start step
The Clerk authentication flows are made up of steps. Steps handle rendering the UI for each part of the flow. To allow users to create a sign-in attempt, the start
step needs to be rendered. The following example does so with the <SignIn.Step>
component:
'use client'
import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'
export default function SignInPage() {
return (
<SignIn.Root>
<SignIn.Step name="start">
<h1>Sign in to your account</h1>
</SignIn.Step>
</SignIn.Root>
)
}
Add form fields
Make it functional by adding input fields. The following example uses the <Clerk.Field>
component to render an identifier
field, as well as the <Connection>
component to allow users to sign in with a social connection, like Google:
'use client'
import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'
export default function SignInPage() {
return (
<SignIn.Root>
<SignIn.Step name="start">
<h1>Sign in to your account</h1>
<Clerk.Connection name="google">Sign in with Google</Clerk.Connection>
<Clerk.Field name="identifier">
<Clerk.Label>Email</Clerk.Label>
<Clerk.Input />
<Clerk.FieldError />
</Clerk.Field>
<SignIn.Action submit>Continue</SignIn.Action>
</SignIn.Step>
</SignIn.Root>
)
}
<Clerk.Field>
takes care of wiring up the input with the label element, and <Clerk.FieldError>
will render any field-specific errors that get returned from Clerk's API. The <SignIn.Action>
component provides common actions that are used throughout the flows. In this case, using the submit
action to render a submit button for the start form.
Add verification
As users progress through a sign-in attempt, they may be asked to verify a number of authentication factors in the verifications
step. You can render a form for the user to complete verification, but each verification strategy requires different fields. You must render the form fields conditionally for each authentication strategy your instance supports using the <SignIn.Strategy>
component.
The following example demonstrates how to conditionally render a form for the email_code
strategy:
'use client'
import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'
export default function SignInPage() {
return (
<SignIn.Root>
<SignIn.Step name="start">
<h1>Sign in to your account</h1>
<Clerk.Connection name="google">Sign in with Google</Clerk.Connection>
<Clerk.Field name="identifier">
<Clerk.Label>Email</Clerk.Label>
<Clerk.Input />
<Clerk.FieldError />
</Clerk.Field>
<SignIn.Action submit>Continue</SignIn.Action>
</SignIn.Step>
<SignIn.Step name="verifications">
<SignIn.Strategy name="email_code">
<h1>Check your email</h1>
<p>
We sent a code to <SignIn.SafeIdentifier />.
</p>
<Clerk.Field name="code">
<Clerk.Label>Email code</Clerk.Label>
<Clerk.Input />
<Clerk.FieldError />
</Clerk.Field>
<SignIn.Action submit>Continue</SignIn.Action>
</SignIn.Strategy>
</SignIn.Step>
</SignIn.Root>
)
}
Verification is the final step in the sign-in flow. When a user has verified all required factors, the sign-in attempt will be complete and they will be signed in.
Add password support
If your instance is configured to support authenticating with passwords, you must add a few additional steps and verification strategies. You can choose if you want to support providing a password in the start
step with an additional field, or as an additional verification strategy. For this guide, add it as a standalone verification strategy.
'use client'
import * as Clerk from '@clerk/elements/common'
import * as SignIn from '@clerk/elements/sign-in'
export default function SignInPage() {
return (
<SignIn.Root>
<SignIn.Step name="start">
<h1>Sign in to your account</h1>
<Clerk.Connection name="google">Sign in with Google</Clerk.Connection>
<Clerk.Field name="identifier">
<Clerk.Label>Email</Clerk.Label>
<Clerk.Input />
<Clerk.FieldError />
</Clerk.Field>
<SignIn.Action submit>Continue</SignIn.Action>
</SignIn.Step>
<SignIn.Step name="verifications">
<SignIn.Strategy name="email_code">
<h1>Check your email</h1>
<p>
We sent a code to <SignIn.SafeIdentifier />.
</p>
<Clerk.Field name="code">
<Clerk.Label>Email code</Clerk.Label>
<Clerk.Input />
<Clerk.FieldError />
</Clerk.Field>
<SignIn.Action submit>Continue</SignIn.Action>
</SignIn.Strategy>
<SignIn.Strategy name="password">
<h1>Enter your password</h1>
<Clerk.Field name="password">
<Clerk.Label>Password</Clerk.Label>
<Clerk.Input />
<Clerk.FieldError />
</Clerk.Field>
<SignIn.Action submit>Continue</SignIn.Action>
<SignIn.Action navigate="forgot-password">Forgot password?</SignIn.Action>
</SignIn.Strategy>
<SignIn.Strategy name="reset_password_email_code">
<h1>Check your email</h1>
<p>
We sent a code to <SignIn.SafeIdentifier />.
</p>
<Clerk.Field name="code">
<Clerk.Label>Email code</Clerk.Label>
<Clerk.Input />
<Clerk.FieldError />
</Clerk.Field>
<SignIn.Action submit>Continue</SignIn.Action>
</SignIn.Strategy>
</SignIn.Step>
<SignIn.Step name="forgot-password">
<h1>Forgot your password?</h1>
<SignIn.SupportedStrategy name="reset_password_email_code">
Reset password
</SignIn.SupportedStrategy>
<SignIn.Action navigate="previous">Go back</SignIn.Action>
</SignIn.Step>
<SignIn.Step name="reset-password">
<h1>Reset your password</h1>
<Clerk.Field name="password">
<Clerk.Label>New password</Clerk.Label>
<Clerk.Input />
<Clerk.FieldError />
</Clerk.Field>
<Clerk.Field name="confirmPassword">
<Clerk.Label>Confirm password</Clerk.Label>
<Clerk.Input />
<Clerk.FieldError />
</Clerk.Field>
<SignIn.Action submit>Reset password</SignIn.Action>
</SignIn.Step>
</SignIn.Root>
)
}
To enable users to reset their passwords, you can add the following additional steps:
forgot-password
– Renders<SignIn.SupportedStrategy>
, which initiates the reset process, whereby an email code is sent to the user for verification.<SignIn.SupportedStrategy>
is also used in theforgot-password
andchoose-strategy
steps to trigger verification of a supported strategy.
reset-password
– Allows a verified user to input a new password. If your instance has been set up to accept SMS codes, you can also usereset_password_phone_code
.
Customize and add styling
Learn how to style your Clerk Elements components with the styling guide.
For more extensive customization of the UI, see the additional Clerk Elements components such as <Loading>
and <FieldState>
.
Feedback
Last updated on