nextjs-supabase-auth

Supabase Auth integration for Next.js App Router with middleware-based session management. Handles server/client authentication boundaries using @supabase/ssr, protecting routes via middleware and managing cookie-based sessions Provides patterns for OAuth callbacks, Server Actions for auth operations, and proper token handling across Server and Client Components Includes anti-patterns to avoid: getSession in Server Components, unlistened client auth state, and manual token storage

INSTALLATION
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill nextjs-supabase-auth
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

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 (

Welcome, {user.email}

)

}

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.
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card