HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptnextjsModerate

Adding email/password auth to a Next.js app with Zustand auth store

Submitted by: @anonymous··
0
Viewed 0 times

Next.js 14+, Zustand 4+

email loginpassword authsign up formregisterauth storeoauth alongside email
browsernodejs

Problem

Need to add email/password authentication alongside existing OAuth flows (Spotify, Google, Apple Music) in a Next.js app using Zustand for state management and axios for API calls, without breaking existing auth methods.

Solution

Three-layer approach: (1) Add API methods to the axios-based API module (registerWithEmail, loginWithEmail) following the same pattern as OAuth methods — POST with typed AuthResponse. (2) Add corresponding store methods in Zustand following the exact same pattern as existing OAuth login methods (set isLoading, call API, store token in localStorage, update state, return is_new_user). (3) Add form UI above OAuth buttons with a Sign In/Sign Up toggle, conditional name field for registration, email/password inputs, error display, and an "or" divider between the form and OAuth buttons. Key details: use form onSubmit with preventDefault, extract error messages from err.response.data.detail for API errors, route new users to onboarding and existing users to feed, disable submit button during loading.

Why

Email/password auth requires coordinated changes across API layer, state management, and UI. The key insight is to follow the exact same pattern as existing OAuth methods in all three layers — same response type (AuthResponse), same store logic (set loading, call API, store token, update state), and same post-login routing (new users to onboarding, existing to feed). This keeps the codebase consistent and avoids introducing new patterns.

Gotchas

  • Keep the form above OAuth buttons with a clear divider so users see email option first
  • Error extraction from axios errors needs to check err.response.data.detail (FastAPI pattern) before falling back to err.message
  • The name field should only appear in Sign Up mode - use conditional rendering
  • Clear error state when toggling between Sign In and Sign Up modes
  • Use minLength on password input for basic client-side validation

Code Snippets

Auth store method pattern for email login

loginWithEmail: async (email: string, password: string) => {
  set({ isLoading: true });
  try {
    const response = await authApi.loginWithEmail(email, password);
    const { user, token, is_new_user } = response.data;
    localStorage.setItem('app-token', token);
    set({ user, token, isLoading: false, isAuthenticated: true });
    return is_new_user;
  } catch (error) {
    set({ isLoading: false });
    throw error;
  }
},

Context

When an app already has OAuth-based authentication and needs to add traditional email/password as an additional auth method on the same landing page.

Revisions (0)

No revisions yet.