Retour aux projets
Dcover — Conception et développement d'un site vitrine pour un spécialiste du covering automobile

Dcover — Conception et développement d'un site vitrine pour un spécialiste du covering automobile

16 mars 2026
11 min de lecture

Introduction

Dcover est un projet de site vitrine réalisé pour un professionnel du covering automobile. L'objectif : concevoir une plateforme moderne, immersive et performante qui reflète le haut de gamme des prestations proposées — covering, protection PPF et traitement céramique.

Le site a été développé avec Next.js 14 (App Router), TypeScript, Tailwind CSS et Framer Motion pour le front-end, tandis que tout le contenu est géré dynamiquement via un back-office Strapi (headless CMS). Ce choix d'architecture permet au client de modifier l'intégralité du site sans toucher au code.

Dans cet article, je détaille la conception UI/UX, l'architecture technique et l'intégration de Strapi, de A à Z.

Vue d'ensemble du site Dcover — Section Hero


Partie 1 — UI / UX : L'identité visuelle et l'expérience utilisateur

1.1 Direction artistique : Dark & Premium

Le parti pris visuel est un thème sombre haut de gamme qui évoque l'univers automobile premium. La palette de couleurs repose sur :

  • Fond principal : #0A0A0A (noir profond) avec des variantes #111111 et #1A1A1A pour créer de la profondeur entre les sections
  • Accent : #E63946 (rouge vif) utilisé pour les CTA, les icônes, les éléments interactifs et les effets de glow
  • Texte : blanc pur pour les titres, #A0A0A0 pour le corps de texte, #666666 pour les labels secondaires
  • Bordures subtiles : rgba(255,255,255,0.08) pour délimiter les cartes sans casser l'immersion

Ce système de couleurs crée un contraste fort tout en restant cohérent avec l'image de marque d'un atelier automobile haut de gamme.

1.2 Typographie : Un système à 4 polices

Chaque police a un rôle bien défini dans la hiérarchie visuelle :

PoliceRôleExemple
Bebas NeueTitres massifs (hero)Le mot "DCOVER" en 22vw
OswaldTitres de sections"NOS SERVICES", "DERNIÈRES RÉALISATIONS"
RajdhaniLabels, boutons, navigation"COVERING • PROTECTION • CÉRAMIQUE"
OutfitCorps de texte, descriptionsParagraphes et contenus longs

Cette combinaison donne une identité futuriste et technique qui colle parfaitement au domaine automobile.

1.3 Le Hero : un effet "texte derrière la voiture"

La section hero est la pièce maîtresse du site. Elle utilise un système de couches superposées (z-index) pour créer un effet visuel où le texte géant "DCOVER" semble passer derrière la voiture :

z-[1]  → Fond noir + halos rouges radiaux
z-[10] → Texte PLEIN "DCOVER" (derrière la voiture)
z-[15] → Glow néon au sol (effet de lumière sous la voiture)
z-[20] → Image PNG de la voiture (devant le texte plein)
z-[25] → Texte CONTOUR "DCOVER" masqué par la silhouette de la voiture
z-[40] → Interface utilisateur (titre, description, boutons CTA)

Le texte en contour (couche z-25) utilise un masque CSS dynamique : un <canvas> dessine la silhouette de la voiture, puis est converti en dataURL pour servir de mask-image. Ainsi, le contour n'apparaît que là où la voiture est visible — un effet pixel-perfect qui s'adapte au redimensionnement.

La voiture entre en scène avec une animation Framer Motion (x: 300 → 0), et le texte contour n'apparaît qu'une fois l'animation terminée via onAnimationComplete.

1.4 Animations et micro-interactions

Tout le site utilise Framer Motion pour des animations au scroll (viewport-triggered) :

  • Fade-up : chaque section et ses éléments apparaissent progressivement avec un décalage (delay: index * 0.15)
  • Parallax : la section "Pourquoi nous choisir" utilise useScroll + useTransform pour un léger déplacement de l'image au scroll
  • Hover effects : les cartes de services ont un translateY(-4px) et un glow rouge au survol
  • Scroll indicator : une capsule animée en boucle (y: [0, 8, 0]) invite à scroller
  • Marquee : un défilement horizontal infini pour les logos des partenaires

1.5 Les sections du site

Le site est organisé en 11 sections distinctes, chacune étant un composant React indépendant :

Aperçu des sections du site — Services, Réalisations et formulaire de contact

  1. Navbar — Navigation fixe avec glassmorphism au scroll, liens d'ancrage, menu mobile animé et CTA "Devis Gratuit"
  2. Hero — Section plein écran avec l'effet texte/voiture décrit ci-dessus
  3. Stats — Chiffres clés animés (compteur)
  4. Services — Grille de 3 cartes (Covering, PPF, Céramique) avec numéro watermark, icônes Lucide et liste de caractéristiques
  5. Réalisations — Galerie en bento grid CSS (grille asymétrique) avec overlay au hover et catégorisation
  6. Pourquoi nous — Section split (image parallax + arguments avec icônes)
  7. Citation — Bandeau d'appel à l'action avec image de fond
  8. Avis clients — Carousel horizontal avec snap scroll, notes en étoiles et badge Google
  9. Partenaires — Logos défilants en marquee
  10. Contact — Formulaire de devis (nom, email, téléphone, véhicule, message) + informations de contact et réseaux sociaux
  11. Footer — Navigation, mentions légales, bouton "retour en haut"

1.6 Responsive Design

Chaque composant est conçu en mobile-first grâce à Tailwind CSS :

  • Le bento grid passe de 1 colonne (mobile) → 2 colonnes (tablette) → grille asymétrique 3 colonnes (desktop)
  • Les tailles de texte hero passent de 18vw à 22vw selon le viewport
  • La navbar bascule vers un menu hamburger animé sur mobile
  • Le parallax est désactivé sur mobile (background-attachment: scroll) pour des raisons de performance

1.7 Détails de polish

  • Grain overlay : un bruit SVG en position: fixed à 4% d'opacité sur tout le site, pour une texture film/photo
  • Scrollbar custom : fond noir, poignée grise qui devient rouge au survol
  • Sélection de texte : arrière-plan rouge semi-transparent
  • Glassmorphism : backdrop-filter: blur(20px) sur la navbar et certains composants
  • Gradient borders : bordures dégradées rouge-blanc via la technique background padding-box/border-box

Partie 2 — Strapi : Le CMS headless et son intégration

2.1 Pourquoi Strapi ?

Le client devait pouvoir modifier tout le contenu du site sans intervention technique : textes, images, services, réalisations, avis, articles de blog, etc. Strapi s'est imposé comme choix car :

  • Open-source et auto-hébergeable
  • API REST générée automatiquement pour chaque content type
  • Interface d'administration intuitive et personnalisable
  • Gestion des médias intégrée (upload, redimensionnement)
  • Système de rôles pour contrôler les accès

Interface d'administration Strapi — Dashboard avec les content types

2.2 Architecture des content types

Le back-office Strapi est organisé en Single Types (contenu unique) et Collection Types (listes) :

Single Types :

Content TypeChamps principauxRôle
hero-sectionsousTitre, titre, description, imageVoiture, boutonsSection hero
quote-sectiontitre, motAccentue, description, imageDeFond, texteBoutonBandeau citation
contact-infoadresse, telephone, email, réseaux sociauxInformations de contact
why-us-sectionlibelle, titreLigne1, titreLigne2, imageDeFondEn-tête "Pourquoi nous"
site-globalaccrochePiedDePage, droitsAuteur, boutonNavigationParamètres globaux

Collection Types :

Content TypeChamps principauxRôle
statsvaleur, suffixe, libelle, ordreChiffres clés
servicesnumero, icone, titre, description, caracteristiques[], ordreListe des prestations
realisationsimage, vehicule, prestation, categorie, misEnAvantPortfolio de travaux
reviewstexte, auteur, localisation, noteAvis clients
partnersnom, logo, ordreLogos partenaires
why-us-argumentsicone, titre, description, ordreArguments "Pourquoi nous"
articlestitre, slug, extrait, contenu (blocks), imageCouverture, categorie, auteurBlog

2.3 L'intégration côté Next.js

Le helper fetch générique

Toute la communication avec Strapi passe par une fonction utilitaire centralisée dans src/lib/strapi.ts :

async function fetchStrapi<T>(
  path: string,
  params: Record<string, string> = {},
  tag?: string,
): Promise<T> {
  const qs = new URLSearchParams(params).toString();
  const url = `${STRAPI_URL}/api${path}${qs ? `?${qs}` : ''}`;

  const headers: HeadersInit = { 'Content-Type': 'application/json' };
  if (STRAPI_TOKEN) headers.Authorization = `Bearer ${STRAPI_TOKEN}`;

  const res = await fetch(url, {
    headers,
    next: { revalidate: 60, tags: tag ? [tag] : undefined },
  });

  if (!res.ok) throw new Error(`Strapi fetch failed: ${res.status}`);
  return res.json();
}

Points clés :

  • Typage générique <T> : chaque appel retourne le type exact attendu (pas de any)
  • Revalidation ISR : next: { revalidate: 60 } permet de regénérer le cache toutes les 60 secondes, offrant un bon compromis entre fraîcheur du contenu et performance
  • Tags de cache : permettent une invalidation ciblée si nécessaire
  • Auth par token : le STRAPI_API_TOKEN est stocké en variable d'environnement côté serveur

Les fonctions de fetching

Chaque content type dispose de sa propre fonction typée. Par exemple :

export async function getServices(): Promise<Service[]> {
  const res = await fetchStrapi<StrapiCollectionResponse<Service>>(
    '/services',
    { 'sort': 'ordre:asc', 'populate': '*', 'pagination[pageSize]': '100' },
    'services',
  );
  return res.data;
}
  • sort: 'ordre:asc' : tri par champ ordre pour que le client contrôle l'affichage
  • populate: '*' : récupère les relations et médias associés
  • pagination[pageSize]: '100' : évite la pagination par défaut de Strapi (25 items)

Le helper d'images

export function strapiImage(img?: { url?: string } | null): string {
  if (!img?.url) return '';
  if (img.url.startsWith('http')) return img.url;
  return `${STRAPI_URL}${img.url}`;
}

Cette fonction gère les deux cas : images hébergées sur Strapi (URL relative) et images externes (URL absolue). Côté next.config.mjs, les domaines localhost:1337 et **.strapiapp.com sont autorisés pour le composant <Image> de Next.js.

2.4 Le typage TypeScript complet

Toutes les interfaces sont définies dans src/lib/types.ts et correspondent exactement aux schémas Strapi. Cela inclut :

  • Les wrappers génériques StrapiResponse<T> et StrapiCollectionResponse<T> pour parser la structure de réponse Strapi
  • Les types d'images avec formats (thumbnail, small, medium, large)
  • Les unions littérales pour les icônes ('Layers' | 'Shield' | 'Sparkles' | ...) et les catégories ('Covering' | 'PPF' | 'Céramique' | 'Chrome Delete')

Ce typage strict élimine les erreurs à la compilation et offre une autocomplétion parfaite dans l'IDE.

2.5 Le pattern "fallback data"

Chaque composant implémente un système de données de secours :

export default function Services({ data }: ServicesProps) {
  const services = data && data.length > 0
    ? mapStrapiServices(data)
    : defaultServices;
  // ...
}

Si Strapi est inaccessible ou si aucune donnée n'est encore créée, le site affiche des données par défaut codées en dur. Cela garantit que le site fonctionne toujours, même sans CMS, ce qui facilite le développement et les démonstrations.

2.6 Le rendu des articles (Rich Text Blocks)

Strapi v4+ utilise un format Blocks pour le contenu riche. Le composant BlockRenderer.tsx parse ce format et génère le HTML correspondant :

  • Paragraphes, titres (h1-h6), listes, citations, images sont supportés
  • Le texte inline gère le gras, italique, souligné, barré, code et liens
  • Les images sont rendues via le composant <Image> de Next.js avec lazy loading et optimisation automatique
  • Le style est cohérent avec le design system du site (mêmes polices, couleurs, espacements)

2.7 Data fetching côté serveur (RSC)

La page d'accueil utilise les React Server Components de Next.js 14. Tous les appels Strapi sont effectués en parallèle grâce à Promise.all :

export default async function Home() {
  const [heroData, stats, services, ...] = await Promise.all([
    getHeroSection(),
    getStats(),
    getServices(),
    // ... 8 autres appels
  ]);
  // ...
}

Avantages :

  • Pas de loading state côté client : le HTML est pré-rendu avec les données
  • SEO optimal : le contenu est dans le HTML initial
  • Performance : les 11 appels API s'exécutent simultanément, pas séquentiellement
  • ISR : le cache se revalide toutes les 60 secondes, donc le site est quasi-statique tout en restant à jour

Partie 3 — Stack technique complète

TechnologieVersionRôle
Next.js14 (App Router)Framework React avec SSR/ISR
TypeScript5.4Typage statique
Tailwind CSS3.4Styling utility-first
Framer Motion11.2Animations et transitions
Lucide React0.378Icônes SVG
Strapiv4CMS headless (back-end)
Node.jsRuntime Strapi

Conclusion

Le projet Dcover illustre comment combiner un front-end moderne et immersif avec un CMS headless pour offrir au client une autonomie totale sur son contenu. L'architecture Next.js + Strapi permet d'obtenir un site rapide (ISR), bien référencé (SSR), maintenable (TypeScript) et visuellement impactant (Framer Motion + Tailwind CSS).

Les points forts du projet :

  • Un hero section avec un effet visuel original (masquage dynamique via canvas)
  • Un design system cohérent et premium adapté au secteur automobile
  • Une intégration Strapi complète avec typage strict, fallback data et revalidation ISR
  • Un site 100% responsive pensé mobile-first
  • Une architecture scalable : ajouter une nouvelle section = créer un content type Strapi + un composant React