
Nextjs Supabase Auth
Wire Supabase Auth correctly across browser, server, middleware, and OAuth callbacks in a Next.js App Router SaaS.
Install
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill nextjs-supabase-authWhat is this skill?
- Separate browser and server Supabase clients using @supabase/ssr cookie patterns
- Auth middleware and callback-route patterns for App Router protection
- Documented prerequisite chain: nextjs-app-router and supabase-backend skills first
- Environment-driven URL and anon key configuration for client factories
- Capability tags: nextjs-auth, supabase-auth-nextjs, auth-middleware, auth-callback
Adoption & trust: 5.2k installs on skills.sh; 40.1k GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Entra App Registrationmicrosoft/azure-skills
Azure Aigatewaymicrosoft/azure-skills
Lark Openapi Explorerlarksuite/cli
Supabasesupabase/agent-skills
Firebase Auth Basicsfirebase/agent-skills
Firebase Data Connectfirebase/agent-skills
Journey fit
Primary fit
Build → Backend is the canonical shelf for authentication plumbing that secures your app core, even though patterns touch middleware at the edge. Backend subphase covers session handling, server clients, and auth integration—not marketing pages.
Common Questions / FAQ
Is Nextjs Supabase Auth safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Nextjs Supabase Auth
# 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 } } revalidatePat