Retour au blog
10 min12 avril 2026

Next.js + Supabase : le stack parfait pour les freelances

Pourquoi cette combinaison est ideale pour livrer vite et bien. Auth, RLS, Realtime, deploys Vercel — tout ce qu'il faut sans la complexite.

Next.jsSupabaseStack

Apres avoir construit 5 projets en production avec Next.js + Supabase — dont un SaaS de 480K lignes et un site vitrine avec formulaires et analytics — je suis convaincu que ce stack est le meilleur choix pour un freelance qui veut livrer vite sans sacrifier la qualite.

Cet article est le guide pratique que j'aurais voulu avoir en commençant. Pas de theorie — des patterns testes en production, avec les pieges que j'ai rencontres et comment les eviter.

Pourquoi ce stack ?

En freelance, le temps c'est de l'argent. Literalement. Chaque heure passee a configurer de l'infra, c'est une heure non facturee. Next.js + Supabase + Vercel, c'est :

  • Zero config serveur — Vercel gere le deploiement, Supabase gere la base
  • Auth en 15 minutes — JWT, sessions, cookies, tout est integre
  • Realtime gratuit — subscriptions Postgres sans WebSocket a configurer
  • Type safety bout en bout — du schema Postgres aux composants React
  • Free tier genereux — tu ne paies que quand le projet genere du revenu

Le piege numero 1 : les clients Supabase

C'est le truc qui fait perdre des heures a tout le monde. Supabase avec Next.js, c'est pas un client — c'est trois clients differents, et utiliser le mauvais casse tout silencieusement.

Client Service (API Routes uniquement) :

import { createServiceClient } from '@/lib/supabase/server'
const supabase = createServiceClient()
// Utilise service_role → bypass RLS

Client Serveur (Server Components) :

import { createClient } from '@/lib/supabase/server'
const supabase = await createClient()
// Utilise anon + cookies → respecte RLS

Client Navigateur (Client Components) :

import { createClient } from '@/lib/supabase/client'
const supabase = createClient()
// Utilise anon → respecte RLS

L'arbre de decision est simple :

  • Tu es dans une API Route ? → createServiceClient()
  • Tu es dans un Server Component ? → createClient() depuis server.ts
  • Tu es dans un Client Component ? → createClient() depuis client.ts

Le piege classique : tu crees un formulaire de contact public. L'utilisateur n'est pas authentifie. Tu utilises le client anon dans ton API Route. Boom : "new row violates row-level security policy". Parce que l'anon key respecte RLS, et ta policy n'autorise pas l'insert anonyme — ou pire, tu n'as pas de policy du tout.

La solution : utilise createServiceClient() dans les API Routes publiques. Il bypass RLS avec la service_role key. Et ne jamais exposer cette cle cote client.

RLS : la securite qui mord

Row Level Security, c'est genial. Mais ca mord les debutants. Voici les patterns qui fonctionnent :

Pour les formulaires publics (contact, newsletter) :

-- Autoriser l'insertion anonyme
CREATE POLICY "allow_anon_insert" ON contacts
  FOR INSERT TO anon WITH CHECK (true);
-- Pas de SELECT pour anon = personne ne peut lire

Pour les donnees utilisateur :

-- Chaque user voit uniquement ses donnees
CREATE POLICY "user_own_data" ON todos
  FOR ALL TO authenticated
  USING (auth.uid() = user_id);

Regle d'or : RLS est active par defaut sur toutes tes tables. Si tu oublies de creer une policy, rien ne passe. C'est securise par defaut, mais ca peut etre frustrant quand tu debogues un formulaire qui "ne marche pas" alors que le code est correct.

Le pattern API Route qui marche

Apres plusieurs iterations, voici le pattern que j'utilise dans tous mes projets :

  1. Rate limiting — 5 requetes / 15 minutes par IP (en memoire, suffisant pour un MVP)
  2. Validation Zod — un schema par endpoint, parse avant tout
  3. Insert Supabase — avec createServiceClient()
  4. Analytics — tracking PostHog server-side
  5. Reponse JSON — toujours un { success: true/false }

Ce pipeline en 5 etapes est replique sur chaque endpoint. C'est repetitif ? Oui. Mais c'est aussi previsible, testable, et debuggable. En freelance, la previsibilite vaut plus que l'elegance.

Type safety de bout en bout

Un des plus gros avantages du combo Next.js + Supabase : le typage ne s'arrete pas a React.

Le workflow :

  1. Tu modifies le schema dans une migration SQL
  2. Tu lances npm run supabase:types
  3. TypeScript te dit immediatement tous les endroits du code affectes

Plus de "j'ai rename une colonne et je le decouvre en production". Le compilateur attrape tout. Combine avec des schemas Zod pour la validation runtime, tu as une double couche de securite sur les types.

Deploiement : le workflow en 3 commandes

C'est la que le stack brille vraiment. Deployer en production :

  1. supabase db push — applique les migrations sur la base distante
  2. git push — Vercel detecte, build, deploie automatiquement
  3. npm run test:e2e:prod — smoke tests contre la prod

Pas de Docker a configurer. Pas de serveur a maintenir. Pas de CI/CD complexe a ecrire. Tu push, c'est en prod. Le free tier Vercel + le free tier Supabase couvrent la majorite des projets freelance sans sortir la carte bleue.

Les gotchas en production

Quelques pieges que j'ai rencontres sur mes projets en production :

  • PostHog region mismatch — cle API EU pointant vers l'endpoint US. Resultat : 404 sur config.js, 401 sur les feature flags. Solution : verifier que NEXT_PUBLIC_POSTHOG_HOST correspond a la region de ta cle.
  • Rate limiting en memoire — ca marche bien pour un MVP, mais ca se reinitialise a chaque redeploy Vercel (serverless = stateless). Pour la production serieuse, passe a Upstash Redis.
  • Variables d'environnement — seules les variables prefixees NEXT_PUBLIC_sont exposees au navigateur. Oublie le prefixe sur ta Supabase URL = formulaire casse sans erreur visible cote serveur.
  • Server Components par defaut — Next.js 15 rend tout en Server Component. Ajoute 'use client' uniquement si tu as besoin de hooks, d'event handlers ou d'etat. Moins de client JS = meilleures perfs = meilleur Core Web Vitals.

Mon conseil pour les freelances

Si tu debutes en freelance et que tu cherches un stack, arrete de comparer. Prends Next.js + Supabase + Vercel, livre ton premier projet, et iterate. Le meilleur stack, c'est celui avec lequel tu livres — pas celui qui a le plus d'etoiles sur GitHub.

Les patterns decrits dans cet article — trois clients Supabase, RLS par defaut, validation Zod, API Routes en pipeline, types auto-generes — couvrent 90% des besoins freelance. Le reste, tu l'apprendras en livrant.

Et quand tu tomberas sur le message "new row violates row-level security policy", tu sauras exactement quoi faire.

Tu veux discuter de cet article ?

Je suis toujours ouvert aux echanges — que ce soit pour un projet, une question technique, ou juste pour papoter.

Me contacter