# Fichier: python_cheats/cheatsheets/vercel.txt
# Cheatsheet Vercel - Guide Complet Platform


[OK] INTRODUCTION VERCEL - COMPRENDRE LES BASES

# QU'EST-CE QUE VERCEL ?

Vercel est une plateforme cloud qui permet de déployer des sites web et applications
SANS avoir à gérer de serveurs. C'est comme Heroku, mais spécialisé pour le frontend.

# ANALOGIE SIMPLE:
# - Traditionnellement: Vous louez un serveur, installez Node.js, configurez NGINX, 
#   gérez les mises à jour, la sécurité, etc.
# - Avec Vercel: Vous faites "git push" et TOUT est automatique (build, déploiement, 
#   HTTPS, CDN mondial)

# POURQUOI UTILISER VERCEL ?

# 1. DÉPLOIEMENT EN 30 SECONDES
#    git push -> Vercel détecte -> Build automatique -> Déploiement -> URL live
#    Exemple: vous modifiez index.html, faites git push, 30s après c'est en ligne

# 2. HTTPS AUTOMATIQUE
#    Pas besoin de Let's Encrypt ou certificats SSL
#    Votre site est TOUJOURS en https:// automatiquement

# 3. CDN GLOBAL GRATUIT
#    Votre site est copié sur 50+ serveurs dans le monde
#    Un utilisateur au Japon aura le site aussi rapide qu'un utilisateur en France

# 4. PREVIEW DEPLOYMENTS
#    Chaque Pull Request GitHub = URL de prévisualisation unique
#    Testez les changements AVANT de merger dans production

# 5. SERVERLESS FUNCTIONS
#    Écrivez du code backend (API, webhooks) sans gérer de serveurs
#    Comme AWS Lambda mais 100x plus simple

# 6. GRATUIT POUR DÉBUTER
#    Projets personnels, portfolios, side projects = 100% gratuit
#    Pas de carte bancaire requise

# AVANTAGES DÉTAILLÉS:

[OK] Déploiements automatiques depuis Git
  -> Connectez GitHub/GitLab, chaque push = nouveau déploiement
  
[OK] CDN global automatique  
  -> Votre site est servi depuis le serveur le plus proche de l'utilisateur
  
[OK] HTTPS automatique
  -> Certificat SSL gratuit et automatique pour tous vos domaines
  
[OK] Preview deployments pour chaque PR
  -> Testez visuellement chaque changement avant de le mettre en production
  
[OK] Serverless functions
  -> API backend sans serveur (Node.js, Python, Go, Ruby)
  
[OK] Edge Network
  -> Code exécuté au plus près des utilisateurs (latence ultra-faible)
  
[OK] Analytics intégrés
  -> Voyez les performances, visiteurs, etc. sans Google Analytics
  
[OK] Gratuit pour usage personnel
  -> 100 GB bandwidth/mois, déploiements illimités, projets illimités

# QUAND UTILISER VERCEL ?

[OK] BON POUR:
- Sites statiques (HTML/CSS/JS)
- Applications React, Vue, Angular, Svelte
- Applications Next.js (recommandé - Vercel a créé Next.js)
- Portfolios, landing pages, blogs
- JAMstack applications
- APIs simples avec serverless functions

[X] PAS IDÉAL POUR:
- Applications nécessitant serveur persistant (WebSockets longue durée)
- Bases de données lourdes (PostgreSQL massif)
- Applications nécessitant accès filesystem
- Traitements très longs (> 60 secondes)

# ALTERNATIVES:
- Netlify: Similaire à Vercel (concurrent principal)
- GitHub Pages: Gratuit mais uniquement sites statiques
- Heroku: Plus flexible mais plus complexe
- AWS/GCP/Azure: Puissant mais très complexe


[OK] CONCEPTS CLÉS À COMPRENDRE

# 1. DÉPLOIEMENT vs BUILD

BUILD (Construction):
- Transformer votre code source en fichiers prêts pour production
- Exemples: npm run build, next build, vite build
- Génère dossier dist/ ou build/ ou .next/

DÉPLOIEMENT:
- Envoyer les fichiers buildés sur les serveurs Vercel
- Les rendre accessibles via une URL

WORKFLOW:
Code source -> Build -> Déploiement -> URL live
   (local)    (Vercel) (Vercel)    (Internet)

# 2. PREVIEW vs PRODUCTION

PREVIEW (Aperçu):
- URL temporaire générée pour tester
- Créé à chaque commit sur branches non-production
- Exemple: my-app-abc123.vercel.app
- Parfait pour: tester features, review code, démo client

PRODUCTION:
- URL finale publique de votre application
- Créé uniquement sur branche principale (main/master)
- Exemple: my-app.com ou my-app.vercel.app
- C'est l'URL que vos vrais utilisateurs visitent

ANALOGIE:
Preview = Brouillon
Production = Publication finale

# 3. SERVERLESS FUNCTIONS

SERVEUR TRADITIONNEL:
- Serveur qui tourne 24/7
- Vous payez même si personne ne visite
- Vous gérez mises à jour, sécurité, etc.

SERVERLESS:
- Code exécuté SEULEMENT quand quelqu'un appelle l'API
- Vous payez SEULEMENT pour les exécutions
- Pas de serveur à gérer

EXEMPLE CONCRET:
# api/hello.js - Cette fonction devient automatiquement une API
export default function handler(req, res) {
  res.json({ message: 'Hello' });
}

# Accessible via: https://votre-app.vercel.app/api/hello
# S'exécute SEULEMENT quand quelqu'un visite cette URL

# 4. EDGE FUNCTIONS vs SERVERLESS FUNCTIONS

SERVERLESS FUNCTIONS:
- Exécutées dans UN datacenter (ex: US East)
- Latence: ~100-500ms selon localisation utilisateur
- Durée max: 10-60 secondes
- Parfait pour: API, webhooks, traitement données

EDGE FUNCTIONS:
- Exécutées dans le datacenter le PLUS PROCHE de l'utilisateur
- Latence: ~10-50ms (ultra-rapide)
- Durée max: quelques secondes
- Parfait pour: redirections, A/B testing, personnalisation

ANALOGIE:
Serverless = Restaurant central qui livre partout
Edge = Food trucks dans chaque quartier

# 5. ENVIRONNEMENTS

DEVELOPMENT (Développement):
- Sur votre ordinateur (localhost:3000)
- Variables: .env.local
- Commande: vercel dev

PREVIEW:
- Sur Vercel, branches feature
- Variables: Configuration Vercel "Preview"
- URL: feature-xyz.vercel.app

PRODUCTION:
- Sur Vercel, branche main
- Variables: Configuration Vercel "Production"  
- URL: votre-domaine.com

# 6. VARIABLES D'ENVIRONNEMENT

Ce sont des valeurs secrètes/configurables utilisées par votre application.

EXEMPLES:
- Clés API (Stripe, SendGrid, etc.)
- URLs base de données
- Tokens d'authentification
- Flags de features

RÈGLE D'OR:
[X] JAMAIS dans le code (git)
[OK] TOUJOURS dans variables d'environnement

# Comment ça marche:
1. Définir dans Vercel Dashboard ou CLI
2. Utiliser dans code: process.env.MA_VARIABLE
3. Valeurs différentes par environnement (dev/preview/prod)


[OK] PREMIER DÉPLOIEMENT - GUIDE PAS À PAS

# MÉTHODE 1: DÉPLOIEMENT VIA DASHBOARD (LE PLUS SIMPLE)

# ÉTAPE 1: CRÉER UN COMPTE
# 1. Aller sur https://vercel.com
# 2. Cliquer "Sign Up"
# 3. Choisir "Continue with GitHub" (recommandé)
#    -> Vercel accédera à vos repos GitHub
#    -> Authentification plus simple

# ÉTAPE 2: PRÉPARER VOTRE PROJET

# Exemple 1: Site statique simple
mon-site/
├── index.html       # Page principale
├── style.css        # Styles
└── script.js        # JavaScript

# Exemple 2: Application React
my-react-app/
├── package.json     # Dépendances
├── public/
│   └── index.html
└── src/
    └── App.js

# IMPORTANT: Pusher sur GitHub d'abord
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/mon-projet.git
git push -u origin main

# ÉTAPE 3: IMPORTER DEPUIS GITHUB

# 1. Sur vercel.com, cliquer "Add New..." -> "Project"
# 2. Cliquer "Import Git Repository"
# 3. Sélectionner votre repo GitHub
# 4. Cliquer "Import"

# ÉTAPE 4: CONFIGURER LE PROJET

# Vercel détecte automatiquement:
# - Framework (React, Next.js, Vue, etc.)
# - Build command (npm run build)
# - Output directory (build/, dist/, etc.)

# Configuration automatique pour:
[OK] Next.js      -> détecté si package.json contient "next"
[OK] React (CRA)  -> détecté si package.json contient "react-scripts"
[OK] Vue          -> détecté si package.json contient "vue"
[OK] Vite         -> détecté si package.json contient "vite"
[OK] Static HTML  -> détecté si seulement .html files

# Si détection échoue, configurer manuellement:
Framework Preset: [Sélectionner ou "Other"]
Build Command: npm run build
Output Directory: dist    # ou build/ selon votre projet
Install Command: npm install

# ÉTAPE 5: DÉPLOYER

# 1. Cliquer "Deploy"
# 2. Attendre 30-60 secondes (voir logs build en temps réel)
# 3. [OK] "Your project has been deployed!"
# 4. URL générée: https://mon-projet.vercel.app

# FÉLICITATIONS! Votre site est en ligne!

# ÉTAPE 6: TESTER

# Ouvrir l'URL dans navigateur
# Exemple: https://mon-portfolio-abc123.vercel.app

# ÉTAPE 7: MISES À JOUR AUTOMATIQUES

# Maintenant, chaque fois que vous faites:
git add .
git commit -m "Update homepage"
git push

# -> Vercel redéploie AUTOMATIQUEMENT (30-60s)
# -> URL reste la même
# -> Anciens déploiements conservés (rollback possible)


# MÉTHODE 2: DÉPLOIEMENT VIA CLI (POUR DÉVELOPPEURS)

# ÉTAPE 1: INSTALLER VERCEL CLI

# Avec npm (Node.js requis)
npm install -g vercel

# Avec yarn
yarn global add vercel

# Avec pnpm  
pnpm add -g vercel

# Vérifier installation
vercel --version
# Résultat attendu: Vercel CLI 28.x.x

# ÉTAPE 2: SE CONNECTER

# Lancer commande de connexion
vercel login

# Choisir méthode:
# -> Continue with GitHub (recommandé)
# -> Continue with Email
# -> Continue with GitLab
# -> Continue with Bitbucket

# Si GitHub:
# 1. Navigateur s'ouvre automatiquement
# 2. Cliquer "Authorize Vercel"
# 3. Retour terminal: "Success! GitHub authentication complete"

# Vérifier connexion
vercel whoami
# Résultat: votre-username

# ÉTAPE 3: NAVIGUER VERS PROJET

cd mon-projet

# Structure minimale attendue:
# - Pour HTML statique: index.html
# - Pour React/Vue: package.json + src/
# - Pour Next.js: package.json + pages/

# ÉTAPE 4: PREMIER DÉPLOIEMENT

vercel

# Questions interactives (première fois):

# ? Set up and deploy "~/mon-projet"? [Y/n]
# -> Taper: y (Enter)

# ? Which scope do you want to deploy to?
# -> Sélectionner: votre-username (Enter)

# ? Link to existing project? [y/N]
# -> Taper: N (premier déploiement)

# ? What's your project's name?
# -> Proposé: mon-projet
# -> Taper: Enter (accepter) ou taper nouveau nom

# ? In which directory is your code located?
# -> Proposé: ./
# -> Taper: Enter (si code à la racine)

# ? Want to modify settings? [y/N]
# -> Taper: N (settings auto-détectés)

# Vercel va maintenant:
# 1. [RAPIDE] Inspecting project
# 2. [LIEN] Linking to existing project (si déjà créé)
# 3. [OUTIL] Building project
# 4. [OK] Deploying
# 5. [BRAVO] Success!

# Résultat:
# Preview: https://mon-projet-abc123.vercel.app
# Production sera sur: https://mon-projet.vercel.app (après --prod)

# ÉTAPE 5: VOIR LE RÉSULTAT

# URL copiée automatiquement dans clipboard
# Ouvrir navigateur: Ctrl+V (coller URL)

# ÉTAPE 6: DÉPLOYER EN PRODUCTION

vercel --prod

# Différences Preview vs Production:
# Preview:  mon-projet-abc123.vercel.app (URL unique par déploiement)
# Production: mon-projet.vercel.app (URL fixe)

# ÉTAPE 7: MISES À JOUR

# Après modifications:
git add .
git commit -m "Update"

# Déployer preview
vercel

# Déployer production
vercel --prod

# COMPRENDRE LES URLS:

# PREMIÈRE FOIS:
vercel
# -> https://mon-projet-abc123.vercel.app (preview random)

vercel --prod  
# -> https://mon-projet.vercel.app (production fixe)

# DEUXIÈME FOIS:
vercel
# -> https://mon-projet-xyz789.vercel.app (nouveau preview)

vercel --prod
# -> https://mon-projet.vercel.app (MÊME URL, nouveau contenu)


[OK] SCÉNARIOS PRATIQUES DÉBUTANT

# SCÉNARIO 1: DÉPLOYER UN SITE HTML SIMPLE

# Structure projet:
mon-site/
├── index.html
├── about.html
├── css/
│   └── style.css
└── js/
    └── script.js

# index.html
<!DOCTYPE html>
<html>
<head>
    <title>Mon Site</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <h1>Bienvenue sur mon site!</h1>
    <script src="js/script.js"></script>
</body>
</html>

# Déployer:
cd mon-site
vercel

# [OK] C'EST TOUT! Pas de build, pas de config
# Vercel détecte HTML et déploie directement

# Résultat: https://mon-site.vercel.app


# SCÉNARIO 2: DÉPLOYER UNE APP REACT (CREATE REACT APP)

# 1. Créer app
npx create-react-app my-app
cd my-app

# 2. Tester localement
npm start
# -> http://localhost:3000

# 3. Vérifier package.json contient:
{
  "scripts": {
    "build": "react-scripts build"  # <- Vercel utilisera ça
  }
}

# 4. Déployer
vercel --prod

# Vercel va automatiquement:
# - Détecter React
# - Exécuter: npm install
# - Exécuter: npm run build
# - Déployer: dossier build/

# [OK] Résultat: https://my-app.vercel.app


# SCÉNARIO 3: DÉPLOYER UNE APP NEXT.JS

# 1. Créer app Next.js
npx create-next-app@latest my-nextjs-app
cd my-nextjs-app

# 2. Tester localement
npm run dev
# -> http://localhost:3000

# 3. Déployer (Next.js = créé par Vercel, support parfait)
vercel --prod

# Fonctionnalités automatiques:
# [OK] Optimisation images
# [OK] API routes deviennent serverless functions
# [OK] Static generation
# [OK] Server-side rendering
# [OK] Incremental Static Regeneration

# [OK] Résultat: https://my-nextjs-app.vercel.app


# SCÉNARIO 4: DÉPLOYER AVEC VARIABLES D'ENVIRONNEMENT

# Exemple: Application React avec API key

# 1. Créer fichier .env.local (local seulement)
REACT_APP_API_KEY=ma-cle-secrete-dev
REACT_APP_API_URL=http://localhost:3001/api

# 2. Utiliser dans code (src/App.js)
const apiKey = process.env.REACT_APP_API_KEY;
const apiUrl = process.env.REACT_APP_API_URL;

fetch(`${apiUrl}/data`, {
  headers: {
    'Authorization': `Bearer ${apiKey}`
  }
});

# 3. Ajouter .env.local au .gitignore
echo ".env.local" >> .gitignore

# [X] NE JAMAIS commit .env.local dans git!

# 4. Ajouter variables dans Vercel (via CLI)
vercel env add REACT_APP_API_KEY production
# Terminal demande: What's the value?
# Taper: ma-cle-secrete-production

vercel env add REACT_APP_API_URL production
# Valeur: https://api.monsite.com

# Ou via Dashboard:
# Project -> Settings -> Environment Variables
# -> Add New
# -> Name: REACT_APP_API_KEY
# -> Value: ma-cle-secrete-production
# -> Environment: Production
# -> Save

# 5. Redéployer pour appliquer
vercel --prod

# [OK] Variables utilisées automatiquement au build


# SCÉNARIO 5: CRÉER UNE API SERVERLESS SIMPLE

# Structure:
my-api/
├── api/
│   ├── hello.js       # Devient /api/hello
│   └── users.js       # Devient /api/users
└── package.json

# api/hello.js - API endpoint simple
export default function handler(req, res) {
  // req = requête entrante
  // res = réponse à envoyer
  
  res.status(200).json({
    message: 'Hello from serverless!',
    timestamp: new Date().toISOString()
  });
}

# api/users.js - API avec logique
export default function handler(req, res) {
  // Exemple de données
  const users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' }
  ];
  
  // Gérer différentes méthodes HTTP
  if (req.method === 'GET') {
    res.status(200).json(users);
  } else if (req.method === 'POST') {
    const newUser = req.body;
    res.status(201).json({ created: newUser });
  } else {
    res.status(405).json({ error: 'Method not allowed' });
  }
}

# package.json (minimal)
{
  "name": "my-api",
  "version": "1.0.0"
}

# Déployer
vercel --prod

# [OK] URLs générées automatiquement:
# https://my-api.vercel.app/api/hello
# https://my-api.vercel.app/api/users

# Tester avec curl:
curl https://my-api.vercel.app/api/hello
# -> {"message":"Hello from serverless!","timestamp":"2024-01-15..."}

# COMPRENDRE CE QUI SE PASSE:
# 1. Chaque fichier dans api/ = un endpoint
# 2. Code s'exécute SEULEMENT quand API appelée
# 3. Pas de serveur à gérer
# 4. Scale automatique (1 ou 1000 requêtes/s)


# SCÉNARIO 6: AJOUTER UN DOMAINE PERSONNALISÉ

# Vous avez: mon-site.vercel.app
# Vous voulez: monsite.com

# MÉTHODE A: Via Dashboard (recommandé)

# 1. Acheter domaine (ex: chez Namecheap, GoDaddy, etc.)

# 2. Dans Vercel Dashboard:
#    Project -> Settings -> Domains
#    -> Add Domain
#    -> Taper: monsite.com
#    -> Add

# 3. Configurer DNS:
# Vercel affiche instructions:
# -> Type A, Name @, Value 76.76.21.21
# -> Type CNAME, Name www, Value cname.vercel-dns.com

# 4. Aller chez votre registrar (Namecheap, etc.)
#    DNS Settings -> Add Record:
#    - Type: A, Host: @, Value: 76.76.21.21
#    - Type: CNAME, Host: www, Value: cname.vercel-dns.com

# 5. Attendre propagation DNS (5 min - 48h, souvent 1-2h)

# 6. [OK] Certificat SSL automatique généré
#    https://monsite.com fonctionne!

# MÉTHODE B: Via CLI
vercel domains add monsite.com
# Suivre instructions DNS affichées


# SCÉNARIO 7: WORKFLOW COMPLET AVEC GITHUB

# Setup initial (une seule fois):

# 1. Créer repo GitHub
# Via https://github.com/new
# Nom: mon-projet

# 2. Connecter projet local à GitHub
cd mon-projet
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/username/mon-projet.git
git push -u origin main

# 3. Connecter à Vercel
# Via Dashboard: Import Git Repository -> mon-projet
# OU via CLI: vercel (puis link au repo)

# Workflow quotidien:

# 1. Créer feature branch
git checkout -b feature/nouvelle-fonctionnalite

# 2. Développer localement
# Modifier fichiers...
npm run dev  # Tester localement

# 3. Commit et push
git add .
git commit -m "Add nouvelle fonctionnalité"
git push origin feature/nouvelle-fonctionnalite

# 4. [OK] Vercel déploie automatiquement un PREVIEW
#    -> URL unique: https://mon-projet-abc123.vercel.app
#    -> Reçu par email + commentaire GitHub PR

# 5. Créer Pull Request sur GitHub
# -> Voir preview deployment directement dans PR

# 6. Review et tests
# Cliquer sur preview URL dans PR
# Tester fonctionnalité
# Si OK -> Merge PR

# 7. Merge vers main
git checkout main
git pull
git merge feature/nouvelle-fonctionnalite
git push

# 8. [OK] Vercel déploie automatiquement en PRODUCTION
#    -> URL production: https://mon-projet.vercel.app
#    -> Ancienne version remplacée

# AVANTAGES:
# [OK] Preview pour chaque feature avant production
# [OK] Tester sans casser la production
# [OK] Collaborateurs peuvent voir changements
# [OK] Rollback facile si problème

# Avec npm
npm install -g vercel

# Avec yarn
yarn global add vercel

# Avec pnpm
pnpm add -g vercel

# Vérifier installation
vercel --version
vercel -v

# === Connexion & Authentification ===

# Se connecter
vercel login

# Connexion avec email
vercel login user@example.com

# Connexion avec GitHub
vercel login --github

# Connexion avec GitLab
vercel login --gitlab

# Connexion avec Bitbucket
vercel login --bitbucket

# Logout
vercel logout

# Vérifier connexion
vercel whoami

# === Configuration Token API ===

# Créer token: https://vercel.com/account/tokens

# Utiliser token
vercel --token YOUR_TOKEN

# Variable d'environnement
export VERCEL_TOKEN=your_token_here

# Avec CLI
VERCEL_TOKEN=your_token vercel deploy


[OK] DÉPLOIEMENT

# === Déploiement Basique ===

# Déployer projet actuel
vercel

# Déployer avec alias personnalisé
vercel --name my-project

# Déployer en production
vercel --prod
vercel --production

# Déployer dossier spécifique
vercel ./dist
vercel ./build

# Déploiement avec confirmation
vercel --confirm

# Déploiement silencieux
vercel --yes

# === Options de Déploiement ===

# Spécifier environnement
vercel --target production
vercel --target preview
vercel --target development

# Avec build env variables
vercel --build-env KEY=value

# Avec variables d'environnement
vercel -e KEY=value
vercel --env KEY=value

# Forcer nouveau déploiement
vercel --force

# Déployer sans build
vercel --no-build

# Déployer publiquement (accessible sans login)
vercel --public

# Déployer localement pour test
vercel dev

# === Preview Deployments ===

# Déployer preview avec commentaire
vercel --meta gitCommitMessage="Fix bug"

# Preview avec scope
vercel --scope team-name

# Lister déploiements
vercel ls
vercel list

# Lister pour projet spécifique
vercel ls my-project

# === Inspection & Logs ===

# Inspecter déploiement
vercel inspect URL

# Voir logs
vercel logs URL
vercel logs my-project.vercel.app

# Logs en temps réel
vercel logs URL --follow
vercel logs URL -f

# Logs depuis timestamp
vercel logs URL --since 1h
vercel logs URL --since 2023-01-01

# === Gestion des Déploiements ===

# Supprimer déploiement
vercel rm URL
vercel remove URL

# Supprimer tous les deployments d'un projet
vercel rm my-project --yes

# Promouvoir preview en production
vercel promote URL

# Rollback vers déploiement précédent
vercel rollback

# Rollback vers URL spécifique
vercel rollback URL


[OK] PROJETS

# === Création & Gestion ===

# Lier projet existant
vercel link

# Lier avec scope
vercel link --scope team-name

# Créer nouveau projet
vercel init

# Templates disponibles
vercel init next
vercel init react
vercel init vue
vercel init nuxt
vercel init gatsby
vercel init svelte

# Lister projets
vercel projects ls
vercel projects list

# Voir détails projet
vercel projects inspect my-project

# Supprimer projet
vercel projects rm my-project
vercel projects remove my-project

# === Configuration Projet ===

# Pull configuration
vercel pull
vercel pull --environment=production

# Pull pour environnement spécifique
vercel pull --environment=development
vercel pull --environment=preview

# Définir variables projet
vercel env add KEY
vercel env add KEY production
vercel env add KEY preview development


[OK] DOMAINES & DNS

# === Gestion des Domaines ===

# Lister domaines
vercel domains ls
vercel domains list

# Ajouter domaine
vercel domains add example.com
vercel domains add www.example.com

# Ajouter domaine à projet
vercel domains add example.com my-project

# Supprimer domaine
vercel domains rm example.com
vercel domains remove example.com

# Inspecter domaine
vercel domains inspect example.com

# === Alias & URLs ===

# Créer alias
vercel alias set deployment-url.vercel.app my-app.vercel.app

# Créer alias vers production
vercel alias my-custom-domain.com

# Lister alias
vercel alias ls
vercel alias ls my-project

# Supprimer alias
vercel alias rm my-app.vercel.app

# === Configuration DNS ===

# Lister enregistrements DNS
vercel dns ls example.com

# Ajouter enregistrement DNS
vercel dns add example.com A 192.0.2.1
vercel dns add example.com CNAME www.example.com
vercel dns add example.com MX 10 mail.example.com
vercel dns add example.com TXT "v=spf1 include:_spf.example.com ~all"

# Supprimer enregistrement DNS
vercel dns rm record-id


[OK] VARIABLES D'ENVIRONNEMENT

# === Ajouter Variables ===

# Ajouter variable interactive
vercel env add

# Ajouter pour environnement spécifique
vercel env add KEY production
vercel env add KEY preview
vercel env add KEY development

# Ajouter pour tous les environnements
vercel env add KEY production preview development

# Ajouter depuis stdin
echo "secret_value" | vercel env add SECRET production

# === Lister Variables ===

# Lister toutes les variables
vercel env ls

# Lister pour environnement
vercel env ls production
vercel env ls preview
vercel env ls development

# Format JSON
vercel env ls --json

# === Supprimer Variables ===

# Supprimer variable
vercel env rm KEY
vercel env remove KEY

# Supprimer pour environnement spécifique
vercel env rm KEY production

# === Pull Variables ===

# Télécharger variables localement
vercel env pull
vercel env pull .env.local

# Pull pour environnement
vercel env pull .env.production --environment=production

# === Types de Variables ===

# Plain text
vercel env add API_KEY

# Sensitive (chiffrée)
vercel env add DATABASE_PASSWORD

# System (réservées Vercel)
# VERCEL=1
# VERCEL_ENV=production|preview|development
# VERCEL_URL=deployment-url.vercel.app
# VERCEL_GIT_PROVIDER=github|gitlab|bitbucket
# VERCEL_GIT_REPO_SLUG=username/repo
# VERCEL_GIT_REPO_OWNER=username
# VERCEL_GIT_COMMIT_REF=main
# VERCEL_GIT_COMMIT_SHA=abc123
# VERCEL_GIT_COMMIT_MESSAGE="commit message"
# VERCEL_GIT_COMMIT_AUTHOR_LOGIN=username


[OK] SECRETS

# === Gestion des Secrets ===

# Ajouter secret
vercel secrets add secret-name secret-value

# Ajouter depuis fichier
vercel secrets add secret-name < file.txt

# Lister secrets
vercel secrets ls
vercel secrets list

# Renommer secret
vercel secrets rename old-name new-name

# Supprimer secret
vercel secrets rm secret-name
vercel secrets remove secret-name

# === Utilisation des Secrets ===

# Dans vercel.json
{
  "env": {
    "DATABASE_URL": "@database-url-secret",
    "API_KEY": "@api-key-secret"
  }
}

# Via CLI lors du déploiement
vercel --build-env DATABASE_URL=@database-url-secret


[OK] TEAMS & COLLABORATION

# === Gestion Teams ===

# Lister teams
vercel teams ls
vercel teams list

# Changer team active
vercel switch
vercel switch team-name

# Inviter membre
vercel teams invite email@example.com
vercel teams invite email@example.com --role MEMBER
vercel teams invite email@example.com --role VIEWER

# Lister membres
vercel teams members ls

# Supprimer membre
vercel teams members rm email@example.com

# === Scope des Commandes ===

# Exécuter avec scope team
vercel --scope team-name
vercel deploy --scope team-name
vercel ls --scope team-name

# Définir scope par défaut
vercel switch team-name


[OK] CERTIFICATS SSL

# === Gestion Certificats ===

# Lister certificats
vercel certs ls
vercel certs list

# Ajouter certificat
vercel certs add example.com

# Ajouter certificat wildcard
vercel certs add "*.example.com"

# Certificat personnalisé
vercel certs issue example.com cert.crt key.key

# Supprimer certificat
vercel certs rm example.com

# Renouveler certificat
vercel certs renew example.com

# Vérifier certificat
vercel certs inspect example.com


[OK] VERCEL.JSON - CONFIGURATION

# === Configuration Basique ===

{
  "version": 2,
  "name": "my-project",
  "alias": ["my-app.com", "www.my-app.com"],
  "scope": "team-name"
}

# === Build Configuration ===

{
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "installCommand": "npm install",
  "devCommand": "npm run dev",
  "framework": "nextjs"
}

# === Environnement Variables ===

{
  "env": {
    "API_URL": "https://api.example.com",
    "DATABASE_URL": "@database-url-secret",
    "NEXT_PUBLIC_API_KEY": "abc123"
  },
  "build": {
    "env": {
      "BUILD_MODE": "production"
    }
  }
}

# === Routes & Redirects ===

{
  "routes": [
    {
      "src": "/old-page",
      "dest": "/new-page",
      "status": 301
    },
    {
      "src": "/blog/(.*)",
      "dest": "/posts/$1"
    }
  ]
}

# === Redirects ===

{
  "redirects": [
    {
      "source": "/old/:path*",
      "destination": "/new/:path*",
      "permanent": true
    },
    {
      "source": "/blog/:slug",
      "destination": "/posts/:slug",
      "permanent": false
    }
  ]
}

# === Rewrites ===

{
  "rewrites": [
    {
      "source": "/api/:path*",
      "destination": "https://api.example.com/:path*"
    },
    {
      "source": "/docs/:path*",
      "destination": "/documentation/:path*"
    }
  ]
}

# === Headers ===

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-XSS-Protection",
          "value": "1; mode=block"
        }
      ]
    },
    {
      "source": "/api/:path*",
      "headers": [
        {
          "key": "Access-Control-Allow-Origin",
          "value": "*"
        }
      ]
    }
  ]
}

# === CORS Configuration ===

{
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Access-Control-Allow-Credentials", "value": "true" },
        { "key": "Access-Control-Allow-Origin", "value": "*" },
        { "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
        { "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
      ]
    }
  ]
}

# === Regions ===

{
  "regions": ["iad1", "sfo1"],
  "functions": {
    "api/**/*.js": {
      "memory": 1024,
      "maxDuration": 10,
      "runtime": "nodejs18.x"
    }
  }
}

# Regions disponibles:
# iad1 - Washington DC (US East)
# sfo1 - San Francisco (US West)
# cdg1 - Paris (Europe)
# hnd1 - Tokyo (Asia)
# gru1 - São Paulo (South America)
# all - Toutes les régions


[OK] SERVERLESS FUNCTIONS

# === Structure ===

# API Routes structure
/api
  /hello.js          -> /api/hello
  /user.js           -> /api/user
  /posts/[id].js     -> /api/posts/:id

# === Node.js Functions ===

# api/hello.js
export default function handler(req, res) {
  res.status(200).json({ message: 'Hello World' });
}

# Avec paramètres
export default function handler(req, res) {
  const { name } = req.query;
  res.status(200).json({ message: `Hello ${name}` });
}

# Méthodes HTTP
export default function handler(req, res) {
  if (req.method === 'POST') {
    // Handle POST
    const data = req.body;
    res.status(201).json({ created: data });
  } else if (req.method === 'GET') {
    // Handle GET
    res.status(200).json({ data: [] });
  } else {
    res.status(405).json({ error: 'Method not allowed' });
  }
}

# === Python Functions ===

# api/hello.py
from http.server import BaseHTTPRequestHandler
import json

class handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        self.wfile.write(json.dumps({'message': 'Hello World'}).encode())
        return

# Avec Flask
# api/app.py
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/hello')
def hello():
    return jsonify({'message': 'Hello World'})

# === Go Functions ===

// api/hello.go
package handler

import (
    "encoding/json"
    "net/http"
)

func Handler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(map[string]string{
        "message": "Hello World",
    })
}

# === Ruby Functions ===

# api/hello.rb
Handler = Proc.new do |req, res|
  res.status = 200
  res['Content-Type'] = 'application/json'
  res.body = JSON.generate({ message: 'Hello World' })
end

# === Configuration Functions ===

# vercel.json
{
  "functions": {
    "api/**/*.js": {
      "memory": 1024,
      "maxDuration": 10,
      "runtime": "nodejs18.x"
    },
    "api/**/*.py": {
      "runtime": "python3.9",
      "maxDuration": 60
    }
  }
}

# Runtimes disponibles:
# nodejs18.x, nodejs16.x, nodejs14.x
# python3.9, python3.8
# go1.x
# ruby2.7


[OK] EDGE FUNCTIONS

# === Structure Edge Functions ===

# middleware.js (Next.js 12+)
import { NextResponse } from 'next/server';

export function middleware(request) {
  const response = NextResponse.next();
  response.headers.set('X-Custom-Header', 'value');
  return response;
}

export const config = {
  matcher: '/api/:path*',
};

# === Edge API Routes ===

# pages/api/edge.js
export const config = {
  runtime: 'edge',
};

export default async function handler(req) {
  return new Response(
    JSON.stringify({ message: 'Hello from Edge' }),
    {
      status: 200,
      headers: {
        'content-type': 'application/json',
      },
    }
  );
}

# === Geolocation ===

export default async function handler(req) {
  const { geo } = req;
  
  return new Response(
    JSON.stringify({
      city: geo.city,
      country: geo.country,
      region: geo.region,
      latitude: geo.latitude,
      longitude: geo.longitude,
    }),
    {
      status: 200,
      headers: { 'content-type': 'application/json' },
    }
  );
}

# === A/B Testing ===

import { NextResponse } from 'next/server';

export function middleware(req) {
  const bucket = Math.random() < 0.5 ? 'a' : 'b';
  const url = req.nextUrl.clone();
  url.pathname = `/variants/${bucket}`;
  
  return NextResponse.rewrite(url);
}

# === Authentication ===

import { NextResponse } from 'next/server';

export function middleware(req) {
  const token = req.cookies.get('token');
  
  if (!token) {
    return NextResponse.redirect(new URL('/login', req.url));
  }
  
  return NextResponse.next();
}


[OK] DÉVELOPPEMENT LOCAL

# === Vercel Dev ===

# Lancer serveur de développement
vercel dev

# Port personnalisé
vercel dev --listen 8080
vercel dev -l 3001

# Débug
vercel dev --debug

# Avec environnement spécifique
vercel dev --env-file=.env.local

# === Integration Testing ===

# Test functions localement
vercel dev

# Puis accéder:
# http://localhost:3000/api/hello

# === Hot Reloading ===

# Vercel Dev supporte le hot reloading automatique pour:
# - API Routes
# - Serverless Functions
# - Edge Functions
# - Static files


[OK] FRAMEWORKS SUPPORTÉS

# === Next.js ===

# Détection automatique
vercel

# Configuration manuelle
{
  "framework": "nextjs",
  "buildCommand": "next build",
  "devCommand": "next dev",
  "installCommand": "npm install"
}

# === React (Create React App) ===

{
  "framework": "create-react-app",
  "buildCommand": "react-scripts build",
  "outputDirectory": "build"
}

# === Vue.js ===

{
  "framework": "vue",
  "buildCommand": "vue-cli-service build",
  "outputDirectory": "dist"
}

# === Nuxt.js ===

{
  "framework": "nuxtjs",
  "buildCommand": "nuxt build",
  "devCommand": "nuxt dev"
}

# === Svelte / SvelteKit ===

{
  "framework": "sveltekit",
  "buildCommand": "svelte-kit build",
  "outputDirectory": ".svelte-kit"
}

# === Angular ===

{
  "framework": "angular",
  "buildCommand": "ng build",
  "outputDirectory": "dist"
}

# === Gatsby ===

{
  "framework": "gatsby",
  "buildCommand": "gatsby build",
  "outputDirectory": "public"
}

# === Astro ===

{
  "framework": "astro",
  "buildCommand": "astro build",
  "outputDirectory": "dist"
}

# === Remix ===

{
  "framework": "remix",
  "buildCommand": "remix build",
  "devCommand": "remix dev"
}

# === Vite ===

{
  "framework": "vite",
  "buildCommand": "vite build",
  "outputDirectory": "dist"
}


[OK] GIT INTEGRATION

# === Connecter Repository ===

# Via Dashboard:
# 1. New Project -> Import Git Repository
# 2. Sélectionner GitHub/GitLab/Bitbucket
# 3. Autoriser accès
# 4. Sélectionner repository

# Via CLI:
vercel link

# === Automatic Deployments ===

# Production:
# git push origin main -> déploiement production

# Preview:
# git push origin feature -> preview deployment

# Pull Request:
# Ouvrir PR -> preview deployment automatique

# === Configuration Git ===

# .gitignore
.vercel
.env*.local
node_modules/
dist/
build/

# === Branch Configuration ===

# Production branch (dans Vercel Dashboard):
# Settings -> Git -> Production Branch -> main

# Deploy branches:
# - All branches
# - Only production branch
# - Custom branch pattern

# === Deploy Hooks ===

# Créer webhook (Dashboard):
# Settings -> Git -> Deploy Hooks -> Create Hook

# Déclencher déploiement:
curl -X POST https://api.vercel.com/v1/integrations/deploy/...

# === Ignored Build Step ===

# vercel.json
{
  "git": {
    "deploymentEnabled": {
      "main": true,
      "feature/*": false
    }
  }
}

# Script personnalisé (package.json)
{
  "scripts": {
    "vercel-build": "node check-build.js && next build"
  }
}


[OK] ANALYTICS

# === Vercel Analytics ===

# Next.js - Installation
npm install @vercel/analytics

# pages/_app.js
import { Analytics } from '@vercel/analytics/react';

export default function App({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
      <Analytics />
    </>
  );
}

# === Web Vitals ===

# Activer dans Dashboard:
# Project -> Analytics -> Enable

# Métriques collectées:
# - First Contentful Paint (FCP)
# - Largest Contentful Paint (LCP)
# - First Input Delay (FID)
# - Cumulative Layout Shift (CLS)
# - Time to First Byte (TTFB)

# === Audiences ===

# Filtrer par:
# - Browser
# - Device
# - Country
# - Operating System
# - Referrer

# === Custom Events ===

import { track } from '@vercel/analytics';

track('button_clicked', {
  label: 'signup',
  category: 'engagement'
});


[OK] MONITORING & LOGS

# === Runtime Logs ===

# Voir logs en temps réel
vercel logs URL --follow

# Logs fonction spécifique
vercel logs URL --scope=api/hello

# Filtrer par statut
vercel logs URL --since=1h --status=error

# === Dashboard Monitoring ===

# Accéder: Project -> Monitoring
# - Request volume
# - Error rate
# - Response time
# - Bandwidth usage

# === Integration Logging ===

# DataDog
# Settings -> Integrations -> DataDog

# Sentry
npm install @sentry/nextjs
npx @sentry/wizard -i nextjs

# LogDNA / Mezmo
# Settings -> Integrations -> LogDNA


[OK] SÉCURITÉ

# === Authentification ===

# Protection par mot de passe
# Settings -> Deployment Protection -> Password Protection

# === IP Allowlist ===

# Settings -> Security -> IP Allowlist
# Ajouter IPs autorisées

# === Secure Headers ===

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-XSS-Protection",
          "value": "1; mode=block"
        },
        {
          "key": "Strict-Transport-Security",
          "value": "max-age=31536000; includeSubDomains"
        },
        {
          "key": "Content-Security-Policy",
          "value": "default-src 'self'; script-src 'self' 'unsafe-inline'"
        }
      ]
    }
  ]
}

# === DDoS Protection ===

# Automatique avec Vercel Edge Network

# === Firewall ===

# Settings -> Security -> Firewall
# - Rate limiting
# - Geographic restrictions
# - User agent filtering


[OK] PERFORMANCE OPTIMIZATION

# === Image Optimization ===

# Next.js Image Component
import Image from 'next/image';

<Image
  src="/photo.jpg"
  width={500}
  height={300}
  alt="Photo"
  priority
/>

# Formats automatiques: WebP, AVIF

# === Caching ===

# Headers cache
{
  "headers": [
    {
      "source": "/static/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    }
  ]
}

# === Edge Caching ===

# Automatic avec Vercel CDN
# - Static assets: permanent cache
# - API responses: configurable

# === Compression ===

# Automatique:
# - Brotli
# - Gzip

# === Prerendering ===

# Static Generation (Next.js)
export async function getStaticProps() {
  return {
    props: { data },
    revalidate: 60, // ISR
  };
}


[OK] CI/CD INTEGRATION

# === GitHub Actions ===

# .github/workflows/deploy.yml
name: Deploy to Vercel
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
      - run: npm install
      - run: npm run build
      - uses: amondnet/vercel-action@v20
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.ORG_ID }}
          vercel-project-id: ${{ secrets.PROJECT_ID }}
          vercel-args: '--prod'

# === GitLab CI ===

# .gitlab-ci.yml
deploy:
  stage: deploy
  script:
    - npm install -g vercel
    - vercel --token=$VERCEL_TOKEN --prod --yes
  only:
    - main

# === CircleCI ===

# .circleci/config.yml
version: 2.1
jobs:
  deploy:
    docker:
      - image: circleci/node:latest
    steps:
      - checkout
      - run: npm install -g vercel
      - run: vercel --token=$VERCEL_TOKEN --prod --yes


[OK] BASES DE DONNÉES

# === Vercel Postgres ===

# Créer database
# Dashboard -> Storage -> Create Database -> Postgres

# Installation SDK
npm install @vercel/postgres

# Utilisation
import { sql } from '@vercel/postgres';

export default async function handler(req, res) {
  const { rows } = await sql`SELECT * FROM users`;
  res.json(rows);
}

# === Vercel KV (Redis) ===

# Installation
npm install @vercel/kv

# Utilisation
import { kv } from '@vercel/kv';

export default async function handler(req, res) {
  await kv.set('key', 'value');
  const value = await kv.get('key');
  res.json({ value });
}

# === Vercel Blob ===

# Upload fichiers
npm install @vercel/blob

import { put } from '@vercel/blob';

export default async function handler(req, res) {
  const blob = await put('avatar.png', file, {
    access: 'public',
  });
  res.json({ url: blob.url });
}

# === Vercel Edge Config ===

# Configuration edge
npm install @vercel/edge-config

import { get } from '@vercel/edge-config';

export const config = { runtime: 'edge' };

export default async function handler(req) {
  const value = await get('feature-flag');
  return new Response(JSON.stringify({ value }));
}


[OK] PRICING & LIMITS

# === Plan Hobby (Gratuit) ===
# [OK] Bandwidth: 100 GB/mois
# [OK] Serverless function executions: 100 GB-Hrs
# [OK] Serverless function duration: 10s max
# [OK] Deployments: Illimité
# [OK] Team members: 1
# [OK] Commercial use: Non

# === Plan Pro ($20/mois) ===
# [OK] Bandwidth: 1 TB/mois
# [OK] Serverless function executions: 1000 GB-Hrs
# [OK] Serverless function duration: 60s max
# [OK] Team members: Illimité
# [OK] Analytics: Avancé
# [OK] Commercial use: Oui

# === Plan Enterprise (Custom) ===
# [OK] Bandwidth: Custom
# [OK] SLA 99.99%
# [OK] Support prioritaire
# [OK] Single Sign-On (SSO)
# [OK] Audit logs


[OK] BONNES PRATIQUES

# 1. Utiliser variables d'environnement
# - Ne jamais commit secrets
# - Utiliser .env.local pour développement
# - Utiliser Vercel secrets pour production

# 2. Optimiser images
# - Utiliser Next.js Image component
# - Formats modernes (WebP, AVIF)
# - Lazy loading automatique

# 3. Caching stratégique
# - Static assets: cache permanent
# - API responses: cache approprié
# - Utiliser ISR pour contenu dynamique

# 4. Sécurité headers
# - CSP, HSTS, X-Frame-Options
# - CORS configuration
# - Rate limiting API

# 5. Monitoring
# - Analytics activés
# - Logs monitoring
# - Error tracking (Sentry)

# 6. Preview deployments
# - Tester avant production
# - Review dans PR
# - QA sur preview URLs

# 7. Edge Functions
# - Utiliser pour latence minimale
# - Geolocation personnalisation
# - A/B testing

# 8. Structure projet
# - Séparer code frontend/backend
# - API routes organisées
# - Environment variables bien gérées

# 9. Git workflow
# - main/master -> production
# - develop -> preview
# - feature branches -> preview

# 10. Performance
# - Code splitting
# - Tree shaking
# - Compression activée


[OK] DÉPANNAGE DÉBUTANT - PROBLÈMES COURANTS

# PROBLÈME 1: "Command not found: vercel"

# Cause: CLI pas installé ou pas dans PATH

# Solutions:
# 1. Vérifier installation
npm list -g vercel

# 2. Réinstaller
npm uninstall -g vercel
npm install -g vercel

# 3. Utiliser npx (sans installation)
npx vercel

# 4. Vérifier PATH (Linux/Mac)
echo $PATH
# Doit contenir: /usr/local/bin ou ~/.npm-global/bin

# 5. Redémarrer terminal


# PROBLÈME 2: Build échoue avec "Module not found"

# Cause: Dépendance manquante ou mauvais import

# Solutions:
# 1. Vérifier package.json contient toutes dépendances
npm install  # Installe tout

# 2. Si module utilisé mais pas dans package.json:
npm install nom-du-module --save

# 3. Vérifier import path
# [X] Mauvais: import './Component'  (manque extension)
# [OK] Bon: import './Component.js'

# 4. Tester build localement AVANT déployer
npm run build

# 5. Voir logs build dans Vercel
vercel logs URL


# PROBLÈME 3: "Error: No package.json found"

# Cause: Vous êtes dans mauvais dossier

# Solutions:
# 1. Vérifier vous êtes dans bon dossier
pwd  # Affiche dossier actuel
ls   # Liste fichiers (package.json doit être présent)

# 2. Naviguer vers bon dossier
cd mon-projet

# 3. Pour site HTML statique (pas de package.json):
# -> PAS BESOIN de package.json!
# -> vercel déploie directement les fichiers HTML


# PROBLÈME 4: Variables d'environnement non définies

# Symptôme: process.env.MA_VARIABLE est undefined

# Cause: Variable pas ajoutée dans Vercel

# Solutions:
# 1. Vérifier variables définies
vercel env ls

# 2. Ajouter variable
vercel env add MA_VARIABLE production

# 3. Pull variables localement
vercel env pull

# 4. Redéployer (variables appliquées au build)
vercel --prod --force

# 5. Vérifier nom variable
# React: DOIT commencer par REACT_APP_
# Next.js: NEXT_PUBLIC_ pour variables client-side


# PROBLÈME 5: "This deployment was not found"

# Cause: URL incorrecte ou déploiement supprimé

# Solutions:
# 1. Vérifier URL exacte
vercel ls  # Liste tous déploiements

# 2. Utiliser URL production (pas preview)
# Preview: mon-projet-abc123.vercel.app (temporaire)
# Production: mon-projet.vercel.app (permanent)

# 3. Si supprimé, redéployer
vercel --prod


# PROBLÈME 6: Serverless function retourne 404

# Cause: Mauvais emplacement fichier ou export

# Solutions:
# 1. Vérifier structure dossiers
# Fichier DOIT être dans: api/
mon-projet/
├── api/
│   └── hello.js  # [OK] Correct
└── hello.js      # [X] Pas accessible

# 2. Vérifier export
# [X] Mauvais:
function handler() {}

# [OK] Bon:
export default function handler(req, res) {}

# 3. Redéployer après modification
vercel --prod


# PROBLÈME 7: CORS error dans navigateur

# Symptôme: "Access-Control-Allow-Origin" error

# Cause: Frontend et API sur domaines différents

# Solution: Ajouter headers CORS dans vercel.json
{
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        {
          "key": "Access-Control-Allow-Origin",
          "value": "*"
        },
        {
          "key": "Access-Control-Allow-Methods",
          "value": "GET,POST,PUT,DELETE,OPTIONS"
        }
      ]
    }
  ]
}

# Redéployer:
vercel --prod


# PROBLÈME 8: Fonction timeout (erreur 504)

# Cause: Fonction prend trop de temps

# Solutions:
# 1. Optimiser code (requêtes parallèles)
# Avant:
const a = await fetch(url1);
const b = await fetch(url2);  // Attend a finisse

# Après:
const [a, b] = await Promise.all([
  fetch(url1),
  fetch(url2)  // Parallèle!
]);

# 2. Augmenter timeout (vercel.json)
{
  "functions": {
    "api/**/*.js": {
      "maxDuration": 60  # Max 60s (Pro plan)
    }
  }
}

# 3. Si vraiment long, utiliser queue externe
# (ex: Vercel KV, Redis Queue)


# PROBLÈME 9: "Cannot find module '@vercel/postgres'"

# Cause: Package pas installé

# Solution:
npm install @vercel/postgres
git add package.json package-lock.json
git commit -m "Add postgres"
git push

# Vercel réinstalle automatiquement au prochain déploiement


# PROBLÈME 10: Domaine ne fonctionne pas

# Cause: DNS pas configuré ou propagation en cours

# Solutions:
# 1. Vérifier configuration DNS
# Dans Vercel: Project -> Settings -> Domains
# Copier exactement les valeurs affichées

# 2. Vérifier chez registrar (Namecheap, etc.)
# DNS Records doivent correspondre EXACTEMENT

# 3. Attendre propagation (jusqu'à 48h)
# Tester propagation: https://dnschecker.org

# 4. Forcer refresh certificat SSL
vercel certs issue mondomaine.com


# PROBLÈME 11: "Permission denied" lors login

# Cause: Problème authentification GitHub

# Solutions:
# 1. Logout et re-login
vercel logout
vercel login

# 2. Révoquer et réautoriser
# GitHub -> Settings -> Applications -> Vercel -> Revoke
# Puis vercel login

# 3. Utiliser email au lieu de GitHub
vercel login user@example.com


# PROBLÈME 12: Build réussit localement mais échoue sur Vercel

# Causes possibles:
# 1. Node version différente
# 2. Dépendances dev manquantes
# 3. Variables environnement manquantes

# Solutions:
# 1. Spécifier Node version (package.json)
{
  "engines": {
    "node": "18.x"
  }
}

# 2. Vérifier dependencies vs devDependencies
# Si utilisé au build: dependencies
# Si seulement dev local: devDependencies

# 3. Ajouter toutes variables nécessaires
vercel env add

# 4. Voir logs complets
vercel logs URL --since 1h


# PROBLÈME 13: Images ne s'affichent pas

# Cause: Chemin incorrect ou images non déployées

# Solutions:
# 1. Vérifier chemins relatifs
# [X] Mauvais: src="/images/logo.png" (absolu)
# [OK] Bon: src="./images/logo.png" (relatif)

# 2. Vérifier images dans dossier public/ (React/Next.js)
public/
└── images/
    └── logo.png

# Utiliser: src="/images/logo.png" (commence par /)

# 3. Vérifier .gitignore n'exclut pas images
# [X] Ne devrait PAS avoir: *.png

# 4. Redéployer avec --force
vercel --prod --force


# PROBLÈME 14: Git push ne déclenche pas déploiement

# Cause: Intégration Git pas configurée

# Solutions:
# 1. Vérifier intégration existe
# Vercel Dashboard -> Project -> Settings -> Git

# 2. Reconnecter repository
# Settings -> Git -> Disconnect -> Import Git Repository

# 3. Vérifier branche déploiement
# Settings -> Git -> Production Branch
# Doit être: main (ou master)

# 4. Vérifier webhook GitHub
# GitHub repo -> Settings -> Webhooks
# Doit y avoir webhook Vercel actif


# PROBLÈME 15: Déploiement lent (>5 minutes)

# Causes: Build lourd, dépendances nombreuses

# Solutions:
# 1. Vérifier temps build localement
time npm run build

# 2. Optimiser dépendances
# Supprimer packages inutilisés:
npm prune

# 3. Utiliser cache
# Vercel cache automatiquement node_modules
# Mais réinstalle si package.json change

# 4. Réduire taille bundle
# Analyser:
npm run build -- --analyze  # Next.js

# 5. Split code par routes


# COMMANDES UTILES DÉPANNAGE

# Voir tous déploiements
vercel ls

# Logs détaillés
vercel logs URL --follow

# Inspecter déploiement
vercel inspect URL

# Forcer nouveau build
vercel --prod --force

# Pull configuration
vercel pull

# Vérifier connexion
vercel whoami

# Lister variables
vercel env ls

# Supprimer déploiement raté
vercel rm URL

# Rollback vers version précédente
vercel rollback


[OK] INSTALLATION & CONFIGURATION

# === Installation Vercel CLI ===

# Avec npm (recommandé)
npm install -g vercel

# EXPLICATION:
# -g = global (accessible partout dans terminal)
# Sans -g: installé seulement dans projet actuel

# Tester build localement
vercel dev
npm run build

# Vérifier node version
# vercel.json
{
  "build": {
    "env": {
      "NODE_VERSION": "18"
    }
  }
}

# === Erreur: Function Timeout ===

# Augmenter maxDuration
{
  "functions": {
    "api/**/*.js": {
      "maxDuration": 60
    }
  }
}

# === Erreur: Module Not Found ===

# Vérifier package.json
npm install package-name

# Vérifier import path
# Relatif: import './module'
# Absolu: import 'package'

# === Erreur: Environment Variables ===

# Pull variables localement
vercel env pull

# Vérifier dans dashboard
# Project -> Settings -> Environment Variables

# Rebuild déploiement
vercel --force

# === Erreur: CORS ===

# Ajouter headers CORS
{
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Access-Control-Allow-Origin", "value": "*" },
        { "key": "Access-Control-Allow-Methods", "value": "GET,POST,PUT,DELETE" }
      ]
    }
  ]
}

# === Erreur: Domain Not Working ===

# Vérifier DNS
vercel dns ls domain.com

# Vérifier certificat
vercel certs inspect domain.com

# Attendre propagation DNS (24-48h)

# === Erreur: Rate Limited ===

# Vérifier limites plan
# Dashboard -> Usage

# Upgrade plan si nécessaire
# Dashboard -> Settings -> Billing

# === Erreur: Git Integration ===

# Reconnect repository
# Settings -> Git -> Disconnect -> Reconnect

# Vérifier permissions GitHub/GitLab
# Settings -> Installed GitHub Apps

# === Cache Issues ===

# Clear build cache
vercel --force

# Clear browser cache
# Hard refresh: Ctrl+Shift+R (Windows/Linux)
# Hard refresh: Cmd+Shift+R (Mac)


[OK] VERCEL CLI - COMMANDES COMPLÈTES

# === help ===
vercel help
vercel help deploy
vercel help env

# === bisect ===
vercel bisect              # Trouver déploiement problématique

# === build ===
vercel build               # Build localement
vercel build --prod
vercel build --debug

# === dev ===
vercel dev                 # Serveur dev local
vercel dev --listen 8080
vercel dev --debug

# === deploy ===
vercel deploy              # Déployer
vercel deploy --prod
vercel deploy --yes
vercel deploy --force
vercel deploy --public
vercel deploy --no-wait

# === domains ===
vercel domains ls
vercel domains add domain.com
vercel domains rm domain.com
vercel domains inspect domain.com
vercel domains buy domain.com

# === dns ===
vercel dns ls domain.com
vercel dns add domain.com
vercel dns rm record-id

# === env ===
vercel env ls
vercel env add KEY
vercel env rm KEY
vercel env pull

# === git ===
vercel git connect
vercel git disconnect

# === init ===
vercel init                # Nouveau projet
vercel init next
vercel init react

# === inspect ===
vercel inspect URL         # Détails déploiement

# === link ===
vercel link                # Lier projet

# === list / ls ===
vercel ls                  # Lister déploiements
vercel ls --next 20
vercel ls my-project

# === login ===
vercel login
vercel login email@example.com
vercel login --github

# === logout ===
vercel logout

# === logs ===
vercel logs URL
vercel logs URL --follow
vercel logs URL --since 1h

# === projects ===
vercel projects ls
vercel projects add
vercel projects rm project-name

# === promote ===
vercel promote URL         # Promouvoir en prod

# === pull ===
vercel pull                # Pull configuration
vercel pull --environment=production

# === remove / rm ===
vercel rm URL              # Supprimer déploiement
vercel rm project-name --yes

# === rollback ===
vercel rollback            # Rollback déploiement
vercel rollback URL

# === secrets ===
vercel secrets ls
vercel secrets add name value
vercel secrets rm name
vercel secrets rename old new

# === switch ===
vercel switch              # Changer team/scope
vercel switch team-name

# === teams ===
vercel teams ls
vercel teams add
vercel teams invite email@example.com

# === whoami ===
vercel whoami              # Utilisateur actuel


[OK] EXEMPLES PRATIQUES

# === Déployer Site Statique Simple ===

# 1. Créer projet
mkdir my-site && cd my-site
echo "<h1>Hello Vercel</h1>" > index.html

# 2. Déployer
vercel

# 3. Production
vercel --prod

# === Déployer Next.js App ===

# 1. Créer app
npx create-next-app@latest my-app
cd my-app

# 2. Configurer
# vercel.json
{
  "framework": "nextjs",
  "buildCommand": "next build",
  "devCommand": "next dev"
}

# 3. Déployer
vercel --prod

# === API REST avec Node.js ===

# api/users.js
export default async function handler(req, res) {
  const { method } = req;
  
  switch (method) {
    case 'GET':
      // Fetch users
      const users = await fetchUsers();
      res.status(200).json(users);
      break;
      
    case 'POST':
      // Create user
      const newUser = await createUser(req.body);
      res.status(201).json(newUser);
      break;
      
    case 'PUT':
      // Update user
      const updated = await updateUser(req.query.id, req.body);
      res.status(200).json(updated);
      break;
      
    case 'DELETE':
      // Delete user
      await deleteUser(req.query.id);
      res.status(204).end();
      break;
      
    default:
      res.setHeader('Allow', ['GET', 'POST', 'PUT', 'DELETE']);
      res.status(405).end(`Method ${method} Not Allowed`);
  }
}

# === Webhook Handler ===

# api/webhook.js
import crypto from 'crypto';

export default async function handler(req, res) {
  // Vérifier signature
  const signature = req.headers['x-signature'];
  const body = JSON.stringify(req.body);
  const hash = crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(body)
    .digest('hex');
  
  if (signature !== hash) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  // Traiter webhook
  const { event, data } = req.body;
  
  switch (event) {
    case 'user.created':
      await handleUserCreated(data);
      break;
    case 'order.completed':
      await handleOrderCompleted(data);
      break;
  }
  
  res.status(200).json({ received: true });
}

# === Proxy API ===

# api/proxy/[...path].js
export default async function handler(req, res) {
  const { path } = req.query;
  const apiPath = path.join('/');
  
  const response = await fetch(
    `https://api.example.com/${apiPath}`,
    {
      method: req.method,
      headers: {
        'Authorization': `Bearer ${process.env.API_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: req.method !== 'GET' ? JSON.stringify(req.body) : undefined,
    }
  );
  
  const data = await response.json();
  res.status(response.status).json(data);
}

# === Authentication Middleware ===

# middleware.js
import { NextResponse } from 'next/server';
import { verify } from 'jsonwebtoken';

export function middleware(req) {
  const token = req.cookies.get('token')?.value;
  
  if (!token) {
    return NextResponse.redirect(new URL('/login', req.url));
  }
  
  try {
    const decoded = verify(token, process.env.JWT_SECRET);
    
    // Ajouter user info dans headers
    const requestHeaders = new Headers(req.headers);
    requestHeaders.set('x-user-id', decoded.userId);
    
    return NextResponse.next({
      request: {
        headers: requestHeaders,
      },
    });
  } catch (error) {
    return NextResponse.redirect(new URL('/login', req.url));
  }
}

export const config = {
  matcher: ['/dashboard/:path*', '/api/protected/:path*'],
};

# === Rate Limiting ===

# api/limited.js
const rateLimit = new Map();

export default function handler(req, res) {
  const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
  const now = Date.now();
  const windowMs = 60 * 1000; // 1 minute
  const maxRequests = 10;
  
  if (!rateLimit.has(ip)) {
    rateLimit.set(ip, []);
  }
  
  const requests = rateLimit.get(ip).filter(time => now - time < windowMs);
  
  if (requests.length >= maxRequests) {
    return res.status(429).json({
      error: 'Too many requests',
      retryAfter: Math.ceil((requests[0] + windowMs - now) / 1000),
    });
  }
  
  requests.push(now);
  rateLimit.set(ip, requests);
  
  res.status(200).json({ message: 'Success' });
}

# === Image Upload ===

# api/upload.js
import { put } from '@vercel/blob';

export const config = {
  api: {
    bodyParser: {
      sizeLimit: '10mb',
    },
  },
};

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }
  
  const { filename, file } = req.body;
  
  // Upload vers Vercel Blob
  const blob = await put(filename, file, {
    access: 'public',
    addRandomSuffix: true,
  });
  
  res.status(200).json({
    url: blob.url,
    pathname: blob.pathname,
  });
}

# === Scheduled Task (Cron) ===

# vercel.json
{
  "crons": [
    {
      "path": "/api/cron/daily",
      "schedule": "0 0 * * *"
    },
    {
      "path": "/api/cron/hourly",
      "schedule": "0 * * * *"
    }
  ]
}

# api/cron/daily.js
export default async function handler(req, res) {
  // Vérifier que c'est un cron Vercel
  if (req.headers['x-vercel-cron'] !== process.env.CRON_SECRET) {
    return res.status(401).end();
  }
  
  // Exécuter tâche quotidienne
  await performDailyTask();
  
  res.status(200).json({ success: true });
}

# === Email avec Resend ===

# api/send-email.js
import { Resend } from 'resend';

const resend = new Resend(process.env.RESEND_API_KEY);

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }
  
  const { to, subject, html } = req.body;
  
  try {
    const data = await resend.emails.send({
      from: 'hello@example.com',
      to,
      subject,
      html,
    });
    
    res.status(200).json(data);
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
}

# === Database Connection ===

# api/db/users.js
import { sql } from '@vercel/postgres';

export default async function handler(req, res) {
  try {
    const { rows } = await sql`
      SELECT id, name, email, created_at
      FROM users
      WHERE active = true
      ORDER BY created_at DESC
      LIMIT 100
    `;
    
    res.status(200).json(rows);
  } catch (error) {
    res.status(500).json({ error: 'Database error' });
  }
}

# === Redis Cache ===

# api/cache/[key].js
import { kv } from '@vercel/kv';

export default async function handler(req, res) {
  const { key } = req.query;
  
  if (req.method === 'GET') {
    const value = await kv.get(key);
    if (!value) {
      return res.status(404).json({ error: 'Not found' });
    }
    res.status(200).json({ value });
  } else if (req.method === 'POST') {
    const { value, ttl } = req.body;
    await kv.set(key, value, { ex: ttl || 3600 });
    res.status(201).json({ success: true });
  } else if (req.method === 'DELETE') {
    await kv.del(key);
    res.status(204).end();
  }
}


[OK] INTÉGRATIONS POPULAIRES

# === Stripe ===
npm install stripe

# api/stripe/checkout.js
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

export default async function handler(req, res) {
  const session = await stripe.checkout.sessions.create({
    line_items: [
      {
        price: 'price_xxx',
        quantity: 1,
      },
    ],
    mode: 'payment',
    success_url: `${req.headers.origin}/success`,
    cancel_url: `${req.headers.origin}/cancel`,
  });
  
  res.redirect(303, session.url);
}

# === Auth0 ===
npm install @auth0/nextjs-auth0

# pages/api/auth/[...auth0].js
import { handleAuth } from '@auth0/nextjs-auth0';

export default handleAuth();

# === Supabase ===
npm install @supabase/supabase-js

# lib/supabase.js
import { createClient } from '@supabase/supabase-js';

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);

# === Prisma ===
npm install prisma @prisma/client

# Initialize
npx prisma init

# Generate client
npx prisma generate

# api/users.js
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();

export default async function handler(req, res) {
  const users = await prisma.user.findMany();
  res.json(users);
}

# === Firebase ===
npm install firebase-admin

# lib/firebase.js
import admin from 'firebase-admin';

if (!admin.apps.length) {
  admin.initializeApp({
    credential: admin.credential.cert({
      projectId: process.env.FIREBASE_PROJECT_ID,
      clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
      privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'),
    }),
  });
}

export default admin;

# === SendGrid ===
npm install @sendgrid/mail

# api/send-email.js
import sgMail from '@sendgrid/mail';

sgMail.setApiKey(process.env.SENDGRID_API_KEY);

export default async function handler(req, res) {
  const msg = {
    to: 'recipient@example.com',
    from: 'sender@example.com',
    subject: 'Hello',
    text: 'Hello world',
  };
  
  await sgMail.send(msg);
  res.status(200).json({ success: true });
}

# === Algolia ===
npm install algoliasearch

# api/search.js
import algoliasearch from 'algoliasearch';

const client = algoliasearch(
  process.env.ALGOLIA_APP_ID,
  process.env.ALGOLIA_API_KEY
);
const index = client.initIndex('products');

export default async function handler(req, res) {
  const { query } = req.query;
  const results = await index.search(query);
  res.json(results);
}

# === Cloudinary ===
npm install cloudinary

# api/upload-image.js
import { v2 as cloudinary } from 'cloudinary';

cloudinary.config({
  cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET,
});

export default async function handler(req, res) {
  const result = await cloudinary.uploader.upload(req.body.image);
  res.json({ url: result.secure_url });
}


[OK] MIGRATION VERS VERCEL

# === Depuis Netlify ===

# 1. Exporter variables environnement
netlify env:list

# 2. Import dans Vercel
vercel env add KEY

# 3. Adapter configuration
# netlify.toml -> vercel.json

# 4. Redirects
[[redirects]]
  from = "/old"
  to = "/new"
  status = 301

# Devient:
{
  "redirects": [
    {
      "source": "/old",
      "destination": "/new",
      "permanent": true
    }
  ]
}

# === Depuis Heroku ===

# 1. Adapter Procfile
# web: npm start

# Devient package.json:
{
  "scripts": {
    "start": "node server.js"
  }
}

# 2. Variables environnement
heroku config -a my-app

# Import dans Vercel
vercel env add

# 3. Buildpacks -> vercel.json
{
  "builds": [
    {
      "src": "package.json",
      "use": "@vercel/node"
    }
  ]
}

# === Depuis AWS ===

# 1. S3 static -> Vercel
# Upload dist folder:
vercel ./dist

# 2. Lambda -> Serverless Functions
# Adapter handlers AWS -> Vercel format

# 3. CloudFront -> Vercel CDN
# Configuration automatique


[OK] RESSOURCES

# Documentation officielle:
# https://vercel.com/docs

# CLI Reference:
# https://vercel.com/docs/cli

# Templates:
# https://vercel.com/templates

# Guides:
# https://vercel.com/guides

# API Reference:
# https://vercel.com/docs/rest-api

# Support:
# https://vercel.com/support

# Status:
# https://vercel-status.com

# Blog:
# https://vercel.com/blog

# Community:
# https://github.com/vercel/vercel/discussions


[OK] COMMANDES RAPIDES (AIDE-MÉMOIRE)

# Setup
vercel login
vercel link

# Développement
vercel dev
vercel dev --listen 3001

# Déploiement
vercel                      # Preview
vercel --prod              # Production
vercel --force             # Force rebuild

# Variables
vercel env add KEY
vercel env pull
vercel env ls

# Logs
vercel logs URL
vercel logs URL -f

# Projets
vercel ls
vercel projects ls
vercel rm URL

# Domaines
vercel domains add domain.com
vercel domains ls

# Configuration
vercel pull
vercel whoami
vercel switch

# Inspection
vercel inspect URL
vercel logs URL --since 1h