Supabase Auth i Next.js: Komplett guide for 2026
> TL;DR
Supabase Auth integreres i Next.js App Router via @supabase/ssr-pakken, med middleware for session-håndtering og Row Level Security (RLS) i PostgreSQL for sikker datatilgang.
Autentisering er noe av det viktigste — og mest frustrerende — å implementere i en webapplikasjon. Med Supabase og Next.js App Router har du en stack som gir deg full kontroll over brukerautentisering, session-håndtering og datatilgang — uten å skrive en eneste linje backend-kode for auth. Kombinert med Row Level Security, får du en komplett sikkerhetsmodell.
Vi bruker denne stacken i produksjon på Boligposten.com, og i denne guiden deler vi oppsettet steg for steg.
Hva trenger du for å komme i gang?
Før du starter, sørg for at du har:
| Krav | Detaljer |
|------|----------|
| Node.js | v18 eller nyere |
| Next.js | v14+ med App Router |
| Supabase-prosjekt | Opprett gratis på supabase.com |
| Miljøvariabler | NEXT_PUBLIC_SUPABASE_URL og NEXT_PUBLIC_SUPABASE_ANON_KEY |
Hvordan installerer du Supabase i Next.js?
Start med å installere de nødvendige pakkene:
npm install @supabase/supabase-js @supabase/ssr
@supabase/ssr er den offisielle pakken for server-side rendering med Supabase. Den håndterer cookies og sessions automatisk i App Router.
Opprett deretter hjelpefunksjoner for å lage Supabase-klienter:
// lib/supabase/server.ts
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)
)
},
},
}
)
}
// lib/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr'
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
}
Hvordan setter du opp middleware for sessions?
Middleware er kritisk for å holde sessions oppdatert. Uten dette vil brukere logges ut uventet:
// 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: { headers: request.headers },
})
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: { headers: request.headers },
})
cookiesToSet.forEach(({ name, value, options }) =>
response.cookies.set(name, value, options)
)
},
},
}
)
// Refresh session
await supabase.auth.getUser()
return response
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
}
Hvordan implementerer du login og registrering?
Med Supabase Auth kan du bruke flere strategier — e-post/passord, magic link, OAuth (Google, GitHub) og mer. Her er et eksempel med e-post:
// app/login/actions.ts
'use server'
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'
export async function login(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) {
redirect('/login?error=Feil e-post eller passord')
}
redirect('/dashboard')
}
export async function signup(formData: FormData) {
const supabase = await createClient()
const { error } = await supabase.auth.signUp({
email: formData.get('email') as string,
password: formData.get('password') as string,
})
if (error) {
redirect('/login?error=Kunne ikke opprette konto')
}
redirect('/login?message=Sjekk e-posten din for bekreftelse')
}
Hva er Row Level Security og hvorfor er det viktig?
Row Level Security (RLS) er PostgreSQL sin mekanisme for å kontrollere hvilke rader en bruker kan lese, opprette, oppdatere og slette. Det er sikkerhetsmodellen som gjør at du kan eksponere Supabase-klienten direkte til frontend uten risiko. Les vår komplette RLS-guide for avanserte mønstre og beste praksis.
-- Aktiver RLS på en tabell
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- Bare autentiserte brukere kan lese
CREATE POLICY "Autentiserte kan lese"
ON posts FOR SELECT
TO authenticated
USING (true);
-- Brukere kan bare oppdatere egne poster
CREATE POLICY "Brukere oppdaterer egne poster"
ON posts FOR UPDATE
TO authenticated
USING (auth.uid() = user_id);
-- Brukere kan bare slette egne poster
CREATE POLICY "Brukere sletter egne poster"
ON posts FOR DELETE
TO authenticated
USING (auth.uid() = user_id);
| RLS-policy | Effekt |
|-----------|--------|
| FOR SELECT | Kontrollerer hvem som kan lese |
| FOR INSERT | Kontrollerer hvem som kan opprette |
| FOR UPDATE | Kontrollerer hvem som kan endre |
| FOR DELETE | Kontrollerer hvem som kan slette |
| USING (auth.uid() = user_id) | Begrenser til egne rader |
Hvordan beskytter du sider med autentisering?
I Next.js App Router kan du sjekke auth-status i Server Components:
// 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>Velkommen, {user.email}</h1>
</div>
)
}
Hva er vanlige fallgruver?
Basert på erfaring fra Boligposten.com og andre prosjekter utviklet av Webagent AS:
- Manglende middleware — Uten middleware for session-refresh vil brukere oppleve uventede utlogginger.
- RLS ikke aktivert — Supabase deaktiverer RLS som standard. Alltid aktiver det på alle tabeller.
- Bruk
getUser()ikkegetSession()—getUser()validerer mot Supabase-serveren, mensgetSession()bare leser lokalt token. For sikkerhetskritiske sjekker, bruk alltidgetUser(). - Glemmer auth callback route — For OAuth og magic links trenger du en
/auth/callbackroute handler.
For bedrifter som bygger moderne nettsider med brukerinnlogging, er dette oppsettet en solid grunnmur.
// 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')
if (code) {
const supabase = await createClient()
await supabase.auth.exchangeCodeForSession(code)
}
return NextResponse.redirect(origin)
}
Denne stacken er også ideell for prosjekter som krever AI-integrasjon og GEO-optimalisering.
Oppsummering
Supabase + Next.js gir deg en moderne, sikker auth-stack uten å måtte bygge backend fra scratch. Nøklene er:
- Bruk
@supabase/ssrfor korrekt cookie-håndtering - Implementer middleware for session-refresh
- Aktiver RLS på alle tabeller
- Bruk Server Actions for login/signup
- Valider med
getUser()i Server Components
Denne stacken skalerer fra MVP til produksjon — den er rask å sette opp, trygg å drifte, og fleksibel nok til å vokse med produktet.
Fra teori til praksis
Denne artikkelen er en del av hjelp.dev-eksperimentet — der vi tester om AI-drevet innhold kan bygge ekte autoritet. Alt innhold er åpent og GEO-optimalisert.
Bygget av Webagent AS i Bergen.