Page 2: Implementing User Authentication in Next.js (App Router)

2. Implementing User Authentication in Next.js (App Router)

Supabase Auth provides a robust and easy-to-implement authentication system. This section covers setting up email/password authentication and managing user sessions within your Next.js (App Router) application.

2.1. Server Component to get User Session

In the App Router, you'll often need to access the user session in Server Components. This example shows how to fetch the session.

// app/page.tsx (or any server component)
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'

export default async function Page() {
  const supabase = createClient()

  const {
    data: { user },
  } = await supabase.auth.getUser()

  if (!user) {
    redirect('/login') // Redirect to login if no user
  }

  return (
    <div>
      <h1>Welcome, {user.email}</h1>
      {/* Your protected content */}
    </div>
  )
}

2.2. Login and Signup Client Component

Create a client component for user authentication (e.g., app/login/page.tsx). You'll typically use a form for this.

'use client'

import { createClient } from '@/lib/supabase/client'
import { useRouter } from 'next/navigation'
import { useState } from 'react'

export default function LoginPage() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const router = useRouter()
  const supabase = createClient()

  const handleSignIn = async (e: React.FormEvent) => {
    e.preventDefault()
    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    })

    if (error) {
      alert(error.message)
    } else {
      router.push('/') // Redirect to home page on successful login
    }
  }

  const handleSignUp = async (e: React.FormEvent) => {
    e.preventDefault()
    const { error } = await supabase.auth.signUp({
      email,
      password,
    })

    if (error) {
      alert(error.message)
    } else {
      alert('Check your email for a verification link!')
    }
  }

  return (
    <form>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password"
      />
      <button onClick={handleSignIn}>Sign In</button>
      <button onClick={handleSignUp}>Sign Up</button>
    </form>
  )
}

Important: Remember to set up a /login route in your App Router to host this component.

2.3. User Session Management

The @supabase/ssr package helps manage user sessions automatically using cookies. When a user logs in, Supabase sets secure, HTTP-only cookies. Your server components can then read these cookies using createServerClient to determine the user's authentication status without manual token management.

You can also listen for auth state changes in client components:

supabase.auth.onAuthStateChange((event, session) => {
  if (event === 'SIGNED_IN') {
    // User signed in
  } else if (event === 'SIGNED_OUT') {
    // User signed out
  }
})

This setup provides a complete authentication flow for your Next.js application.