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.