<header class="flex items-center">

<NuxtImg src="logo.png" class="w-18" alt="Dywan Dev - Digital tools & templates" format="webp" quality="80" loading="lazy" />

<Item><nuxt-link href="/">Home</nuxt-link></Item>

<Item><nuxt-link href="/about">About</nuxt-link></Item>

<Item><nuxt-link href="/works"> Portfolio</nuxt-link></Item>

<Item><nuxt-link href="/contact_me"> Contact</nuxt-link></Item>

<a href="/contact-me" title="Get in touch with Dywan Dev"> Contact </a>

<themeswitch class="moon">Dark/Light</themeswitch>

<langswitch class="en">en/fa</langswitch>

</header>

<initilizecontent class="content">Hello World - Dywan Dev</initilizecontent>

<myname is="Dywan Dev" />

<jobtitle is="Digital tools · Templates · Case studies" />

<portfolios are="ready" number="8" />

<experience years="more than 6" />

<birthdate year="1998" month="july" day="11" />

<skills :list="['NUXT', 'Vue', 'React', 'Next', 'Javascript','Responsive Design', 'i18n', 'TypeScript]" />

<contactDetails :list="['contact@dywandev.com', 'linkedin.com/in/dywan-dev', 'github.com/dywan-dev']" />

Dywan Dev
Blog
Comment j’ai construit un template de site restaurant avec 3 variantes depuis une seule base de code
13min

Comment j’ai construit un template de site restaurant avec 3 variantes depuis une seule base de code

Introduction

Tout a commencé avec un client.

Un restaurateur qui avait besoin d’un site. Rien de compliqué. Rien de cher. Juste quelque chose qui ressemble à son établissement — chaleureux, accueillant, authentique. Je l’ai fait. Il était content. Je suis passé à autre chose.

Puis un autre restaurant m’a contacté. Style différent. Public différent. Identité de marque complètement différente. J’ai recommencé depuis zéro et, vers la troisième heure, je me suis arrêté et je me suis posé une question qui a changé ma façon de penser les templates :

Pourquoi suis-je en train de reconstruire la même structure pour la troisième fois ?

Chaque site de restaurant partage le même squelette. Un hero qui rend la nourriture irrésistible. Un menu facile à parcourir. Une histoire qui inspire confiance. Une section contact qui convertit les visiteurs en réservations. La structure ne change jamais. Seule la personnalité change.

Cette observation est devenue Savoura Dywan — une seule base de code React qui produit trois sites de restaurant réellement distincts. Gastronomie de luxe. Restaurant de quartier convivial. Pizzeria rapide et audacieuse. Un build. Trois identités. Zéro compromis sur la qualité.

Voici l’histoire complète de sa construction et la raison derrière chaque décision.

1. Le problème des templates restaurant existants

Avant de construire quoi que ce soit, j’ai passé du temps à étudier ce qui existait déjà sur le marché.

La plupart des templates restaurant tombent dans l’une de deux catégories.

La première catégorie est belle mais rigide. Design superbe, contenu codé en dur, pas de vraie personnalisation au-delà de remplacer des images et modifier du texte directement dans les composants. Un développeur peut l’utiliser. Un restaurateur ne peut pas. Et un développeur qui veut le livrer à trois clients différents doit le reconstruire trois fois.

La seconde catégorie est flexible mais générique. Builders, outils drag-and-drop, thèmes WordPress avec des options infinies. Flexibilité maximale, personnalité minimale. Au final, chaque restaurant ressemble à tous les autres.

Aucune des deux catégories ne résolvait le vrai problème : un restaurateur a besoin d’un site qui donne l’impression de son établissement, livré vite, à un prix cohérent pour un commerce local.

Savoura Dywan a été conçu pour se placer dans l’entre-deux. Assez « opinionated » pour avoir une vraie personnalité. Assez flexible pour servir différents types de restaurants. Assez simple pour que la personnalisation consiste à modifier un seul fichier, pas à reconstruire tout le codebase.

2. Définir les trois variantes

Les trois variantes n’ont pas été choisies au hasard. Elles correspondent à trois publics réellement différents, avec des attentes visuelles et une psychologie client distinctes.

Luxury — Fine Dining

La variante luxury s’adresse aux restaurants où l’expérience est le produit. Un restaurant gastronomique à menu dégustation. Une maison de fruits de mer haut de gamme. Une destination gastronomique.

Le visiteur qui arrive ici a déjà décidé de dépenser. Il ne compare pas les prix. Il évalue le prestige, l’ambiance et l’exclusivité. Le site doit communiquer ces trois éléments avant même qu’un mot ne soit lu.

Langage visuel : fonds sombres, accents dorés, typographie serif avec espacement large, animations lentes et élégantes, hero plein écran avec imagerie cinématographique, whitespace généreux qui exprime un positionnement premium.

Casual — Neighbourhood Restaurant

La variante casual s’adresse aux restaurants où la chaleur et la communauté sont le produit. Une trattoria familiale. Un bistrot de quartier. Un spot brunch avec une clientèle locale fidèle.

Le visiteur veut se sentir chez lui avant même d’arriver. Il veut voir des plats souriants, des menus lisibles, et une personnalité humaine plutôt que corporate.

Langage visuel : tons terreux chauds, coins arrondis, typographie sans-serif amicale, animations « bouncy » avec effet ressort, hero accessible avec lumière naturelle, sections qui ressemblent à une conversation plutôt qu’à une présentation.

Pizzeria — Fast and Bold

La variante pizzeria s’adresse aux restaurants où la vitesse, l’appétit et l’énergie sont le produit. Une pizzeria de nuit. Une activité orientée livraison. Un concept de comptoir.

Le visiteur a faim. Il veut voir le produit immédiatement, trouver le menu vite, et commander ou appeler sans friction.

Langage visuel : fond sombre à fort contraste, accents rouge et jaune, typographie condensée et lourde, animations rapides et nerveuses, hero dominé par la photo produit, call-to-action très visible au-dessus de la ligne de flottaison.

Trois variantes. Trois psychologies. Trois parcours clients complètement différents — depuis une seule base de code.

3. La décision d’architecture qui a rendu cela possible

La tentation, quand on construit quelque chose comme ça, c’est de faire du rendu conditionnel partout. Un if luxury ici. Un switch variant là. Ça commence propre et devient ingérable en quelques semaines.

J’ai pris une décision fondatrice qui a évité cela : le codebase ne sait pas quel restaurant il sert. La configuration, si.

Tout ce qui est spécifique à une variante vit dans deux fichiers. siteConfig.js contient le contenu, les coordonnées, les feature toggles et l’identifiant de variante. themes.js contient la personnalité visuelle complète de chaque variante — couleurs, typographies, espacements, vitesses d’animation, rayons de bordure et styles d’ombre.

Chaque composant lit ces fichiers via un contexte de thème central. Aucun composant n’a de logique spécifique à la variante sauf si la mise en page diffère réellement. Et quand c’est le cas, un simple pattern de resolver le gère proprement.

// The only place variant logic lives in components
const HeroComponent = {
  luxury: LuxuryHero,
  casual: CasualHero,
  pizzeria: PizzeriaHero
}[variant];

return <HeroComponent />;

Cette architecture a une conséquence cruciale pour la vente du template : l’acheteur change variant: 'luxury' en variant: 'casual' dans un seul fichier et tout le site se transforme. Couleurs, polices, animations, espacements, personnalité — tout se met à jour instantanément.

Ce n’est pas seulement une bonne ingénierie. C’est une feature qui conclut des ventes.

4. Construire le système de menu

Le menu est la section la plus importante de tout site de restaurant. C’est là que le visiteur décide de venir… ou de partir. Se tromper ici, c’est perdre la vente avant même que le restaurant n’ait une chance.

Le système de menu de Savoura Dywan est entièrement piloté par configuration. Tout le contenu du menu vit dans siteConfig.js :

menu: {
  categories: [
    {
      id: 'starters',
      name: 'Starters',
      nameAr: 'المقبلات',
      nameFr: 'Entrées',
      items: [
        {
          id: 1,
          name: 'Burrata & Heirloom Tomato',
          nameAr: 'بوراتا وطماطم',
          nameFr: 'Burrata et Tomate',
          description: 'Fresh burrata with seasonal heirloom tomatoes, aged balsamic, and micro basil',
          price: 14,
          currency: 'USD',
          image: '/menu/burrata.jpg',
          tags: ['vegetarian', 'gluten-free'],
          featured: true,
          available: true
        }
      ]
    }
  ],
  displayStyle: 'grid', // 'grid' | 'list' | 'magazine'
  showImages: true,
  showCalories: false,
  enableFilters: true
}

Le composant menu lit cette configuration et rend l’UI en conséquence. Changer displayStyle de grid à list modifie toute la mise en page. Désactiver showImages supprime les photos pour les restaurants qui préfèrent un menu texte. Activer les filtres ajoute automatiquement une barre de filtrage par catégorie.

Chaque item supporte trois langues nativement. Quand le visiteur passe en arabe, le menu s’affiche en arabe avec une mise en page RTL. Les visiteurs francophones voient le français. L’anglais est le fallback. Aucun travail développeur après la config initiale.

5. Multilingue et RTL — le différenciateur

Cette feature à elle seule différencie Savoura Dywan de la plupart des templates restaurant concurrents.

Le marché MENA — Maroc, Algérie, Tunisie, Égypte, pays du Golfe — compte des millions de restaurants sans présence web professionnelle. La plupart des templates ne supportent pas l’arabe. Et la plupart de ceux qui le prétendent l’implémentent mal — layouts cassés, directions de texte mélangées, polices qui rendent l’arabe incorrectement.

Savoura Dywan traite l’arabe comme une langue de première classe, pas comme un ajout de dernière minute.

L’implémentation utilise i18next pour la traduction de contenu et un hook de direction qui met à jour l’attribut HTML dir, les propriétés CSS logiques et les directions d’animation en même temps lorsque la langue change.

export const useDirection = () => {
  const { i18n } = useTranslation();

  useEffect(() => {
    const isRTL = ['ar'].includes(i18n.language);
    document.documentElement.dir = isRTL ? 'rtl' : 'ltr';
    document.documentElement.lang = i18n.language;
    document.documentElement.setAttribute('data-direction', isRTL ? 'rtl' : 'ltr');
  }, [i18n.language]);
};

L’attribut data-direction permet au CSS et aux animations Framer Motion de réagir au changement de direction. Les animations « slide-in » s’inversent correctement. Les images directionnelles se mettent en miroir au bon moment. Toute la mise en page bascule sans bug.

Pour un restaurant marocain qui sert une clientèle francophone et arabophone, ce n’est pas un « nice-to-have ». C’est une exigence business. Savoura Dywan le livre prêt à l’emploi.

6. PWA — la feature perçue comme de la magie

Chaque client à qui j’ai montré la PWA a eu la même réaction. Ils prennent leur téléphone, ouvrent la démo, voient l’invite d’installation, appuient… et regardent le site apparaître sur l’écran d’accueil comme une app native. Les yeux s’écarquillent légèrement.

Ce moment vaut plus en vente que n’importe quelle explication technique.

L’implémentation utilise Vite PWA Plugin avec une configuration Workbox soignée. Les décisions clés :

Support offline pour le menu. Si un client consulte le menu dans une zone à faible réseau — ce qui arrive souvent dans de nombreuses villes marocaines — le menu continue de fonctionner depuis le cache. Le restaurant ne perd pas un client potentiel à cause d’un loader.

Notifications de mise à jour. Quand le restaurateur met à jour son menu ou ajoute une promo, les visiteurs qui ont installé la PWA voient une notification pour rafraîchir. Ils voient toujours l’info à jour.

Timing de l’invite d’installation. L’invite apparaît après trente secondes sur le site — assez pour montrer un intérêt réel, sans interrompre la première impression.

export const usePWAInstall = () => {
  const [installPrompt, setInstallPrompt] = useState(null);
  const [showPrompt, setShowPrompt] = useState(false);

  useEffect(() => {
    const handler = (e) => {
      e.preventDefault();
      setInstallPrompt(e);

      // Wait 30 seconds before showing install UI
      setTimeout(() => setShowPrompt(true), 30000);
    };

    window.addEventListener('beforeinstallprompt', handler);
    return () => window.removeEventListener('beforeinstallprompt', handler);
  }, []);

  const install = async () => {
    if (!installPrompt) return;
    await installPrompt.prompt();
    setShowPrompt(false);
    setInstallPrompt(null);
  };

  return { showPrompt, install };
};

7. Le flow réservation et WhatsApp

La plupart des sites de restaurants au Maroc et plus largement dans la région MENA n’utilisent pas de système de réservation en ligne. Le canal principal est WhatsApp. Un template qui ignore cette réalité n’est pas conçu pour ce marché.

Savoura Dywan inclut un bouton WhatsApp flottant qui pré-remplit un message avec le nom du restaurant et une demande de réservation :

export const WhatsAppButton = () => {
  const { config } = useTheme();

  if (!config.features.enableWhatsApp) return null;

  const message = encodeURIComponent(
    `Hello, I'd like to make a reservation at ${config.branding.name}.`
  );

  const url = `https://wa.me/${config.contact.whatsapp.replace(/\\D/g, '')}?text=${message}`;

  return (
    <motion.a
      href={url}
      target="_blank"
      rel="noopener noreferrer"
      className="whatsapp-float"
      whileHover={{ scale: 1.1 }}
      whileTap={{ scale: 0.95 }}
      aria-label="Contact us on WhatsApp"
    >
      <WhatsAppIcon />
    </motion.a>
  );
};

Activez-le avec enableWhatsApp: true dans la config. Définissez le numéro une fois. Chaque demande de réservation arrive directement sur le téléphone du restaurateur. Pas de frais de plateforme. Pas de dépendances tierces. Juste le canal de communication qui fonctionne réellement sur ce marché.

8. Performance — parce qu’un site lent fait fuir les clients

Un visiteur qui attend plus de trois secondes qu’un site de restaurant charge va partir. Il n’attendra pas. Il trouvera un autre restaurant.

La performance n’a pas été une optimisation de fin de projet sur Savoura Dywan. C’était une contrainte de design dès le départ.

Décisions clés :

Lazy loading de toutes les images. Les images hero chargent immédiatement. Toutes les autres se chargent au scroll. Le chargement initial ne transporte que ce qui est visible au-dessus de la ligne de flottaison.

Optimisation des polices. Google Fonts est chargé avec display=swap et des hints preconnect. Le texte apparaît tout de suite en police fallback puis bascule vers la police finale — pas de texte invisible.

Code splitting par route. React Router charge chaque page en lazy. Un visiteur qui arrive sur la home ne télécharge pas le code de la page menu avant d’y aller.

Optimisation build Vite. Le découpage manuel sépare vendors et code applicatif. Framer Motion, i18next et React sont dans des chunks distincts qui se cachent indépendamment. Mettre à jour le contenu du menu n’invalide pas le cache Framer Motion.

Résultat : sur les trois variantes, un score Lighthouse mobile régulièrement au-dessus de 90 — l’appareil que la majorité des clients utilisent pour décider où manger.

9. Le problème des 90% et comment je l’ai résolu

Je vais être honnête. Savoura Dywan a atteint 90% de complétion trois fois avant d’être réellement fini.

Les premiers 90% étaient la mise en page de base et les trois designs. Puis j’ai ajouté le multilingue — encore 90%. Puis la PWA, les animations et l’architecture config — encore 90%.

À chaque fois, dès que je sentais que c’était « terminé », quelque chose semblait nécessaire. Une nouvelle feature. Une amélioration. Une meilleure organisation du fichier de config. Et chaque ajout réinitialisait ce sentiment de fin sans faire avancer le produit de manière significative.

La question qui a fini par casser la boucle était simple : un client qui paye verrait-il la différence entre ce que j’ai maintenant et ce que je m’apprête à ajouter ?

Quand la réponse était non — j’ai arrêté et j’ai livré.

C’est la leçon la plus importante que j’ai apprise en construisant Savoura Dywan. Le perfectionnisme et la qualité ne sont pas la même chose. Un produit livré qui résout le problème vaut plus qu’un produit non livré qui le résout un peu mieux.

La version deux existe pour une raison.

10. Ce que Savoura Dywan fournit « out of the box »

Pour un restaurateur ou un développeur livrant un projet restaurant, Savoura Dywan apporte :

Trois variantes complètes avec des personnalités distinctes couvrant la majorité des types de restaurants. Support multilingue complet en anglais, français et arabe avec mise en page RTL correcte — une fonctionnalité absente de la plupart des templates concurrents. Capacité PWA avec menu disponible hors ligne et installation sur l’écran d’accueil. Une architecture entièrement pilotée par config : contenu, branding, et features dans un seul fichier. Animations Framer Motion ajustées à la personnalité de chaque variante. Intégration WhatsApp pensée pour le marché MENA. Mise en place SEO : meta tags, Open Graph, Twitter cards et données structurées business. Layout responsive mobile-first optimisé pour les appareils réellement utilisés par les clients.

Un développeur utilisant Savoura Dywan pour livrer un projet restaurant économise entre deux et quatre jours de travail par rapport à un build from scratch. À un taux freelance raisonnable, cette économie rentabilise le template plusieurs fois dès le premier projet.

Conclusion

Savoura Dywan a commencé par une question : pourquoi reconstruire la même structure alors que seule la personnalité change ?

La réponse est devenue un produit. Un produit construit non seulement pour les développeurs qui veulent un raccourci, mais aussi pour les restaurateurs qui ont besoin d’une présence web pro sans coûts de développement sur mesure, et pour les réalités du marché marocain et MENA où le multilingue et WhatsApp ne sont pas optionnels.

Chaque décision d’architecture — système config-driven, theme context, resolver pattern, implémentation RTL — a été prise pour servir un objectif : un template qui paraît totalement sur mesure tout en demandant un minimum de configuration.

C’est ce qui sépare un template d’un moteur de template.

Savoura Dywan est disponible maintenant sur Dywan Dev. Trois variantes complètes, support RTL multilingue, PWA et configuration totale depuis un seul fichier. Conçu pour les développeurs qui livrent vite et les restaurateurs qui veulent du pro sans coûts sur mesure. Obtenir Savoura Dywan.

Continuer la lecture

Voir toutVoir tout
WhatsApp