Custom email/password flow
Clerk supports password authentication, which allows users to sign up and sign in using their email address and password. This guide will walk you through how to build a custom email/password sign-up and sign-in flow using the useSignUp()
and useSignIn()
React hooks.
Enable password and email
In the Clerk dashboard, you will need to enable both email and password as a sign-in and sign-up method. Go to User & Authentication > Email, Phone, and Username.Toggle on Email address and Password.

Create sign up flow
The email/password sign-up flow requires users to provide their email address and their password and returns a newly-created user with an active session.
A successful sign-up consists of the following steps:
- Initiate the sign-up process by collecting the user's email address and password.
- Prepare the email address verification, which sends a one-time code to the given address.
- Attempt to complete the email address verification by supplying the one-time code.
- If the email address verification is successful, complete the sign-up process by creating the user account and setting their session as active.
'use client'
import * as React from 'react';
import { useSignUp } from '@clerk/nextjs';
import { useRouter } from 'next/navigation';
import { ClerkAPIErrorJSON } from '@clerk/types';
export default function Page() {
const { isLoaded, signUp, setActive } = useSignUp();
const [emailAddress, setEmailAddress] = React.useState("");
const [password, setPassword] = React.useState("");
const [verifying, setVerifying] = React.useState(false);
const [code, setCode] = React.useState("");
const router = useRouter();
// This function will handle the user submitting their email and password
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!isLoaded) return;
// Start the sign-up process using the email and password provided
try {
await signUp.create({
emailAddress, password
});
// 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) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error('Error:', JSON.stringify(err, null, 2));
}
}
// This function will handle the user submitting a code for verification
const handleVerify = async (e: React.FormEvent) => {
e.preventDefault();
if (!isLoaded) return;
try {
// Submit the code that the user provides to attempt verification
const completeSignUp = await signUp.attemptEmailAddressVerification({
code
});
if (completeSignUp.status !== "complete") {
// The status can also be `abandoned` or `missing_requirements`
// Please see https://clerk.com/docs/references/react/use-sign-up#result-status for more information
console.log(JSON.stringify(completeSignUp, null, 2));
}
// Check the status to see if it is complete
// If complete, the user has been created -- set the session active
if (completeSignUp.status === "complete") {
await setActive({ session: completeSignUp.createdSessionId });
// Redirect the user to a post sign-up route
router.push("/");
}
}
catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error('Error:', JSON.stringify(err, null, 2));
}
}
// Once the sign-up form was submitted, verifying was set to true and as a result, this verification form is presented to the user to input their verification code.
if (verifying) {
return (
<form onSubmit={handleVerify}>
<label id="code">Code</label>
<input value={code} id="code" name="code" onChange={(e) => setCode(e.target.value)} />
<button type="submit">Complete Sign Up</button>
</form>
)
}
// Display the initial sign-up form to capture the email and password
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email address</label>
<input id="email" type='email' name="email" value={emailAddress} onChange={(e) => setEmailAddress(e.target.value)} />
</div>
<div>
<label className="block text-sm mt-8" htmlFor="password">Password</label>
<input id="password" type='password' name="password" value={password} onChange={(e) => setPassword(e.target.value)} />
</div>
<div>
<button type="submit">Verify Email</button>
</div>
</form>
);
}
import { useState } from "react";
import { useSignUp } from "@clerk/nextjs";
import { useRouter } from "next/router";
export default function SignUpForm() {
const { isLoaded, signUp, setActive } = useSignUp();
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
const [pendingVerification, setPendingVerification] = useState(false);
const [code, setCode] = useState("");
const router = useRouter();
// This function will handle the user submitting their email and password
const handleSubmit = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
// Start the sign-up process using the email and password provided
try {
await signUp.create({
emailAddress,
password,
});
// 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
setPendingVerification(true);
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// This function will handle the user submitting a code for verification
const onPressVerify = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
try {
// Submit the code that the user provides to attempt verification
const completeSignUp = await signUp.attemptEmailAddressVerification({
code,
});
if (completeSignUp.status !== "complete") {
// The status can also be `abandoned` or `missing_requirements`
// Please see https://clerk.com/docs/references/react/use-sign-up#result-status for more information
console.log(JSON.stringify(completeSignUp, null, 2));
}
// Check the status to see if it is complete
// If complete, the user has been created -- set the session active
if (completeSignUp.status === "complete") {
await setActive({ session: completeSignUp.createdSessionId })
// Redirect the user to a post sign-up route
router.push("/");
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
return (
<div>
{!pendingVerification && (
<form>
<div>
<label htmlFor="email">Email</label>
<input onChange={(e) => setEmailAddress(e.target.value)} id="email" name="email" type="email" />
</div>
<div>
<label htmlFor="password">Password</label>
<input onChange={(e) => setPassword(e.target.value)} id="password" name="password" type="password" />
</div>
<button onClick={handleSubmit}>Sign up</button>
</form>
)}
{pendingVerification && (
<div>
<form>
<input
value={code}
placeholder="Code..."
onChange={(e) => setCode(e.target.value)}
/>
<button onClick={onPressVerify}>
Verify Email
</button>
</form>
</div>
)}
</div>
);
}
import { useState } from "react";
import { useSignUp } from "@clerk/clerk-react";
export default function SignUpForm() {
const { isLoaded, signUp, setActive } = useSignUp();
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
const [verifying, setVerifying] = React.useState(false);
const [code, setCode] = useState("");
// This function will handle the user submitting their email and password
const handleSubmit = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
// Start the sign-up process using the email and password provided
try {
await signUp.create({
emailAddress,
password,
});
// 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) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// This function will handle the user submitting a code for verification
const handleVerify = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
try {
// Submit the code that the user provides to attempt verification
const completeSignUp = await signUp.attemptEmailAddressVerification({
code,
});
if (completeSignUp.status !== "complete") {
// The status can also be `abandoned` or `missing_requirements`
// Please see https://clerk.com/docs/references/react/use-sign-up#result-status for more information
console.log(JSON.stringify(completeSignUp, null, 2));
}
// Check the status to see if it is complete
// If complete, the user has been created -- set the session active
if (completeSignUp.status === "complete") {
await setActive({ session: completeSignUp.createdSessionId })
// Handle your own logic here, like redirecting to a new page if needed.
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
return (
<div>
{!verifying && (
<form>
<div>
<label htmlFor="email">Email</label>
<input onChange={(e) => setEmailAddress(e.target.value)} id="email" name="email" type="email" />
</div>
<div>
<label htmlFor="password">Password</label>
<input onChange={(e) => setPassword(e.target.value)} id="password" name="password" type="password" />
</div>
<button onClick={handleSubmit}>Sign up</button>
</form>
)}
{verifying && (
<div>
<form>
<input
value={code}
placeholder="Code..."
onChange={(e) => setCode(e.target.value)}
/>
<button onClick={handleVerify}>
Verify Email
</button>
</form>
</div>
)}
</div>
);
}
import { useState } from "react";
import { useSignUp } from "@clerk/remix";
export default function SignUpForm() {
const { isLoaded, signUp, setActive } = useSignUp();
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
const [verifying, setVerifying] = React.useState(false);
const [code, setCode] = useState("");
// This function will handle the user submitting their email and password
const handleSubmit = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
// Start the sign-up process using the email and password provided
try {
await signUp.create({
emailAddress,
password,
});
// 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) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// This function will handle the user submitting a code for verification
const handleVerify = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
try {
// Submit the code that the user provides to attempt verification
const completeSignUp = await signUp.attemptEmailAddressVerification({
code,
});
if (completeSignUp.status !== "complete") {
// The status can also be `abandoned` or `missing_requirements`
// Please see https://clerk.com/docs/references/react/use-sign-up#result-status for more information
or if the user needs to complete more steps.*/
console.log(JSON.stringify(completeSignUp, null, 2));
}
// Check the status to see if it is complete
// If complete, the user has been created -- set the session active
if (completeSignUp.status === "complete") {
await setActive({ session: completeSignUp.createdSessionId })
// Handle your own logic here, like redirecting to a new page if needed.
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
return (
<div>
{!verifying && (
<form>
<div>
<label htmlFor="email">Email</label>
<input onChange={(e) => setEmailAddress(e.target.value)} id="email" name="email" type="email" />
</div>
<div>
<label htmlFor="password">Password</label>
<input onChange={(e) => setPassword(e.target.value)} id="password" name="password" type="password" />
</div>
<button onClick={handleSubmit}>Sign up</button>
</form>
)}
{verifying && (
<div>
<form>
<input
value={code}
placeholder="Code..."
onChange={(e) => setCode(e.target.value)}
/>
<button onClick={handleVerify}>
Verify Email
</button>
</form>
</div>
)}
</div>
);
}
import { useState } from "react";
// Use the react package when using Gatsby
import { useSignUp } from "@clerk/react";
import { useRouter } from "next/router";
export default function SignUpForm() {
const { isLoaded, signUp, setActive } = useSignUp();
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
const [verifying, setVerifying] = React.useState(false);
const [code, setCode] = useState("");
const router = useRouter();
// This function will handle the user submitting their email and password
const handleSubmit = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
// Start the sign-up process using the email and password provided
try {
await signUp.create({
emailAddress,
password,
});
// 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) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// This function will handle the user submitting a code for verification
const handleVerify = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
try {
// Submit the code that the user provides to attempt verification
const completeSignUp = await signUp.attemptEmailAddressVerification({
code,
});
if (completeSignUp.status !== "complete") {
// The status can also be `abandoned` or `missing_requirements`
// Please see https://clerk.com/docs/references/react/use-sign-up#result-status for more information
console.log(JSON.stringify(completeSignUp, null, 2));
}
// Check the status to see if it is complete
// If complete, the user has been created -- set the session active
if (completeSignUp.status === "complete") {
await setActive({ session: completeSignUp.createdSessionId })
// Redirect the user to a post sign-up route
router.push("/");
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
return (
<div>
{!verifying && (
<form>
<div>
<label htmlFor="email">Email</label>
<input onChange={(e) => setEmailAddress(e.target.value)} id="email" name="email" type="email" />
</div>
<div>
<label htmlFor="password">Password</label>
<input onChange={(e) => setPassword(e.target.value)} id="password" name="password" type="password" />
</div>
<button onClick={handleSubmit}>Sign up</button>
</form>
)}
{verifying && (
<div>
<form>
<input
value={code}
placeholder="Code..."
onChange={(e) => setCode(e.target.value)}
/>
<button onClick={handleVerify}>
Verify Email
</button>
</form>
</div>
)}
</div>
);
}
import * as React from "react";
import { Text, TextInput, TouchableOpacity, View } from "react-native";
import { useSignUp } from "@clerk/clerk-expo";
export default function SignUpScreen() {
const { isLoaded, signUp, setActive } = useSignUp();
const [emailAddress, setEmailAddress] = React.useState("");
const [password, setPassword] = React.useState("");
const [verifying, setVerifying] = React.useState(false);
const [code, setCode] = React.useState("");
// This function will handle the user submitting their email and password
const onSignUpPress = async () => {
if (!isLoaded) {
return;
}
// Start the sign-up process using the email and password provided
try {
await signUp.create({
emailAddress,
password,
});
// 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) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// This function will handle the user submitting a code for verification
const handleVerify = async () => {
if (!isLoaded) {
return;
}
try {
// Submit the code that the user provides to attempt verification
const completeSignUp = await signUp.attemptEmailAddressVerification({
code,
});
if (completeSignUp.status !== "complete") {
// The status can also be `abandoned` or `missing_requirements`
// Please see https://clerk.com/docs/references/react/use-sign-up#result-status for more information
console.log(JSON.stringify(completeSignUp, null, 2));
}
// Check the status to see if it is complete
// If complete, the user has been created -- set the session active
if (completeSignUp.status === "complete") {
await setActive({ session: completeSignUp.createdSessionId });
// Handle your own logic here, like redirecting to a new page if needed.
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
return (
<View>
{!verifying && (
<View>
<View>
<TextInput
autoCapitalize="none"
value={emailAddress}
placeholder="Email..."
onChangeText={(email) => setEmailAddress(email)}
/>
</View>
<View>
<TextInput
value={password}
placeholder="Password..."
placeholderTextColor="#000"
secureTextEntry={true}
onChangeText={(password) => setPassword(password)}
/>
</View>
<TouchableOpacity onPress={onSignUpPress}>
<Text>Sign up</Text>
</TouchableOpacity>
</View>
)}
{verifying && (
<View>
<View>
<TextInput
value={code}
placeholder="Code..."
onChangeText={(code) => setCode(code)}
/>
</View>
<TouchableOpacity onPress={handleVerify}>
<Text>Verify Email</Text>
</TouchableOpacity>
</View>
)}
</View>
);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Clerk JavaScript Email + Password</title>
</head>
<body>
<h1>Clerk JavaScript Email + Password</h1>
<div id="auth-signup">
<input placeholder="email" id="email" type="email"></input>
<input placeholder="password" id="password" type="password"></input>
<button onclick="SignUp()">SignUp</button>
</div>
<div id="auth-verification" hidden="true">
<input placeholder="code" id="code" type="text"></input>
<button onclick="VerifyEmailAddress()">Verify</button>
</div>
<div id="user-button" />
<script>
const SignUp = async () => {
const emailAddress = document.getElementById('email').value;
const password = document.getElementById('password').value;
const {client} = window.Clerk;
try {
await client.signUp.create({
emailAddress,
password
});
await client.signUp.prepareEmailAddressVerification();
//hide signup form
document.getElementById('auth-signup').hidden = true;
//show verification form
document.getElementById('auth-verification').hidden = false;
}
catch (err) {
console.log(err)
}
};
const VerifyEmailAddress = async () => {
const code = document.getElementById('code').value;
const {client, setActive} = window.Clerk;
try {
// Verify the email address.
const verify = await client.signUp.attemptEmailAddressVerification({
code
});
// User is created. Now, set the session to active. session is never null.
await setActive({session: verify.createdSessionId})
}
catch (err) {
console.log(err)
}
}
</script>
// Script to load Clerk up
<script src="src/script.js" async crossorigin="anonymous"></script>
</body>
</html>
Create sign in flow
In email/password authentication, the sign-in is a process that requires users to provide their email address and their password and authenticates them by creating a new session for the user.
'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 router = useRouter();
// Handle the submission of the sign-in form
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!isLoaded) {
return;
}
// Start the sign-in process using the email and password provided
try {
const completeSignIn = await signIn.create({
identifier: email,
password,
});
if (completeSignIn.status !== 'complete') {
// The status can also be `needs_factor_on', 'needs_factor_two', or 'needs_identifier'
// Please see https://clerk.com/docs/references/react/use-sign-in#result-status for more information
console.log(JSON.stringify(completeSignIn, null, 2));
}
if (completeSignIn.status === 'complete') {
// If complete, user exists and provided password match -- set session active
await setActive({ session: completeSignIn.createdSessionId });
// Redirect the user to a post sign-in route
router.push('/');
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// Display a form to capture the user's email and password
return (
<div>
<form onSubmit={(e) => handleSubmit(e)}>
<div>
<label htmlFor="email">Email</label>
<input onChange={(e) => setEmail(e.target.value)} id="email" name="email" type="email" value={email} />
</div>
<div>
<label htmlFor="password">Password</label>
<input onChange={(e) => setPassword(e.target.value)} id="password" name="password" type="password" value={password} />
</div>
<button type="submit">Sign In</button>
</form>
</div>
);
}
import { useState } from "react";
import { useSignIn } from "@clerk/nextjs";
import { useRouter } from "next/router";
export default function SignInForm() {
const { isLoaded, signIn, setActive } = useSignIn();
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
const router = useRouter();
// Handle the submission of the sign-in form
const handleSubmit = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
// Start the sign-in process using the email and password provided
try {
const result = await signIn.create({
identifier: emailAddress,
password,
});
if (result.status === "complete") {
// If complete, user exists and provided password match -- set session active
await setActive({ session: result.createdSessionId });
// Redirect the user to a post sign-in route
router.push("/")
}
else {
// The status can also be `needs_factor_on', 'needs_factor_two', or 'needs_identifier'
// Please see https://clerk.com/docs/references/react/use-sign-in#result-status for more information
console.error(JSON.stringify(results, null, 2));
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// Display a form to capture the user's email and password
return (
<div>
<form>
<div>
<label htmlFor="email">Email</label>
<input onChange={(e) => setEmailAddress(e.target.value)} id="email" name="email" type="email" />
</div>
<div>
<label htmlFor="password">Password</label>
<input onChange={(e) => setPassword(e.target.value)} id="password" name="password" type="password" />
</div>
<button onClick={handleSubmit}>Sign In</button>
</form>
</div>
);
}
import { useState } from "react";
import { useSignIn } from "@clerk/clerk-react";
export default function SignInForm() {
const { isLoaded, signIn, setActive } = useSignIn();
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
// Handle the submission of the sign-in form
const handleSubmit = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
// Start the sign-in process using the email and password provided
try {
const completeSignIn = await signIn.create({
identifier: emailAddress,
password,
});
if (completeSignIn.status !== 'complete') {
// The status can also be `needs_factor_on', 'needs_factor_two', or 'needs_identifier'
// Please see https://clerk.com/docs/references/react/use-sign-in#result-status for more information
console.log(JSON.stringify(completeSignIn, null, 2));
}
if (completeSignIn.status === "complete") {
// If complete, user exists and provided password match -- set session active
await setActive({ session: completeSignIn.createdSessionId });
// redirect the user how you see fit.
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
return (
<div>
<form>
<div>
<label htmlFor="email">Email</label>
<input onChange={(e) => setEmailAddress(e.target.value)} id="email" name="email" type="email" />
</div>
<div>
<label htmlFor="password">Password</label>
<input onChange={(e) => setPassword(e.target.value)} id="password" name="password" type="password" />
</div>
<button onClick={handleSubmit}>Sign In</button>
</form>
</div>
);
}
import { useState } from "react";
import { useSignIn } from "@clerk/remix";
export default function SignInForm() {
const { isLoaded, signIn, setActive } = useSignIn();
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
// Start the sign-in process using the email and password provided
const handleSubmit = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
// Start the sign-in process using the email and password provided
try {
const completeSignIn = await signIn.create({
identifier: emailAddress,
password,
});
if (completeSignIn.status !== 'complete') {
// The status can also be `needs_factor_on', 'needs_factor_two', or 'needs_identifier'
// Please see https://clerk.com/docs/references/react/use-sign-in#result-status for more information
console.log(JSON.stringify(completeSignIn, null, 2));
}
if (completeSignIn.status === 'complete') {
// If complete, user exists and provided password match -- set session active
await setActive({ session: completeSignIn.createdSessionId });
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// Display a form to capture the user's email and password
return (
<div>
<form>
<div>
<label htmlFor="email">Email</label>
<input onChange={(e) => setEmailAddress(e.target.value)} id="email" name="email" type="email" />
</div>
<div>
<label htmlFor="password">Password</label>
<input onChange={(e) => setPassword(e.target.value)} id="password" name="password" type="password" />
</div>
<button onClick={handleSubmit}>Sign In</button>
</form>
</div>
);
}
import { useState } from "react";
// Use React for Gatsby
import { useSignIn } from "@clerk/clerk-react";
export default function SignInForm() {
const { isLoaded, signIn, setActive } = useSignIn();
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
// Handle the submission of the sign-in form
const handleSubmit = async (e) => {
e.preventDefault();
if (!isLoaded) {
return;
}
// Start the sign-in process using the email and password provided
try {
const completeSignIn = await signIn.create({
identifier: emailAddress,
password,
});
if (completeSignIn.status !== 'complete') {
// The status can also be `needs_factor_on', 'needs_factor_two', or 'needs_identifier'
// Please see https://clerk.com/docs/references/react/use-sign-in#result-status for more information
console.log(JSON.stringify(completeSignIn, null, 2));
}
if (completeSignIn.status === 'complete') {
// If complete, user exists and provided password match -- set session active
await setActive({ session: completeSignIn.createdSessionId });
// Redirect the user to a post sign-in route
router.push('/');
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// Display a form to capture the user's email and password
return (
<div>
<form>
<div>
<label htmlFor="email">Email</label>
<input onChange={(e) => setEmailAddress(e.target.value)} id="email" name="email" type="email" />
</div>
<div>
<label htmlFor="password">Password</label>
<input onChange={(e) => setPassword(e.target.value)} id="password" name="password" type="password" />
</div>
<button onClick={handleSubmit}>Sign In</button>
</form>
</div>
);
}
import React from "react";
import { Text, TextInput, TouchableOpacity, View } from "react-native";
import { useSignIn } from "@clerk/clerk-expo";
export default function SignInScreen() {
const { signIn, setActive, isLoaded } = useSignIn();
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 completeSignIn = await signIn.create({
identifier: emailAddress,
password,
});
if (completeSignIn.status !== 'complete') {
// The status can also be `needs_factor_on', 'needs_factor_two', or 'needs_identifier'
// Please see https://clerk.com/docs/references/react/use-sign-in#result-status for more information
console.log(JSON.stringify(completeSignIn, null, 2));
}
if (completeSignIn.status === 'complete') {
// If complete, user exists and provided password match -- set session active
await setActive({ session: completeSignIn.createdSessionId });
// Redirect the user to a post sign-in route
router.push('/');
}
} catch (err: any) {
// This can return an array of errors.
// See https://clerk.com/docs/custom-flows/error-handling to learn about error handling
console.error(JSON.stringify(err, null, 2));
}
};
// Display a form to capture the user's email and password
return (
<View>
<View>
<TextInput
autoCapitalize="none"
value={emailAddress}
placeholder="Email..."
onChangeText={(emailAddress) => setEmailAddress(emailAddress)}
/>
</View>
<View>
<TextInput
value={password}
placeholder="Password..."
secureTextEntry={true}
onChangeText={(password) => setPassword(password)}
/>
</View>
<TouchableOpacity onPress={onSignInPress}>
<Text>Sign in</Text>
</TouchableOpacity>
</View>
);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Clerk JavaScript Email + Password</title>
</head>
<body>
<h1>Clerk JavaScript Email + Password</h1>
<div id="auth-signin">
<input placeholder="email" id="email" type="email"></input>
<input placeholder="password" id="password" type="password"></input>
<button onclick="SignIn()">SignIn</button>
</div>
<script>
const SignIn = async () => {
const emailAddress = document.getElementById('email').value;
const password = document.getElementById('password').value;
const {client} = window.Clerk;
try {
const signInAttempt = await client.signIn.create({
emailAddress,
password
});
if (signInAttempt.status === "complete") {
await setActive({ session: signInAttempt.createdSessionId });
// redirect the user how you see fit.
}
else {
/*Investigate why the sign-in hasn't completed */
console.log(signInAttempt);
}
}
catch (err) {
console.log(err)
}
};
</script>
// Script to load Clerk up
<script src="src/script.js" async crossorigin="anonymous"></script>
</body>
</html>
Feedback
Last updated on