Appearance
Email ​
To authenticate your users with a one-time passcode (OTP) sent to their email address, use the useLoginWithEmail
hook.
The useLoginWithEmail
hook returns two methods necessary for the authentication flow:
sendCode
: sends an OTP to the user's email addressloginWithCode
: authenticates the user with the OTP sent to their email address
The hook also returns a state
variable that tracks the flow state of the login process.
Sending the OTP ​
To authenticate your users with email, first, prompt your user for their email address and send an OTP to this address using the sendCode
method. As a required parameter to sendCode
, pass a JSON object with a variable containing the user's provided email addressas a string. When invoked, this method will return a Promise that:
- resolves to
void
if the OTP was successfully sent - rejects if there was an error
Authenticating with the OTP ​
Once the OTP has been sent via sendCode
, prompt your user for the OTP sent to their email address and use the loginWithCode
method to authenticate them. As a required parameter to loginWithCode
, pass a JSON object with a variable code
containing the OTP provided by the user as a string. When invoked, this method will return a Promise that:
- resolves to
void
if the entered OTP was correct, and the user has successfully authenticated - rejects if there was an error, such as an invalid code entry
To handle cases where a user accidentally enters the wrong OTP in your prompt, for a given OTP delivered to the user's email with sendCode
, you may call loginWithCode
up to a maximum of 5 times, to allow the user to retry if the code they entered is invalid. After 5 attempts, the OTP is no longer valid, and you must request a new code for the user via sendCode
.
Example usage ​
As an example, you might set up a LoginWithEmail
component for your app that uses these methods, like below:
tsx
import {useState} from 'react';
import {useLoginWithEmail} from '@privy-io/react-auth';
export default function LoginWithEmail() {
// Local State
const [email, setEmail] = useState('');
const [code, setCode] = useState('');
// Privy
const {state, sendCode, loginWithCode} = useLoginWithEmail();
return (
<div>
{/* Prompt your user to enter their email address */}
<input onChange={(e) => setEmail(e.currentTarget.value)} />
{/* Once an email has been entered, send the OTP to it on click */}
<button onClick={() => sendCode({email})}>Send Code</button>
{/* Prompt your user to enter the OTP */}
<input onChange={(e) => setCode(e.currentTarget.value)} />
{/* Once an OTP has been entered, submit it to Privy on click */}
<button onClick={() => loginWithCode({code})}>Log in</button>
</div>
);
}
Tracking login flow state ​
The state
variable returned from all of the useLoginWithEmail
hook will always be one of the following values.
ts
type OtpFlowState =
| {status: 'initial'}
| {status: 'error'; error: Error | null}
| {status: 'sending-code'}
| {status: 'awaiting-code-input'}
| {status: 'submitting-code'}
| {status: 'done'};
Learn more about conditional rendering with the state
variable in the state guide.