nextjs-supabase-auth

Expert integration of Supabase Auth with Next.js App Router

By sickn33 · 6,420 installs

npx skills add sickn33/agentic-awesome-skills --skill nextjs-supabase-auth

Source repository · Upstream listing

Next.js + Supabase Auth Expert integration of Supabase Auth with Next.js App Router Capabilities nextjs auth supabase auth nextjs auth middleware auth callback Prerequisites Required skills: nextjs app router, supabase backend Patterns Supabase Client Setup Create properly configured Supabase clients for different contexts When to use : Setting up auth in a Next.js project // lib/supabase/client.ts (Browser client) 'use client' import { createBrowserClient } from '@supabase/ssr' export function createClient() { return createBrowserClient( process.env.NEXT PUBLIC SUPABASE URL!, process.env.NEXT PUBLIC SUPABASE ANON KEY! ) } // lib/supabase/server.ts (Server client) import { createServerClient } from '@supabase/ssr' import { cookies } from 'next/headers' export async function createClient() { const cookieStore = await cookies() return createServerClient( process.env.NEXT PUBLIC SUPABASE URL!, process.env.NEXT PUBLIC SUPABASE ANON KEY!, { cookies: { getAll() { return cookieStore.getAll() }, setAll(cookiesToSet) { cookiesToSet.forEach(({ name, value, options }) = { cookieStore.set(name, value, options) }) }, }, } ) } Auth Middleware Protect routes and refresh sessions in middleware When to use : You need route protection or session refresh // middleware.ts import { createServerClient } from '@supabase/ssr' import { NextResponse, type NextRequest } from 'next/server' export async function middleware(request: NextRequest) { let response = NextResponse.next({ request }) const supabase = createServerClient( process.env.NEXT PUBLIC SUPABASE URL!, process.env.NEXT PUBLIC SUPABASE ANON KEY!, { cookies: { getAll() { return request.cookies.getAll() }, setAll(cookiesToSet) { cookiesToSet.forEach(({ name, value, options }) = { response.cookies.set(name, value, options) }) }, }, } ) // Refresh session if expired const { data: { user } } = await supabase.auth.getUser() // Protect dashboard routes if (request.nextUrl.pathname.startsWith('/dashboard') && !user) { return NextResponse.redirect(new URL('/login', request.url)) } return response } export const config = { matcher: ['/((?! next/static next/image favicon.ico). )'], } Auth Callback Route Handle OAuth callback and exchange code for session When to use : Using OAuth providers (Google, GitHub, etc.) // app/auth/callback/route.ts import { createClient } from '@/lib/supabase/server' import { NextResponse } from 'next/server' export async function GET(request: Request) { const { searchParams, origin } = new URL(request.url) const code = searchParams.get('code') const next = searchParams.get('next') ?? '/' if (code) { const supabase = await createClient() const { error } = await supabase.auth.exchangeCodeForSession(code) if (!error) { return NextResponse.redirect( ${origin}${next} ) } } return NextResponse.redirect( ${origin}/auth/error ) } Server Action Auth Handle auth operations in Server Actions When to use : Login, logout, or signup from Server Components // app/actions/auth.ts 'use server' import { createClient } from '@/lib/supabase/server' import { redirect } from 'next/navigation' import { revalidatePath } from 'next/cache' export async function signIn(formData: FormData) { const supabase = await createClient() const { error } = await supabase.auth.signInWithPassword({ email: formData.get('email') as string, password: formData.get('password') as string, }) if (error) { return { error: error.message } } revalidatePath('/', 'layout') redirect('/dashboard') } export async function signOut() { const supabase = await createClient() await supabase.auth.signOut() revalidatePath('/', 'layout') redirect('/') } Get User in Server Component Access the authenticated user in Server Components When to use : Rendering user specific content server side // app/dashboard/page.tsx import { createClient } from '@/lib/supabase/server' import { redirect } from 'next/navigation' export default async function DashboardPage() { const supabase = await createClient() const { data: { user } } = await supabase.auth.getUser() if (!user) { redirect('/login') } return ( <div <h1 Welcome, {user.email}</h1 </div ) } Validation Checks Using getSession() for Auth Checks Severity: ERROR Message: getSession() doesn't verify the JWT. Use getUser() for secure auth checks. Fix action: Replace getSession() with getUser() for security critical checks OAuth Without Callback Route Severity: ERROR Message: Using OAuth but missing callback route at app/auth/callback/route.ts Fix action: Create app/auth/callback/route.ts to handle OAuth redirects Browser Client in Server Context Severity: ERROR Message: Browser client used in server context. Use createServerClient instead. Fix action: Import and use createServerClient from @supabase/ssr Protected Routes Without Middleware Severity: WARNING Message: No middleware.ts found. Consider adding middleware for route protection. Fix action: Create middleware.ts to protect routes and refresh sessions Hardcoded Auth Redirect URL Severity: WARNING Message: Hardcoded localhost redirect. Use origin for environment flexibility. Fix action: Use window.location.origin or process.env.NEXT PUBLIC SITE URL Auth Call Without Error Handling Severity: WARNING Message: Auth operation without error handling. Always check for errors. Fix action: Destructure { data, error } and handle error case Auth Action Without Revalidation Severity: WARNING Message: Auth action without revalidatePath. Cache may show stale auth state. Fix action: Add revalidatePath('/', 'layout') after auth operations Client Only Route Protection Severity: WARNING Message: Client side route protection shows flash of content. Use middleware. Fix action: Move protection to middleware.ts for better UX Collaboration Delegation Triggers database rls queries tables supabase backend (Auth needs database layer) route page component layout nextjs app router (Auth needs Next.js patterns) deploy production vercel vercel deployment (Auth needs deployment config) ui form button design frontend (Auth needs UI components) Full Auth Stack Skills: nextjs supabase auth, supabase backend, nextjs app router, vercel deployment Workflow: Protected SaaS Skills: nextjs supabase auth, stripe integration, supabase backend Workflow: Related Skills Works well with: nextjs app router , supabase backend When to Use User mentions or implies: supabase auth next User mentions or implies: authentication next.js User mentions or implies: login supabase User mentions or implies: auth middleware User mentions or implies: protected route User mentions or implies: auth callback User mentions or implies: session management Limitations Use this skill only when the task clearly matches the scope described above. Do not treat the output as a substitute for environment specific validation, testing, or expert review. Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.