nextjs-supabase-auth — Claude Code skill: what it does, install
This skill wires Supabase Auth into the Next.js App Router with clients, middleware, OAuth callbacks, and Server Actions. Use it when you need protected routes and session handling.
npx skills add sickn33/agentic-awesome-skills --skill nextjs-supabase-auth -a claude-codeWhat nextjs-supabase-auth does
The skill covers Supabase Auth integration for the Next.js App Router. It sets up separate browser and server clients with @supabase/ssr, handles cookies, and uses getUser() when authenticated data is read in Server Components.
It includes patterns for middleware.ts, the OAuth callback at app/auth/callback/route.ts, and Server Actions for sign-in and sign-out. Middleware refreshes sessions and protects /dashboard; the callback exchanges an OAuth code for a session.
The setup expects nextjs-app-router and supabase-backend skills, plus NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, and APP_ORIGIN. The skill is marked critical, so review cookie handling and redirect targets before adding it to a project.
What it helps with
- set up browser and server Supabase clients
- protect
/dashboardwith middleware - exchange an OAuth code for a session
- handle sign-in and sign-out in Server Actions
- check auth code for common implementation errors
Example prompts for the agent
- Set up Supabase Auth in my Next.js App Router project and create `lib/supabase/client.ts` and `lib/supabase/server.ts`.
- Add middleware protection for `/dashboard` and refresh the session with `getUser()`.
- Review `app/auth/callback/route.ts` and fix insecure authentication checks.
How to install nextjs-supabase-auth
1Skills CLI (Vercel)
npx skills add sickn33/agentic-awesome-skills --skill nextjs-supabase-auth -a claude-code2Manually: put the files in place
~/.claude/skills/nextjs-supabase-auth/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/nextjs-supabase-auth/
1Skills CLI (Vercel)
npx skills add sickn33/agentic-awesome-skills --skill nextjs-supabase-auth -a codex2Manually: put the files in place
.agents/skills/nextjs-supabase-auth/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add sickn33/agentic-awesome-skills --skill nextjs-supabase-auth -a cursor2Manually: put the files in place
.cursor/skills/nextjs-supabase-auth/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install sickn33/agentic-awesome-skills nextjs-supabase-auth2Manually: put the files in place
.github/skills/nextjs-supabase-auth/SKILL.md1Skills CLI (Vercel)
npx skills add sickn33/agentic-awesome-skills --skill nextjs-supabase-auth -a gemini-cli2Platform CLI
gemini skills install https://github.com/sickn33/agentic-awesome-skills --path skills/nextjs-supabase-authManually: put the files in place
.devin/skills/nextjs-supabase-auth/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add sickn33/agentic-awesome-skills --skill nextjs-supabase-auth -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
From the same set80
The whole set →Similar
Questions about nextjs-supabase-auth
How do I install nextjs-supabase-auth in Claude Code?
Run npx skills add sickn33/agentic-awesome-skills --skill nextjs-supabase-auth -a claude-code, run the same command a second time, then check ~/.claude/skills/nextjs-supabase-auth/SKILL.md.
What does nextjs-supabase-auth do?
It guides Supabase Auth setup for the Next.js App Router, including clients, middleware, an OAuth callback, and Server Actions.
What does nextjs-supabase-auth require?
The setup expects the nextjs-app-router and supabase-backend skills, along with NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, and APP_ORIGIN.
Source text
SKILL.md · MIT
---
name: nextjs-supabase-auth
description: Expert integration of Supabase Auth with Next.js App Router
risk: critical
source: vibeship-spawner-skills (Apache 2.0)
date_added: 2026-02-27
---
# 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) {
// This helper is for a Route Handler/Server Action with writable cookies.
// In a Server Component use the official read-only client pattern and
// refresh sessions in middleware/proxy; do not attempt cookie writes here.
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 }) => request.cookies.set(name, value))
response = NextResponse.next({ request })
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 candidate = searchParams.get('next') ?? '/'
const next = candidate.startsWith('/') && !candidate.startsWith('//') && !candidate.includes('\\') ? candidate : '/'
if (code) {
const supabase = await createClient()
const { error } = await supabase.auth.exchangeCodeForSession(code)
if (!error) {
return NextResponse.redirect(new URL(next, process.env.APP_ORIGIN!)) // validated trusted deployment origin
}
}
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:
```
1. Database setup (supabase-backend)
2. Auth implementation (nextjs-supabase-auth)
3. Route protection (nextjs-app-router)
4. Deployment config (vercel-deployment)
```
### Protected SaaS
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)
```
## 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.
These are separate-file fragments, not a complete auth deployment. Configure and validate the trusted `APP_ORIGIN`, callback allowlist and exact Next.js/Supabase versions first. Server Components cannot write cookies; use the current official context-specific helper rather than suppressing arbitrary refresh failures. Preserve refreshed cookies on returned redirects. Middleware is not the sole authorization layer: validate sessions/claims and tenant/resource permissions on every server data/action path and enforce RLS. Never expose a service-role key to browsers. See [Supabase server-side client guidance](https://supabase.com/docs/guides/auth/server-side/creating-a-client?queryGroups=framework&framework=nextjs).
© sickn33 · MIT · sickn33/agentic-awesome-skills