Supabase Auth

Complete authentication system with Supabase including sign in/up, password reset, OTP verification, magic links, and OAuth providers (Google, GitHub). Features passwordless options, comprehensive error handling, and responsive UI.

Preview

Welcome Back
Sign in to your account
Or
No account? Sign up

Overview

A complete authentication system with Supabase including sign in/up, password reset, OTP verification, magic links, and OAuth providers (Google, GitHub). Features passwordless options, comprehensive error handling, and responsive UI.

This comprehensive auth system provides:

  • Multiple Sign-in Methods: Magic links, OTP codes, password-based auth, and OAuth
  • Complete User Flows: Sign up, sign in, password reset, email verification
  • Modern UI: Built with shadcn/ui components for a polished experience
  • Error Handling: Comprehensive error states with user-friendly messages
  • Security Best Practices: Rate limiting, secure redirects, and proper session management
  • Responsive Design: Mobile-first design that works on all devices

Installation

Install the supabase auth system
npx shadcn@latest add https://jt-components.vercel.app/r/supabase-auth.json
pnpm dlx shadcn@latest add https://jt-components.vercel.app/r/supabase-auth.json
yarn dlx shadcn@latest add https://jt-components.vercel.app/r/supabase-auth.json
bunx --bun shadcn@latest add https://jt-components.vercel.app/r/supabase-auth.json

Environment Variables

Make sure to add the following environment variables to your .env.local file:

NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
NEXT_PUBLIC_SITE_URL=http://localhost:3000

Supabase Setup

1. Enable Authentication Providers

In your Supabase dashboard, go to Authentication > Providers and enable:

  • Email (for magic links and OTP)
  • Google (optional)
  • GitHub (optional)

2. Configure OAuth Providers

For Google OAuth:

Site URL: http://localhost:3000
Redirect URLs: http://localhost:3000/auth/callback

For GitHub OAuth:

Site URL: http://localhost:3000
Redirect URLs: http://localhost:3000/auth/callback

3. Email Templates

Configure your email templates in Authentication > Email Templates for:

  • Magic Link
  • Confirm signup
  • Reset password

Usage

Basic Authentication Flow

The auth system provides multiple sign-in options:

// Sign in with magic link
import { signInWithMagicLink } from '@/actions/auth'

export default function SignInForm() {
  return (
    <form action={signInWithMagicLink}>
      <input type="email" name="email" required />
      <button type="submit">Send Magic Link</button>
    </form>
  )
}

Password Authentication

// Sign in with password
import { signInWithPassword } from '@/actions/auth'

export default function PasswordSignIn() {
  return (
    <form action={signInWithPassword}>
      <input type="email" name="email" required />
      <input type="password" name="password" required />
      <button type="submit">Sign In</button>
    </form>
  )
}

OTP Verification

// Verify OTP code
import { signInWithOTP } from '@/actions/auth'

export default function OTPForm() {
  return (
    <form action={signInWithOTP}>
      <input type="email" name="email" required />
      <button type="submit">Send OTP</button>
    </form>
  )
}

OAuth Providers

// Social authentication
import { signInWithGoogle, signInWithGithub } from '@/actions/auth'

export default function SocialAuth() {
  return (
    <div>
      <button onClick={signInWithGoogle}>Sign in with Google</button>
      <button onClick={signInWithGithub}>Sign in with GitHub</button>
    </div>
  )
}

Sign Out

// Sign out user
import { signOut } from '@/actions/auth'

export default function SignOutButton() {
  return (
    <form action={signOut}>
      <button type="submit">Sign Out</button>
    </form>
  )
}

Authentication Pages

The system includes complete authentication pages:

Sign In Page (/signin)

  • Magic link and OTP options (recommended)
  • Link to password-based sign in
  • OAuth provider buttons
  • Error handling and rate limiting

Sign Up Page (/signup)

  • Passwordless registration options
  • Link to password-based sign up
  • OAuth provider buttons
  • Account verification flow

Password Pages

  • /signin/password - Password-based sign in
  • /signup/password - Password-based sign up
  • /signin/password/reset - Password reset request

Verification Pages

  • /verify-email - Email verification confirmation
  • /verify-otp - OTP code verification
  • /update-password - Password update form

Middleware Integration

Add the auth middleware to your middleware.ts:

import { updateSession } from '@/lib/supabase/middleware'

export async function middleware(request) {
  return await updateSession(request)
}

export const config = {
  matcher: [
    '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
  ],
}

Source Code

Loading component...

Server Actions

The auth system includes comprehensive server actions:

Authentication Actions

  • signInWithMagicLink() - Send magic link email
  • signInWithOTP() - Send OTP code
  • signInWithPassword() - Password-based sign in
  • signUpWithPassword() - Password-based sign up
  • signInWithGoogle() - Google OAuth
  • signInWithGithub() - GitHub OAuth
  • signOut() - Sign out user

Password Management

  • requestPasswordReset() - Request password reset
  • updateUserPassword() - Update user password

Customization

Styling

All components use shadcn/ui classes and can be customized via your CSS variables:

:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 222.2 47.4% 11.2%;
  /* ... */
}

Branding

Update the auth layout in app/(auth)/layout.tsx:

export default function AuthLayout({ children }) {
  return (
    <main className="flex min-h-screen w-full flex-col items-center justify-center p-4">
      <YourLogo className="w-10 h-10" />
      <h1 className="text-2xl font-bold">Your App Name</h1>
      <p className="text-sm text-muted-foreground">
        Your app description
      </p>
      {children}
    </main>
  )
}

Redirects

Customize redirect URLs in the auth actions:

// Custom redirect after sign in
const { error } = await supabase.auth.signInWithPassword({
  email: result.data.email,
  password: result.data.password,
})

if (!error) {
  redirect('/dashboard') // Custom redirect
}

Examples

Protected Route

// app/dashboard/page.tsx
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'

export default async function Dashboard() {
  const supabase = await createClient()
  
  const { data: { user } } = await supabase.auth.getUser()
  
  if (!user) {
    redirect('/signin')
  }
  
  return (
    <div>
      <h1>Welcome, {user.email}</h1>
    </div>
  )
}

User Profile

// components/user-profile.tsx
import { createClient } from '@/lib/supabase/client'
import { useEffect, useState } from 'react'

export default function UserProfile() {
  const [user, setUser] = useState(null)
  const supabase = createClient()
  
  useEffect(() => {
    const getUser = async () => {
      const { data: { user } } = await supabase.auth.getUser()
      setUser(user)
    }
    
    getUser()
  }, [supabase])
  
  return user ? (
    <div>
      <p>Signed in as: {user.email}</p>
    </div>
  ) : (
    <div>Not signed in</div>
  )
}

Auth State Listener

// hooks/use-auth.ts
import { createClient } from '@/lib/supabase/client'
import { useEffect, useState } from 'react'

export function useAuth() {
  const [user, setUser] = useState(null)
  const supabase = createClient()
  
  useEffect(() => {
    const { data: { subscription } } = supabase.auth.onAuthStateChange(
      (event, session) => {
        setUser(session?.user ?? null)
      }
    )
    
    return () => subscription.unsubscribe()
  }, [supabase])
  
  return { user }
}

FAQ

Some common issues and solutions.

Last updated on