Privy enables users to login to your application with SMS or email. With Privy, your application can verify ownership of a user’s email address or phone number to send them notifications, campaigns, and more to keep them activated.

Configuring your application

Through your app’s Privy configuration, you can set the default country code for phone numbers. This is useful if your application primarily serves users from a specific country. The default country can be set in your PrivyProvider, like so:
<PrivyProvider
  appId="your-privy-app-id"
  config={{
    intl: {
      defaultCountry: "US",
    },
    ...insertTheRestOfYourPrivyProviderConfig
  }}
>
  {children}
</PrivyProvider>
To authenticate your users with a one-time passcode (OTP) sent to their phone number, use the useLoginWithSms hook.
To authenticate your users with Privy’s out of the box UIs, check out UI components here.

Send Code

sendCode: ({phoneNumber: string, disableSignup?: boolean}) => Promise<void>

Parameters

phoneNumber
string
required
The phone number of the user to log in. Must follow specific formatting conventions (see below).
disableSignup
boolean
Whether to disable the ability to sign up with the phone number.

Returns

void
Promise<void>
A promise that resolves when the code is sent.

Formatting the phone number

The sendCode method requires a phoneNumber string param that must follow these formatting conventions:
  • By default, the implicit phone number country code is +1/US.
  • Explicitly prepending a (+)1 to the phone number will still be read as a US phone number.
  • For non-US phone numbers, append a +${countryCode} to the beginning of the input value.
  • Non-numerical values in the string are ignored, except for a leading + that denotes a custom country code.

Login with Code

loginWithCode: ({ code: string }) => Promise<void>;

Parameters

code
string
required
The one-time passcode sent to the user’s phone number.

Returns

void
Promise<void>
A promise that resolves when the user is logged in.

Usage

import { useState } from "react";
import { useLoginWithSms } from "@privy-io/react-auth";

export default function LoginWithSms() {
  const [phoneNumber, setPhoneNumber] = useState("");
  const [code, setCode] = useState("");
  const { state, sendCode, loginWithCode } = useLoginWithSms();

  return (
    <div>
      {/* Prompt your user to enter their phone number */}
      <input onChange={(e) => setPhoneNumber(e.currentTarget.value)} value={phoneNumber} />
      {/* Once a phone number 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)} value={code} />
      {/* Once an OTP has been entered, submit it to Privy on click */}
      <button onClick={() => loginWithCode({ code })}>Log in</button>
    </div>
  );
}

Tracking Flow State

Track the state of the OTP flow via the state variable returned by the useLoginWithSms hook.
type OtpFlowState =
  | {status: 'initial'}
  | {status: 'error'; error: Error | null}
  | {status: 'sending-code'}
  | {status: 'awaiting-code-input'}
  | {status: 'submitting-code'}
  | {status: 'done'};
status
'initial' | 'error' | 'sending-code' | 'awaiting-code-input' | 'submitting-code' | 'done'
The current state of the OTP flow.
error
Error | null
The error that occurred during the OTP flow.

Callbacks

You can optionally pass callbacks into the useLoginWithSms hook to run custom logic after a successful login or to handle errors that occur during the flow.

onComplete

onComplete?: ((params: {
    user: User;
    isNewUser: boolean;
    wasAlreadyAuthenticated: boolean;
    loginMethod: LoginMethod | null;
    loginAccount: LinkedAccountWithMetadata | null;
}) => void) | undefined

Parameters

user
User
The user object corresponding to the authenticated user.
isNewUser
boolean
Whether the user is a new user or an existing user.
wasAlreadyAuthenticated
boolean
Whether the user entered the application already authenticated.
loginMethod
LoginMethod | null
The method used by the user to login.
loginAccount
LinkedAccountWithMetadata | null
The account corresponding to the loginMethod used.

onError

onError: (error: Error) => void

Parameters

error
Error
The error that occurred during the login flow.

Resources