Site de campagne électorale pour les élections municipales 2026 à La Chapelle de la Tour.
- Framework: Next.js 16 (App Router)
- Styling: TailwindCSS
- CMS: Prismic
- Deployment: Vercel
- Language: TypeScript
- Node.js 18+
- npm ou yarn
- Un compte Prismic (gratuit)
- Un compte Vercel (gratuit)
- Cloner le projet
cd chapelle-tour-2026
npm install- Configurer Prismic
- Aller sur prismic.io et créer un compte
- Créer un nouveau repository nommé
chapelle-tour-2026 - Dans Prismic, aller dans Settings → Custom Types
- Créer un Single Type nommé
homepageavec les slices suivants :- Hero
- Team
- Contact
- Les modèles JSON des slices sont dans
/slices/*/model.json
- Configurer les variables d'environnement
cp .env.example .envÉditer .env avec les valeurs suivantes :
# Prismic
NEXT_PUBLIC_PRISMIC_ENVIRONMENT=chapelle-tour-2026 # Nom de votre repository Prismic
# Webhook Prismic (sécurité)
# Générer avec : openssl rand -base64 32
PRISMIC_WEBHOOK_SECRET=your_webhook_secret_here
# Resend (envoi d'emails)
# Obtenir sur : https://resend.com/api-keys
RESEND_API_KEY=your_resend_api_key_here
# Email de destination pour le formulaire de contact
CONTACT_EMAIL=contact@lachapelledelatour2026.fr
# URL de votre site (pour protection CSRF)
NEXT_PUBLIC_SITE_URL=https://lachapelledelatour2026.frGénérer le secret webhook :
openssl rand -base64 32Copier le résultat dans PRISMIC_WEBHOOK_SECRET.
- Configurer Resend (envoi d'emails)
- Créer un compte sur resend.com
- Aller dans API Keys et créer une nouvelle clé
- Copier la clé dans
RESEND_API_KEYde votre.env - Vérifier votre domaine d'envoi (ou utiliser le domaine de test)
- Configurer le webhook Prismic (pour le cache)
Une fois déployé sur Vercel :
- Aller dans Prismic → Settings → Webhooks
- Cliquer sur Create a webhook
- Name: "Cache Revalidation"
- URL:
https://votre-domaine.fr/api/revalidate - Secret: Copier votre
PRISMIC_WEBHOOK_SECRET - Ajouter le header personnalisé :
- Name:
Authorization - Value:
Bearer VOTRE_PRISMIC_WEBHOOK_SECRET
- Name:
- Triggers: Cocher "A document is published" et "A document is unpublished"
- Sauvegarder
- Lancer le serveur de développement
npm run devOuvrir http://localhost:3000 dans votre navigateur.
Dans Prismic, créer un Single Type avec :
API ID: homepage
Slices Zone: Ajouter les slices suivants :
- Hero (pour la bannière principale)
- Team (pour la liste électorale)
- Contact (pour le formulaire de contact)
- Title: "Ensemble pour La Chapelle de la Tour"
- Description: Votre slogan de campagne
- Background Image: Photo de la commune (optionnel)
- Logo: Logo de votre liste (optionnel)
- CTA Text: "Découvrir notre équipe"
- Section Title: "Notre équipe"
- Section Description: Présentation de votre liste
- Team Members: Ajoutez chaque membre avec :
- Nom complet
- Rôle (Tête de liste, Adjoint, etc.)
- Photo (format carré recommandé)
- Courte biographie
- Section Title: "Contactez-nous"
- Section Description: "Une question ? N'hésitez pas à nous écrire"
- Email: Votre email de campagne
- Phone: Numéro de téléphone (optionnel)
- Submit Button Text: "Envoyer"
- Aller sur vercel.com
- Cliquer sur "New Project"
- Importer votre repository Git
- Configurer les variables d'environnement :
NEXT_PUBLIC_PRISMIC_ENVIRONMENT= votre repository Prismic
- Déployer
# Installer Vercel CLI
npm i -g vercel
# Déployer
vercel
# Suivre les instructions
# Configurer les variables d'environnement quand demandéDans les Project Settings → Environment Variables, ajouter :
| Variable | Valeur | Environment |
|---|---|---|
NEXT_PUBLIC_PRISMIC_ENVIRONMENT |
chapelle-tour-2026 |
Production, Preview, Development |
PRISMIC_WEBHOOK_SECRET |
Générer avec openssl rand -base64 32 |
Production, Preview |
RESEND_API_KEY |
Votre clé API Resend | Production, Preview |
CONTACT_EMAIL |
contact@lachapelledelatour2026.fr |
Production, Preview, Development |
NEXT_PUBLIC_SITE_URL |
https://lachapelledelatour2026.fr |
Production |
NEXT_PUBLIC_SITE_URL |
https://votre-preview.vercel.app |
Preview |
Important : Après avoir ajouté les variables, redéployer le site pour qu'elles soient prises en compte.
npm run dev # Lancer le serveur de développement
npm run build # Build de production
npm run start # Lancer le serveur de production
npm run lint # Vérifier le code
npm run lint:fix # Corriger automatiquement les erreurs
npm run format # Formater le code avec PrettierLes couleurs principales sont dans tailwind.config.ts. Par défaut :
- Primaire: Indigo (bleu)
- Pour changer, modifier les classes
indigo-*dans les composants
La police par défaut est system (Arial/Helvetica). Pour personnaliser :
- Ajouter une Google Font dans
app/layout.tsx - Mettre à jour
app/globals.css
chapelle-tour-2026/
├── app/ # Pages Next.js (App Router)
│ ├── layout.tsx # Layout principal
│ ├── page.tsx # Page d'accueil
│ └── globals.css # Styles globaux
├── slices/ # Composants Prismic Slices
│ ├── Hero/
│ ├── Team/
│ └── Contact/
├── public/ # Fichiers statiques
├── prismicio.ts # Configuration Prismic
└── slicemachine.config.json
Le site implémente plusieurs couches de protection contre les vulnérabilités web courantes (OWASP Top 10) :
| Header | Protection | Description |
|---|---|---|
| Content-Security-Policy | XSS, injection de code | Contrôle les sources autorisées (scripts, images, styles) |
| Strict-Transport-Security | Man-in-the-Middle | Force HTTPS pendant 1 an (HSTS) |
| X-Frame-Options | Clickjacking | Empêche l'affichage du site dans une iframe externe |
| X-Content-Type-Options | MIME Sniffing | Force le respect du Content-Type déclaré |
| X-XSS-Protection | XSS (navigateurs legacy) | Active le filtre XSS des anciens navigateurs |
| Referrer-Policy | Fuite d'informations | Contrôle les infos envoyées dans le header Referer |
| Permissions-Policy | Abus de permissions | Désactive caméra, micro, géolocalisation |
- ✅ Authentification Bearer token
- ✅ Protection contre DoS (spam de revalidation)
- ✅ Vérification du secret webhook
- ✅ CSRF Protection : Validation de l'origine de la requête
- ✅ Email Injection : Blocage des caractères CRLF (
\r\n) - ✅ Sanitisation : Nettoyage HTML et limitation de longueur
- ✅ Rate Limiting : Client-side (5 soumissions/15 min)
- ❌ Jamais commité dans Git (
.envdans.gitignore) - ✅ Fichier
.env.exampleavec placeholders génériques - ✅ Validation Zod au runtime
- ✅ TypeScript strict mode activé
- ✅ ESLint avec règles de sécurité
- Respect de la norme RFC 5321 pour les emails (max 254 caractères)
- Validation stricte avec Zod sur tous les inputs utilisateurs
- Subject email fixe (pas de contenu utilisateur)
- Pas de
anyen TypeScript - Aucune dépendance avec vulnérabilité connue (
npm auditclean)
Pour vérifier les headers en production :
curl -I https://lachapelledelatour2026.frVous devriez voir tous les headers de sécurité listés ci-dessus.
Cause : Variable PRISMIC_WEBHOOK_SECRET manquante
Solution :
# Générer un secret
openssl rand -base64 32
# L'ajouter dans .env
echo "PRISMIC_WEBHOOK_SECRET=votre_secret_genere" >> .envCause : Protection CSRF active, l'origine de la requête n'est pas autorisée
Solution :
- Vérifier que
NEXT_PUBLIC_SITE_URLcorrespond à votre domaine - En développement local, mettre
http://localhost:3000 - En production, mettre
https://votre-domaine.fr
Cause : L'email contient des retours à la ligne (\r ou \n)
Solution : C'est normal, c'est une protection contre l'injection d'en-têtes. Vérifier que l'email est bien formaté.
Vérifier :
- Le secret est bien configuré dans Prismic (Settings → Webhooks)
- Le header
Authorization: Bearer VOTRE_SECRETest bien ajouté - L'URL du webhook est correcte :
https://votre-domaine.fr/api/revalidate - Tester le webhook manuellement :
curl -X POST https://votre-domaine.fr/api/revalidate \
-H "Authorization: Bearer VOTRE_SECRET"
# Réponse attendue : {"revalidated":true,"now":1234567890}Si vous voyez des erreurs CSP dans la console :
- Identifier la source bloquée dans l'erreur
- Ajouter le domaine dans
next.config.ts:
// Exemple pour autoriser un nouveau CDN
"img-src 'self' data: https://images.prismic.io https://nouveau-cdn.com",- Redémarrer le serveur de développement
Projet open-source pour usage électoral.
Pour toute question :
- Email : [votre-email]
- Issues GitHub : [lien-vers-repo]
Bonne campagne ! 🎉