Appearance
SMS
To authenticate with an OTP sent to their phone number, use the useLoginWithSms
hook.
The useLoginWithSms
hook returns two methods necessary for the authentication flow:
sendCode
: sends an OTP to the user's email address or phone numberloginWithCode
: authenticates the user with the OTP sent to their email address or phone number
The hook also returns a state
variable that tracks the flow state of the login process.
Sending the OTP
To authenticate your users with SMS, first, prompt your user for their phone number and send an OTP to the number using the sendCode
method. As a required parameter to sendCode
, pass a JSON object with a variable containing the user's provided phone number as 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
Formatting the phone number
The sendCode
method from the useLoginWithSms
hook will require a phoneNumber
string param that must follow the formatting conventions below:
- By default, the implicit phone number country code is +1/US. Any phone number inputted is read as a US phone number.
- Explicitly prepending a
(+)1
to the phone number will do nothing, and the phone number will still be read and parsed as a US phone number. - If you are trying to send a message to a non (+1) phone number, you must append a
+${countryCode}
to the beginning of the input value. - The phone number will ignore all non-numerical values in the string except for when the first character is a
+
to denote a custom country code. This numerical string must be a valid phone number in the country code specified.
Authenticating with the OTP
Once the OTP has been sent via sendCode
, prompt your user for the OTP sent to their phone number 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 phone number 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 LoginWithSms
component for your app that uses these methods, like below:
tsx
import {useState} from 'react';
import {useLoginWithSms} from '@privy-io/react-auth';
export default function LoginWithSms() {
// Local State
const [phoneNumber, setPhoneNumber] = useState('');
const [code, setCode] = useState('');
// Privy
const {state, sendCode, loginWithCode} = useLoginWithSms();
return (
<div>
{/* Prompt your user to enter their phone number */}
<input onChange={(e) => setPhoneNumber(e.currentTarget.value)} />
{/* Once an email has been entered, send the OTP to it on click */}
<button onClick={() => sendCode({phoneNumber})}>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 useLoginWithSms
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.