La Stack Vercel + Next.js + Supabase + Claude API : Aucun CMS Nécessaire
Je construis des sites sans CMS en 2026
Je construis des sites web avec des plateformes CMS headless depuis des années. Contentful, Sanity, Strapi -- vous le nommez, je l'ai intégré. Mais à la fin de 2025, j'ai commencé à remarquer une tendance : pour un nombre croissant de projets, je ne cherchais pas du tout un CMS. Au lieu de cela, je livrais des applications full-stack avec Next.js sur Vercel, Supabase pour les données et l'authentification, et l'API Claude pour toute l'intelligence de contenu dont j'avais besoin. Aucun fournisseur CMS. Aucune UI de modélisation de contenu. Aucune licence de siège mensuelle.
Ce n'est pas une question de contrariété. Il y a absolument des projets où un CMS headless est le bon choix -- nous en construisons beaucoup chez Social Animal (consultez notre travail de développement CMS headless). Mais il existe une classe spécifique d'applications où cette pile sans fournisseur n'est pas seulement viable, elle est meilleure. Laissez-moi vous montrer exactement comment cela fonctionne, quand l'utiliser, et comment la configurer de zéro.
Table des matières
- Pourquoi les développeurs abandonnent le CMS
- La pile en un coup d'œil
- Configuration de votre projet Next.js sur Vercel
- Supabase comme back-end : authentification, base de données et stockage
- Intégration de l'API Claude pour l'intelligence de contenu
- Construire une interface d'administration personnalisée
- Coûts réels : ce que cette pile vous coûte vraiment
- Quand vous devriez toujours utiliser un CMS
- Liste de vérification du déploiement en production
- FAQ
Pourquoi les développeurs abandonnent le CMS
Soyons honnêtes sur ce qu'un CMS vous donne : une UI pour que les non-techniciens modifient le contenu, une couche de données structurées, peut-être une gestion des médias, et une API pour tout récupérer. C'est genuinely précieux quand vous avez une équipe marketing publiant des articles de blog tous les jours.
Mais voici ce que je ne cesse de voir en 2026 :
- Produits SaaS où le « contenu » est des données générées par l'utilisateur, pas du contenu éditorial
- Outils internes où l'équipe est assez technique pour modifier une base de données directement ou utiliser un panneau d'administration léger
- Applications natives IA où le contenu est généré, résumé ou transformé à la volée
- Startups qui ne peuvent pas justifier 300-500 $/mois pour un CMS quand elles ont trois utilisateurs
Pour ces projets, un CMS est du surpoids. Vous payez pour des fonctionnalités de modélisation de contenu que vous n'utiliserez pas, gérez des clés API pour un service qui est essentiellement un wrapper de base de données fantaisiste, et devez gérer la complexité des webhooks pour garder les choses synchronisées.
L'alternative ? Possédez complètement votre couche de données. Supabase vous donne Postgres (une vraie base de données, pas un magasin de contenu propriétaire), l'authentification, le stockage de fichiers et les abonnements en temps réel. Claude gère la couche d'intelligence. Next.js et Vercel gèrent le reste.
La pile en un coup d'œil
| Couche | Technologie | Rôle | Tarification 2026 (À partir de) |
|---|---|---|---|
| Frontend & API | Next.js 15 (App Router) | UI, Server Components, Route Handlers | Gratuit (open source) |
| Hébergement & Edge | Vercel | Déploiement, CDN, Fonctions sans serveur | Gratuit / $20/mois Pro |
| Base de données & Auth | Supabase | Postgres, Row Level Security, Auth, Storage | Gratuit / $25/mois Pro |
| Couche IA | Claude API (Anthropic) | Génération de contenu, résumé, classification | Paiement à l'usage (~$3/$15 par 1M de tokens pour Sonnet 4) |
| UI d'administration | Personnalisée (React + Supabase) | Gestion de contenu pour votre équipe | $0 (vous la construisez) |
Coût total pour une application en production avec un trafic modéré : $45-100/mois. Comparez cela à une configuration CMS headless typique où le CMS seul pourrait vous coûter $99-500/mois avant même de payer l'hébergement.
Configuration de votre projet Next.js sur Vercel
Je suppose que vous avez Node.js 20+ et un compte Vercel. Si vous êtes nouveau sur Next.js, notre équipe a écrit extensively à ce sujet dans notre page de capacité de développement Next.js.
npx create-next-app@latest my-app --typescript --tailwind --app --src-dir
cd my-app
Next.js 15 avec l'App Router est la fondation ici. Nous utilisons les Server Components par défaut, ce qui signifie que la plupart de notre récupération de données se fait sur le serveur -- pas de clés API exposées, pas de spinners de chargement côté client pour le contenu initial.
Voici ma structure de projet typique pour cette pile :
src/
├── app/
│ ├── (public)/ # Pages marketing, blog
│ ├── (dashboard)/ # Zone d'administration authentifiée
│ │ ├── layout.tsx # Wrapper de vérification d'auth
│ │ ├── posts/
│ │ ├── media/
│ │ └── settings/
│ ├── api/
│ │ ├── ai/ # Routes de l'API Claude
│ │ └── webhooks/ # Hooks en temps réel Supabase
│ └── layout.tsx
├── lib/
│ ├── supabase/
│ │ ├── client.ts # Client navigateur
│ │ ├── server.ts # Client serveur
│ │ └── admin.ts # Client rôle service
│ ├── claude.ts # Wrapper SDK Anthropic
│ └── utils.ts
├── components/
└── types/
Variables d'environnement
Vous aurez besoin de celles-ci dans votre .env.local :
NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-key
ANTHROPIC_API_KEY=sk-ant-...
Déploiement sur Vercel
Poussez vers GitHub. Connectez le repo dans Vercel. Ajoutez vos variables env. C'est fait. Je ne vais pas m'étendre sur cela -- l'UX de Vercel pour le déploiement Next.js est la meilleure de l'industrie et vous savez probablement déjà comment cela fonctionne.
Une chose à noter : utilisez Vercel Edge Config si vous avez besoin de feature flags ou d'une configuration qui se met à jour sans redéploiement. C'est une petite chose mais cela remplace encore un autre outil SaaS.
Supabase comme back-end : authentification, base de données et stockage
C'est là que la magie se produit. Supabase n'est pas juste « Firebase mais Postgres » -- c'est une plateforme back-end complète que vous possédez réellement. Vos données vivent dans une base de données PostgreSQL standard. Si vous voulez jamais partir, vous pg_dump et vous partez. Essayez de faire cela avec un CMS propriétaire.
Schéma de base de données
Disons que vous construisez une application basée sur le contenu (le genre de chose où vous chercheriez normalement un CMS). Voici un schéma qui gère les articles, les médias et la taxonomie basique :
-- Activation de la génération UUID
create extension if not exists "uuid-ossp";
-- Table de contenu (remplace votre modèle de contenu CMS)
create table public.posts (
id uuid default uuid_generate_v4() primary key,
title text not null,
slug text unique not null,
body text, -- Contenu Markdown
excerpt text,
status text default 'draft' check (status in ('draft', 'published', 'archived')),
author_id uuid references auth.users(id),
featured_image text, -- Chemin de Supabase Storage
metadata jsonb default '{}', -- Champs flexibles, pas de migration nécessaire
published_at timestamptz,
created_at timestamptz default now(),
updated_at timestamptz default now()
);
-- Tags / taxonomie
create table public.tags (
id uuid default uuid_generate_v4() primary key,
name text unique not null,
slug text unique not null
);
create table public.post_tags (
post_id uuid references public.posts(id) on delete cascade,
tag_id uuid references public.tags(id) on delete cascade,
primary key (post_id, tag_id)
);
-- Row Level Security
alter table public.posts enable row level security;
-- N'importe qui peut lire les posts publiés
create policy "Public can read published posts"
on public.posts for select
using (status = 'published');
-- Les utilisateurs authentifiés peuvent gérer leurs propres posts
create policy "Authors can manage own posts"
on public.posts for all
using (auth.uid() = author_id);
Cette colonne metadata jsonb est clé. Elle vous donne la flexibilité des champs personnalisés d'un CMS sans avoir besoin de lancer des migrations chaque fois que l'équipe marketing veut un nouveau champ. Besoin d'une description SEO ? metadata->>'seo_description'. Besoin d'une image Open Graph override ? metadata->>'og_image'. C'est sans schéma où vous avez besoin de flexibilité, structuré où vous avez besoin d'intégrité.
Configuration de l'authentification
Supabase Auth gère tout. Email/mot de passe, liens magiques, OAuth avec Google/GitHub -- c'est tout intégré.
// 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)
)
},
},
}
)
}
Stockage de fichiers
Supabase Storage remplace n'importe quelle bibliothèque de médias que votre CMS avait. Créez un bucket appelé media, configurez une politique, et vous avez un magasin de fichiers compatible S3 avec des URL CDN automatiques.
// Télécharger un fichier
const { data, error } = await supabase.storage
.from('media')
.upload(`posts/${slug}/${file.name}`, file, {
cacheControl: '3600',
upsert: false,
})
// Obtenir l'URL publique
const { data: { publicUrl } } = supabase.storage
.from('media')
.getPublicUrl(`posts/${slug}/${file.name}`)
Intégration de l'API Claude pour l'intelligence de contenu
C'est là que la pile 2026 diverge le plus de la développement web traditionnel. L'API Claude n'est pas juste un chatbot -- c'est une couche d'intelligence qui peut remplacer des catégories entières de plugins CMS et services tiers.
Voici ce que je l'utilise en production :
- Génération automatique de métadonnées SEO à partir du contenu des posts
- Résumé de contenu pour les extraits et les cartes sociales
- Classification de contenu et auto-tagging
- Recherche intelligente qui comprend l'intention, pas seulement les mots-clés
- Assistance à la rédaction pour les auteurs de contenu
Configuration du SDK Anthropic
npm install @anthropic-ai/sdk
// lib/claude.ts
import Anthropic from '@anthropic-ai/sdk'
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY!,
})
export async function generateSEOMetadata(content: string, title: string) {
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
messages: [
{
role: 'user',
content: `Given this article title and content, generate SEO metadata.
Title: ${title}
Content: ${content.slice(0, 3000)}
Respond with JSON only:
{
"seo_title": "50-60 char title with primary keyword",
"seo_description": "120-160 char meta description",
"excerpt": "1-2 sentence hook for social sharing",
"suggested_tags": ["tag1", "tag2", "tag3"]
}`,
},
],
})
const text = message.content[0].type === 'text' ? message.content[0].text : ''
return JSON.parse(text)
}
export async function classifyContent(content: string, existingTags: string[]) {
const message = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 256,
messages: [
{
role: 'user',
content: `Classify this content into the most relevant tags from the existing list. You may suggest up to 2 new tags if nothing fits.
Existing tags: ${existingTags.join(', ')}
Content: ${content.slice(0, 2000)}
Respond with JSON: { "tags": ["tag1", "tag2"], "new_tags": ["maybe-new"] }`,
},
],
})
const text = message.content[0].type === 'text' ? message.content[0].text : ''
return JSON.parse(text)
}
Route d'API pour les fonctionnalités IA
// app/api/ai/seo/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { createClient } from '@/lib/supabase/server'
import { generateSEOMetadata } from '@/lib/claude'
export async function POST(request: NextRequest) {
const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
const { content, title } = await request.json()
try {
const metadata = await generateSEOMetadata(content, title)
return NextResponse.json(metadata)
} catch (error) {
return NextResponse.json(
{ error: 'AI generation failed' },
{ status: 500 }
)
}
}
Le coût ici est négligeable. Un appel typique de génération de métadonnées SEO utilise peut-être 4 000 tokens d'entrée et 200 tokens de sortie. Avec la tarification de Claude Sonnet 4 à environ $3/1M de tokens d'entrée et $15/1M de tokens de sortie, cela représente environ $0,015 par appel. Vous pouvez générer des métadonnées pour 1 000 articles pour $15.
Construire une interface d'administration personnalisée
C'est la partie qui rend les gens nerveux. « Si je n'ai pas de CMS, comment les non-techniciens modifient-ils le contenu ? »
Vous construisez une interface d'administration simple. Et en 2026, « simple » est vraiment simple. Voici un composant éditeur de post basique :
// app/(dashboard)/posts/[id]/editor.tsx
'use client'
import { useState } from 'react'
import { createBrowserClient } from '@supabase/ssr'
export function PostEditor({ post }: { post: Post }) {
const [title, setTitle] = useState(post.title)
const [body, setBody] = useState(post.body || '')
const [saving, setSaving] = useState(false)
const supabase = createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
async function save() {
setSaving(true)
const { error } = await supabase
.from('posts')
.update({
title,
body,
updated_at: new Date().toISOString(),
})
.eq('id', post.id)
setSaving(false)
if (error) alert('Save failed: ' + error.message)
}
async function generateSEO() {
const res = await fetch('/api/ai/seo', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title, content: body }),
})
const metadata = await res.json()
// Appliquer les métadonnées générées au post
await supabase
.from('posts')
.update({ metadata, excerpt: metadata.excerpt })
.eq('id', post.id)
}
return (
<div className="max-w-4xl mx-auto p-6">
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
className="text-3xl font-bold w-full mb-4 border-b pb-2"
/>
<textarea
value={body}
onChange={(e) => setBody(e.target.value)}
className="w-full h-96 font-mono text-sm p-4 border rounded"
/>
<div className="flex gap-4 mt-4">
<button onClick={save} disabled={saving}
className="px-4 py-2 bg-blue-600 text-white rounded">
{saving ? 'Saving...' : 'Save Draft'}
</button>
<button onClick={generateSEO}
className="px-4 py-2 bg-purple-600 text-white rounded">
✨ Generate SEO Metadata
</button>
</div>
</div>
)
}
Oui, c'est une textarea simple. Dans un vrai projet, vous échangeriez quelque chose comme Tiptap, MDXEditor, ou BlockNote pour l'édition riche. Le point est : l'interface d'administration est votre code. Vous contrôlez chaque pixel, chaque workflow, chaque permission. Pas de combat avec les limitations de l'UI du CMS.
Pour les projets plus complexes, envisagez Refine ou AdminJS comme frameworks de panneau d'administration qui se branchent directement sur Supabase. Ils vous feront économiser des semaines.
Coûts réels : ce que cette pile vous coûte vraiment
Soyons spécifiques avec les chiffres pour un site riche en contenu avec 100 000 pages vues/mois :
| Service | Tier | Coût mensuel | Ce que vous obtenez |
|---|---|---|---|
| Vercel | Pro | $20 | 1TB de bande passante, 1000 GB-hrs sans serveur |
| Supabase | Pro | $25 | 8GB de base de données, 250GB de bande passante, 100 000 utilisateurs auth |
| Claude API | Paiement à l'usage | ~$10-30 | ~5M de tokens/mois (gen SEO, résumés, recherche) |
| Domaine | Annuel | ~$1 | domaine .com |
| Total | $56-76/mois |
Comparez cela maintenant à une pile CMS headless typique :
| Service | Tier | Coût mensuel |
|---|---|---|
| Contentful | Team | $300 |
| Vercel | Pro | $20 |
| Algolia (recherche) | Build | $50 |
| Auth0 (auth) | Essentials | $35 |
| Total | $405/mois |
C'est une différence de coût 5-6x. Et la pile Supabase vous donne plus de flexibilité, pas moins.
Quand vous devriez toujours utiliser un CMS
Je veux être réaliste à ce sujet. N'abandonnez pas votre CMS pour chaque projet. Un CMS headless est toujours le meilleur choix quand :
- Grandes équipes éditoriales ont besoin de workflows structurés (chaînes d'approbation, planification, rôles qui vont au-delà du RBAC basique)
- Le contenu est le produit -- éditeurs, médias, sites de documentation avec des centaines de contributeurs
- Vous avez besoin d'édition visuelle -- certaines plateformes CMS offrent un aperçu en direct et des constructeurs visuels qui prendraient des mois à répliquer
- Livraison multi-canaux -- si le même contenu alimente un site web, une application mobile, des panneaux numériques et l'email, le modèle de contenu structuré d'un CMS mérite sa place
- Localisation à l'échelle -- les plateformes CMS comme Contentful et Sanity ont des workflows i18n matures
Nous construisons toujours beaucoup de projets CMS headless chez Social Animal. Si c'est ce dont votre projet a besoin, parlez-nous de cela. Mais pour la catégorie croissante d'applications où ce n'est pas ce dont vous avez besoin, arrêtez de payer pour cela.
Liste de vérification du déploiement en production
Avant de livrer cette pile en production, parcourez cette liste :
- Politiques Row Level Security testées pour chaque table (le simulateur de politique de Supabase aide ici)
- Limitation de débit sur les routes de l'API Claude (utilisez le limiteur de débit
@vercel/edgeou upstash/ratelimit) - Validation d'entrée sur toutes les routes API (Zod est votre ami)
- Limites d'erreur dans votre arbre React pour les défaillances IA (Claude s'arrêtera occasionnellement)
- Stratégie de mise en cache -- utilisez
unstable_cacheourevalidateTagdans Next.js pour les pages sauvegardées en base de données - Surveillance -- Vercel Analytics pour les performances, Tableau de bord Supabase pour les métriques de base de données, Console Anthropic pour l'utilisation de l'API
- Stratégie de sauvegarde -- Supabase Pro inclut les sauvegardes quotidiennes, mais configurez également la réplication logique ou
pg_dumpcron pour la tranquillité d'esprit - En-têtes Content Security Policy configurés dans
next.config.js - Optimisation des images -- utilisez le composant Next.js
<Image>avec les URL de Supabase Storage
FAQ
Supabase peut-il vraiment remplacer un CMS headless ?
Pour de nombreux cas d'utilisation, oui. Supabase vous donne une base de données PostgreSQL avec une API REST et GraphQL générée automatiquement à partir de votre schéma, le stockage de fichiers, l'authentification et les abonnements en temps réel. Ce qu'elle ne vous donne pas, c'est une UI d'édition de contenu polie prête à l'emploi -- vous devrez construire cela vous-même ou utiliser un outil comme Refine. Si votre équipe est technique ou petite, ce compromis en vaut absolument la peine.
Combien coûte l'API Claude pour un site typique ?
Pour un site de contenu qui utilise Claude pour la génération de métadonnées SEO, le résumé de contenu et la classification basique, attendez-vous à dépenser $10-30/mois avec une utilisation modérée (quelques centaines d'opérations IA). La tarification de Claude Sonnet 4 en 2026 s'élève à environ $3 par million de tokens d'entrée et $15 par million de tokens de sortie. Un seul appel de génération de métadonnées SEO coûte environ $0,01-0,02.
Cette pile convient-elle aux applications d'entreprise ?
Cela dépend de votre définition d'entreprise. Vercel et Supabase offrent tous deux des tiers d'entreprise avec des SLA, la conformité SOC 2 et le support dédié. La pile gère bien le trafic élevé -- Next.js sur Vercel se met à l'échelle automatiquement, et Supabase Pro prend en charge le regroupement de connexions et les répliques de lecture. Pour les industries avec beaucoup de conformité, vous voudriez l'option auto-hébergée de Supabase pour garder les données dans votre propre infrastructure.
Qu'en est-il des aperçus de contenu et des workflows de brouillon ?
Vous les construisez. Le Mode Brouillon Next.js combiné à une colonne status dans votre table de posts vous donne des workflows brouillon/publié. Pour les aperçus, créez une route authentifiée qui récupère les posts quel que soit le statut. C'est peut-être 50 lignes de code par rapport à la configuration des URL d'aperçu dans un tableau de bord CMS.
Comment gérez-vous l'édition de texte riche sans CMS ?
Utilisez une bibliothèque d'éditeur de texte riche moderne. Tiptap (construit sur ProseMirror) est le choix le plus populaire en 2026 -- il supporte l'édition collaborative, les blocs personnalisés, les commandes slash et les raccourcis Markdown. BlockNote est une autre option solide avec une UI de type Notion. Stockez la sortie en tant que HTML, Markdown ou JSON dans votre colonne body de Supabase.
Puis-je migrer d'un CMS headless vers cette pile ?
Absolument. La plupart des plateformes CMS headless ont des API d'exportation. Écrivez un script de migration qui tire le contenu de l'API de votre CMS et l'insère dans les tables Supabase. Nous avons effectué cette migration pour plusieurs clients, passant de Contentful et Sanity à des configurations sauvegardées par Supabase. La partie la plus difficile est généralement de mapper le format de texte riche propriétaire du CMS vers du HTML ou du Markdown standard.
Que se passe-t-il si Supabase s'arrête ?
Supabase a eu un bon uptime en 2025-2026, mais aucun service n'est parfait. Parce que vos données vivent dans PostgreSQL standard, vous avez des options : configurez des répliques de lecture, gardez des sauvegardes automatisées dans S3, ou même lancez une instance de secours. Si vous êtes sur le tier auto-hébergé de Supabase, vous contrôlez entièrement l'infrastructure. C'est en fait plus résilient que de dépendre d'un fournisseur CMS -- si Contentful a une panne, vous ne pouvez pas juste « basculer vers un autre Contentful ».
Dois-je utiliser cette pile pour un blog ou un site marketing ?
Pour le blog personnel d'un développeur ou le site marketing d'une startup, cette pile est parfaite. Vous obtenez le contrôle complet, des coûts minimaux et des fonctionnalités alimentées par IA qui nécessiteraient des plugins coûteux dans un CMS. Pour une grande équipe marketing publiant 20+ articles par semaine avec des workflows d'approbation complexes, vous voudriez probablement un CMS approprié. Il s'agit d'adapter l'outil à l'équipe. Si vous ne savez pas quelle approche convient à votre projet, consultez notre page de tarification ou contactez-nous pour une consultation rapide.