StartupKitstartupkit
AuthUsage

useAuth

Complete API reference for the useAuth hook

The useAuth hook provides authentication state and methods in client components.

Import

import {  } from "@startupkit/auth"

Basic Usage

"use client"

import {  } from "@startupkit/auth"

export function () {
  const {
    ,
    ,
    ,
    ,
    ,
    ,
    
  } = ()
}

Return Values

isAuthenticated

"use client"

import {  } from "@startupkit/auth"

function () {
  const {  } = ()
}

Whether the user is currently signed in.

if (isAuthenticated) {
  return <Dashboard />
}
return <SignInPrompt />

isLoading

"use client"

import {  } from "@startupkit/auth"

function () {
  const {  } = ()
}

Whether the auth state is being determined. Always check this before isAuthenticated to avoid flashing content.

if (isLoading) {
  return <Skeleton />
}
if (!isAuthenticated) {
  return <SignIn />
}

user

"use client"

import {  } from "@startupkit/auth"

function () {
  const {  } = ()
}

The current user object. null if not authenticated, undefined while loading.

interface User {
  id: string
  email: string
  name: string
  firstName?: string
  lastName?: string
  image?: string
  emailVerified: boolean
  createdAt: Date
  updatedAt: Date
}

Usage:

if (user) {
  return <span>Welcome, {user.name}</span>
}

Methods

logout()

"use client"

import {  } from "@startupkit/auth"

function () {
  const {  } = ()
}

Signs out the current user and redirects to home.

<button onClick={logout}>Sign Out</button>

Or with custom handling:

const handleLogout = async () => {
  await logout()
  // Additional cleanup if needed
}

sendAuthCode()

"use client"

import {  } from "@startupkit/auth"

function () {
  const {  } = ()
}

Sends a one-time password to the specified email.

const [email, setEmail] = useState("")

const handleSend = async () => {
  try {
    await sendAuthCode(email)
    // Show code input
  } catch (error) {
    // Handle error (invalid email, rate limited, etc.)
  }
}

verifyAuthCode()

"use client"

import {  } from "@startupkit/auth"

function () {
  const {  } = ()
}

Verifies the OTP code and creates a session.

const handleVerify = async () => {
  try {
    await verifyAuthCode(email, code)
    // User is now signed in, redirected automatically
  } catch (error) {
    // Invalid or expired code
  }
}

googleAuth()

"use client"

import {  } from "@startupkit/auth"

function () {
  const {  } = ()
}

Initiates Google OAuth sign-in flow.

<button onClick={googleAuth}>
  Sign in with Google
</button>

AuthProvider

The useAuth hook requires the AuthProvider wrapper:

app/providers.tsx
"use client"

import { AuthProvider } from "@startupkit/auth"
import { authClient } from "@/lib/auth-client"

interface ProvidersProps {
  children: React.ReactNode
  user?: User
}

export function Providers({ children, user }: ProvidersProps) {
  return (
    <AuthProvider authClient={authClient} user={user}>
      {children}
    </AuthProvider>
  )
}

AuthProvider Props

PropTypeDescription
childrenReactNodeChild components
authClientAuthClientBetter Auth client instance
userUserInitial user (from server)
onIdentify(user: User) => voidCalled when user signs in
onReset() => voidCalled on logout

Integration with Analytics

<AuthProvider
  authClient={authClient}
  user={user}
  onIdentify={(user) => {
    // Identify user in analytics
    analytics.identify(user.id, {
      email: user.email,
      name: user.name
    })
  }}
  onReset={() => {
    // Reset analytics identity
    analytics.reset()
  }}
>
  {children}
</AuthProvider>

TypeScript

Custom User Type

Extend the user type with additional fields:

interface CustomUser {
  id: string
  email: string
  name: string
  plan: "free" | "pro" | "enterprise"
  teamId: string
}

// In your component
const { user } = useAuth() as { user: CustomUser | null }

Type Definitions

interface AuthContextType {
  isAuthenticated: boolean
  isLoading: boolean
  user: User | null | undefined
  logout: () => Promise<void>
  sendAuthCode: (email: string) => Promise<void>
  verifyAuthCode: (email: string, code: string) => Promise<void>
  googleAuth: () => Promise<void>
}

Common Patterns

Protected Component

"use client"

import { useAuth } from "@startupkit/auth"

export function ProtectedFeature() {
  const { isAuthenticated, isLoading } = useAuth()

  if (isLoading) return <Skeleton />
  if (!isAuthenticated) return null

  return <Feature />
}

Auth-Dependent UI

"use client"

import { useAuth } from "@startupkit/auth"

export function Header() {
  const { isAuthenticated, user, logout } = useAuth()

  return (
    <header>
      <Logo />
      <nav>
        {isAuthenticated ? (
          <>
            <span>{user?.name}</span>
            <button onClick={logout}>Sign Out</button>
          </>
        ) : (
          <a href="/sign-in">Sign In</a>
        )}
      </nav>
    </header>
  )
}

Redirect After Auth

"use client"

import { useAuth } from "@startupkit/auth"
import { useRouter } from "next/navigation"
import { useEffect } from "react"

export function AuthRedirect({ redirectTo = "/dashboard" }) {
  const { isAuthenticated, isLoading } = useAuth()
  const router = useRouter()

  useEffect(() => {
    if (!isLoading && isAuthenticated) {
      router.push(redirectTo)
    }
  }, [isAuthenticated, isLoading, redirectTo, router])

  return null
}

Error Handling

All auth methods can throw errors. Always check the error type before accessing properties:

try {
  await sendAuthCode(email)
} catch (error) {
  if (error instanceof Error) {
    const message = error.message
    if (message.includes("rate limit")) {
      setError("Too many attempts. Please wait.")
    } else if (message.includes("invalid email")) {
      setError("Please enter a valid email.")
    } else {
      setError("Something went wrong. Please try again.")
    }
  } else {
    setError("An unexpected error occurred.")
  }
}

Next Steps

On this page