skills/nextjs-supabase-auth/SKILL.md
Expert integration of Supabase Auth with Next.js App Router
npx skillsauth add ranbot-ai/awesome-skills nextjs-supabase-authInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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 ( <div> <h1>Welcome, {user.email}</h1> </div> ) }
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
tools
Delegate coding tasks to the Grok Build CLI only when the user explicitly requests it, while the orchestrator retains review and landing responsibility.
development
--- name: graceful-shutdown description: Implement graceful shutdown for servers and workers: drain connections, finish in-flight work, release resources, and exit cleanly on SIGTERM/SIGINT. category: AI & Agents source: antigravity tags: [python, typescript, node, api, claude, ai, template, docker, kubernetes] url: https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/graceful-shutdown --- # Graceful Shutdown ## Overview A skill for implementing graceful shutdown in server
development
--- name: falsify description: The scientific thinking protocol for AI agents. Use when facing complex, ambiguous, or high-stakes questions where guessing is costly: hypothesis → attempt to break it → evidence → calibrated co category: Creative & Media source: antigravity tags: [markdown, claude, ai, agent, llm, template, design, security, rag, cro] url: https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/falsify --- # Falsify — The Scientific Thinking Protocol > Think like
tools
Configure approved delegation lanes across installed implementer CLIs, including optional model and effort choices, then write global or project config only after explicit user approval.