BaliseTonSite

Intégration Next.js

@supabase/ssr, middleware, Server Components et gestion des sessions dans Next.js.

9.1Installation

Installer les packagesbash
npm install @supabase/supabase-js @supabase/ssr
.env.localbash
NEXT_PUBLIC_SUPABASE_URL=https://xxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6...

9.2Client navigateur (composants client)

lib/supabase/client.tstypescript
import { createBrowserClient } from '@supabase/ssr'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
  )
}
Utilisation dans un composant clienttypescript
'use client'

import { createClient } from '@/lib/supabase/client'

export function LikeButton() {
  const supabase = createClient()

  async function handleLike() {
    const { data: { user } } = await supabase.auth.getUser()
    if (!user) return

    await supabase.from('chapter_likes').upsert({
      user_id: user.id,
      chapter_slug: 'mon-chapitre',
    })
  }

  return <button onClick={handleLike}>J'aime</button>
}

9.3Client serveur (Server Components, API Routes)

lib/supabase/server.tstypescript
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) {
          try {
            cookiesToSet.forEach(({ name, value, options }) =>
              cookieStore.set(name, value, options)
            )
          } catch {
            // Ignoré dans les Server Components (read-only)
          }
        },
      },
    },
  )
}
Utilisation dans un Server Componenttypescript
import { createClient } from '@/lib/supabase/server'

export default async function ProfilPage() {
  const supabase = await createClient()
  const { data: { user } } = await supabase.auth.getUser()

  if (!user) {
    return <p>Non connecté</p>
  }

  const { data: orders } = await supabase
    .from('orders')
    .select('tier, amount, created_at')
    .order('created_at', { ascending: false })

  return (
    <div>
      <h1>Bonjour {user.user_metadata.first_name}</h1>
      <p>Email : {user.email}</p>
      <p>Commandes : {orders?.length ?? 0}</p>
    </div>
  )
}

9.4Middleware (refresh automatique)

Le middleware Next.js est essentiel : il rafraîchit le token JWT Supabase à chaque requête. Sans ça, les sessions expirent après 1 heure.

middleware.ts (racine du projet)typescript
import { type NextRequest, NextResponse } from 'next/server'
import { createServerClient } from '@supabase/ssr'

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)
          )
        },
      },
    },
  )

  // Rafraîchir la session (renouvelle le JWT si nécessaire)
  await supabase.auth.getUser()

  return response
}

export const config = {
  matcher: [
    '/((?!_next/static|_next/image|favicon.ico).*)',
  ],
}

9.5Protection de routes

Rediriger les utilisateurs non connectéstypescript
// Dans le middleware, après le refresh de session :
export async function middleware(request: NextRequest) {
  // ... setup supabase + refresh ...

  const { data: { user } } = await supabase.auth.getUser()

  // Protéger les routes /profil/*
  if (request.nextUrl.pathname.startsWith('/profil') && !user) {
    return NextResponse.redirect(new URL('/connexion', request.url))
  }

  return response
}

9.6API Routes

app/api/profil/route.tstypescript
import { createClient } from '@/lib/supabase/server'
import { NextResponse } from 'next/server'

export async function GET() {
  const supabase = await createClient()
  const { data: { user } } = await supabase.auth.getUser()

  if (!user) {
    return NextResponse.json({ error: 'Non autorisé' }, { status: 401 })
  }

  const { data: orders } = await supabase
    .from('orders')
    .select('*')

  return NextResponse.json({ user, orders })
}

Verifie tes acquis

5 questions pour valider ce chapitre

1. Quel package gere les cookies Supabase dans Next.js ?

Valide et sauvegarde ce chapitre

Ne perds pas le fil de ton apprentissage. Chaque QCM terminé sauvegarde ton score. Crée ton profil gratuitement pour débloquer toutes les évaluations du site et retrouver tes résultats plus tard.

Commencer l'aventure
Déjà membre ?Connecte-toi