Supabase Auth is a fully managed authentication service built on top of GoTrue. It handles user storage, session management, and provider integrations — with pre-built UI components and tight Next.js integration. This guide covers setup for the three most common patterns: email magic links, social login, and JWT session handling.
Installation
npm install @supabase/supabase-js @supabase/ssr// lib/supabase/server.ts — server-side client (App Router)
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';
export function createClient() {
const cookieStore = cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll: () => cookieStore.getAll(),
setAll: (cookies) => cookies.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
),
},
}
);
}Recipe 1: Magic Link Email Auth
// app/api/auth/magic-link/route.ts
import { createClient } from '@/lib/supabase/server';
export async function POST(req: Request) {
const { email } = await req.json();
const supabase = createClient();
const { error } = await supabase.auth.signInWithOtp({
email,
options: {
emailRedirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/callback`,
},
});
if (error) return Response.json({ error: error.message }, { status: 400 });
return Response.json({ message: 'Check your email' });
}// app/auth/callback/route.ts — handles the magic link redirect
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');
if (code) {
const supabase = createClient();
await supabase.auth.exchangeCodeForSession(code);
}
return NextResponse.redirect(`${origin}/dashboard`);
}Recipe 2: Social Login (Google, GitHub)
// Client component — sign in button
'use client';
import { createBrowserClient } from '@supabase/ssr';
export function SignInWithGoogle() {
const supabase = createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
const handleSignIn = async () => {
await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: `${location.origin}/auth/callback`,
},
});
};
return <button onClick={handleSignIn}>Sign in with Google</button>;
}Enable each social provider in the Supabase Dashboard under Authentication > Providers. For Google, you need a Google Cloud OAuth 2.0 client ID and secret. For GitHub, create a GitHub OAuth App and paste the credentials into Supabase.Recipe 3: Protecting Routes with Middleware
// middleware.ts — redirect unauthenticated users
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: () => request.cookies.getAll(),
setAll: (c) => c.forEach(({name,value,options}) =>
response.cookies.set(name, value, options)) } }
);
const { data: { user } } = await supabase.auth.getUser();
if (!user && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return response;
}
export const config = {
matcher: ['/dashboard/:path*', '/api/protected/:path*'],
};Reading the Session Server-Side
// app/dashboard/page.tsx — server component
import { createClient } from '@/lib/supabase/server';
import { redirect } from 'next/navigation';
export default async function Dashboard() {
const supabase = createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) redirect('/login');
return <div>Hello {user.email}</div>;
}Always use supabase.auth.getUser() server-side — not getSession(). getUser() makes a network request to verify the token with Supabase's servers; getSession() only reads the local cookie and can be spoofed.| Metadata | Value |
|---|---|
| Title | Supabase Auth Setup: Social Login, Magic Links, and JWT Sessions in Next.js |
| Tool | Supabase |
| Primary SEO keyword | supabase auth next.js |
| Secondary keywords | supabase magic link, supabase social login, supabase middleware next.js, supabase session |
| Estimated read time | 9 minutes |
| Research date | 2026-04-14 |