nextjs-supabase-auth
sickn33/agentic-awesome-skills
Expert integration of Supabase Auth with Next.js App Router
What is nextjs-supabase-auth?
This skill provides production-ready patterns for implementing Supabase authentication in Next.js applications using the App Router. Use it when building login systems, protecting routes, handling OAuth callbacks, and managing user sessions server-side.
- Set up browser and server Supabase clients with proper SSR configuration
- Implement auth middleware for route protection and automatic session refresh
- Handle OAuth provider callbacks and exchange authorization codes for sessions
- Build server actions for sign-in, sign-up, and sign-out operations
- Access authenticated user data in Server Components with security checks
- Validate auth patterns and catch common security mistakes
How to install nextjs-supabase-auth
npx skills add https://github.com/sickn33/agentic-awesome-skills --skill nextjs-supabase-auth- nextjs-app-router skill installed
- supabase-backend skill installed
- Supabase project with auth configured
- Environment variables: NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY
How to use nextjs-supabase-auth
- 1.Create Supabase client files (lib/supabase/client.ts and lib/supabase/server.ts) using the provided SSR patterns
- 2.Add middleware.ts to your project root to protect routes and refresh sessions automatically
- 3.Create app/auth/callback/route.ts to handle OAuth provider redirects
- 4.Build server actions in app/actions/auth.ts for sign-in, sign-up, and sign-out
- 5.Fetch the authenticated user in Server Components using getUser() for security-critical checks
- 6.Run validation checks to catch common mistakes like using getSession() or missing error handling
Use cases
- Building a SaaS application with user authentication and protected dashboards
- Implementing social login (Google, GitHub) with OAuth callback handling
- Creating a multi-tenant app where routes are protected based on user session
- Adding session refresh middleware to keep users logged in across page navigations
- Syncing Supabase auth with Stripe for subscription-gated features
- Full-stack developers building Next.js applications
- Teams implementing authentication from scratch in Supabase projects
- Developers migrating from Pages Router to App Router with auth
- Engineers building SaaS products requiring secure user management
nextjs-supabase-auth FAQ
Always use getUser() for security-critical checks because it verifies the JWT. getSession() does not verify the token and should only be used for non-critical operations.
Browser clients run in the browser and handle client-side auth operations. Server clients run on the server and can securely access user data and perform privileged operations. Using the correct client for each context prevents security issues.
OAuth flows will fail because the provider redirects to /auth/callback/route.ts to exchange the authorization code for a session. Without this route, users cannot complete social login.
Middleware runs before the page renders, so it can redirect unauthenticated users before any content is sent to the browser. This prevents the flash of protected content that occurs with client-side protection.
Yes. Auth operations change the user session, so you must call revalidatePath('/', 'layout') to clear Next.js cache and ensure the UI reflects the new auth state.
Full instructions (SKILL.md)
Source of truth, from sickn33/agentic-awesome-skills.
name: nextjs-supabase-auth description: Expert integration of Supabase Auth with Next.js App Router risk: none 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) { 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:
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.
Related skills
More from sickn33/agentic-awesome-skills and the wider catalog.

nodejs-best-practices
Node.js development principles and decision-making for architecture, frameworks, async patterns, and security.

office-productivity
Automate document creation, spreadsheets, and presentations across LibreOffice and Microsoft Office formats.

playwright-skill
Write and execute custom Playwright browser automation scripts for testing and web scraping.

powershell-windows
Master PowerShell Windows syntax, operators, error handling, and critical pitfalls.

pptx-official
Create, edit, and analyze PowerPoint presentations by working with their XML structure and conversion tools.

prisma-expert
Expert Prisma ORM guidance for schema design, migrations, query optimization, and multi-database operations.