Authentication

Customers authenticate with email + one-time passcode (OTP) — no passwords needed. OAuth providers (Google, Facebook) are also supported.


OTP Login Flow

Two-step flow: enter email, then enter the 6-digit code.

<AuthOtpFlowProvider>
  <AuthEmailStep>
    <AuthOtpRequestProvider>
      <AuthEmailField>
        <TextFieldInput type="email" placeholder="Enter your email" />
      </AuthEmailField>
      <MutationError />
      <MutationButton>Send Code</MutationButton>
    </AuthOtpRequestProvider>
  </AuthEmailStep>

  <AuthVerifyStep>
    <AuthOtpProvider>
      <AuthOtpField>
        <OTPFieldInput />
        <OTPFieldGroup>
          <OTPFieldSlot index={0} />
          <OTPFieldSlot index={1} />
          <OTPFieldSlot index={2} />
        </OTPFieldGroup>
        <OTPFieldSeparator />
        <OTPFieldGroup>
          <OTPFieldSlot index={3} />
          <OTPFieldSlot index={4} />
          <OTPFieldSlot index={5} />
        </OTPFieldGroup>
      </AuthOtpField>
      <MutationError />
      <MutationButton>Verify</MutationButton>
    </AuthOtpProvider>
  </AuthVerifyStep>
</AuthOtpFlowProvider>

AuthEmailStep shows when the user hasn't entered their email. AuthVerifyStep shows after the code is sent. Switching between steps is automatic.


Auto-Verify

Set autoVerify on AuthOtpField to skip the verify button — the mutation fires automatically when all slots are filled:

<AuthOtpProvider>
  <AuthOtpField autoVerify>
    <OTPFieldInput />
    <OTPFieldGroup>
      <OTPFieldSlot index={0} />
      <OTPFieldSlot index={1} />
      <OTPFieldSlot index={2} />
    </OTPFieldGroup>
    <OTPFieldSeparator />
    <OTPFieldGroup>
      <OTPFieldSlot index={3} />
      <OTPFieldSlot index={4} />
      <OTPFieldSlot index={5} />
    </OTPFieldGroup>
  </AuthOtpField>
</AuthOtpProvider>

OAuth Login

Provider buttons redirect to Google or Facebook, then back to your storefront:

<AuthGoogleButton />
<AuthFacebookButton />

Configure OAuth providers in Admin → Settings → Integrations. Handle the OAuth callback on your redirect page:

<OAuthCallbackHandler fallbackRedirect="/">
  <p>Completing sign-in...</p>
</OAuthCallbackHandler>

Guest Checkout

Authentication is optional. Users can browse and add to cart without logging in. The OTP flow triggers at checkout if the user isn't authenticated — no login wall before purchase.


Auth State

useAuth() is available anywhere in the app. AuthProvider is auto-mounted in the root layout:

const { user, isAuthenticated, isLoading, logout } = useAuth()