From antigravity-awesome-skills
Sets up Supabase Auth with Next.js App Router: browser/server clients, auth middleware for route protection and session refresh, and OAuth callback handling.
How this skill is triggered — by the user, by Claude, or both
Slash command
/antigravity-awesome-skills:nextjs-supabase-authThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Expert integration of Supabase Auth with Next.js App Router
Expert integration of Supabase Auth with Next.js App Router
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) }) }, }, } ) }
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).*)'], }
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)
}
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('/') }
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 (
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
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
Severity: ERROR
Message: Browser client used in server context. Use createServerClient instead.
Fix action: Import and use createServerClient from @supabase/ssr
Severity: WARNING
Message: No middleware.ts found. Consider adding middleware for route protection.
Fix action: Create middleware.ts to protect routes and refresh sessions
Severity: WARNING
Message: Hardcoded localhost redirect. Use origin for environment flexibility.
Fix action: Use window.location.origin or process.env.NEXT_PUBLIC_SITE_URL
Severity: WARNING
Message: Auth operation without error handling. Always check for errors.
Fix action: Destructure { data, error } and handle error case
Severity: WARNING
Message: Auth action without revalidatePath. Cache may show stale auth state.
Fix action: Add revalidatePath('/', 'layout') after auth operations
Severity: WARNING
Message: Client-side route protection shows flash of content. Use middleware.
Fix action: Move protection to middleware.ts for better UX
Skills: nextjs-supabase-auth, supabase-backend, nextjs-app-router, vercel-deployment
Workflow:
1. Database setup (supabase-backend)
2. Auth implementation (nextjs-supabase-auth)
3. Route protection (nextjs-app-router)
4. Deployment config (vercel-deployment)
Skills: nextjs-supabase-auth, stripe-integration, supabase-backend
Workflow:
1. User authentication (nextjs-supabase-auth)
2. Customer sync (stripe-integration)
3. Subscription gating (supabase-backend)
Works well with: nextjs-app-router, supabase-backend
npx claudepluginhub sickn33/antigravity-awesome-skills --plugin antigravity-bundle-aas-mobile-app-builderSets up Supabase Auth in Next.js App Router with browser/server clients, middleware for route protection and session refresh, and OAuth callback routes.
Implements Auth.js 5 authentication patterns for Next.js 15+ App Router including protected routes, Server Components sessions, OAuth providers, RBAC, and sign-in/out flows.
Implements complete Next.js authentication with Auth.js: OAuth providers (GitHub/Google), credentials login, Prisma adapter, session management (JWT/DB), middleware-protected routes, RBAC, and login forms.