Article SEO SEO Technique

Agence SEO Marrakech

Sommaire de l'article

Agence SEO Marrakech : guide complet pour booster votre visibilité en 2025

Introduction

En 2025, le marché du digital ne cesse de croître à Marrakech et dans l’ensemble de la région Sud du Maroc. Les entreprises locales et internationales reconnaissent de plus en plus l’importance d’une présence en ligne optimisée pour se démarquer de la concurrence. Dans ce contexte, les agences SEO à Marrakech jouent un rôle clé pour améliorer la visibilité sur les moteurs de recherche et générer un flux régulier de prospects qualifiés.

Une agence SEO à Marrakech sérieuse sait adapter les stratégies de référencement naturel aux spécificités locales : saisonnalité touristique, habitudes de recherche des internautes marocains, particularités linguistiques (français, arabe, parfois anglais) et concurrence sectorielle très forte dans l’hôtellerie, le tourisme, l’immobilier ou la restauration.

Que vous gériez une boutique de souvenirs dans la médina, un riad de charme, une agence immobilière ou un cabinet de services B2B, une stratégie de SEO local à Marrakech bien construite permet d’attirer un public réellement intéressé et de transformer plus de visites en demandes de devis, réservations ou ventes.

Cet article détaille les concepts clés du référencement à Marrakech, les bonnes pratiques à appliquer, les outils indispensables, les vrais tarifs d’une agence SEO à Marrakech ainsi que des conseils concrets pour choisir le bon partenaire.

Concepts clés du SEO à Marrakech

Qu’est-ce qu’une agence SEO ?

Une agence SEO est une entreprise spécialisée dans l’optimisation des sites web pour les moteurs de recherche (Google, Bing, etc.). Son objectif principal est d’améliorer le positionnement d’un site dans les résultats naturels afin d’augmenter le trafic organique, la notoriété de la marque et, in fine, le chiffre d’affaires.

Concrètement, une agence SEO à Marrakech intervient sur plusieurs volets complémentaires :

  • Analyse technique du site (performance, erreurs d’indexation, structure, compatibilité mobile).
  • Recherche et sélection de mots-clés pertinents alignés sur l’intention de recherche de votre audience.
  • Optimisation on-page : balises, contenus, maillage interne, structuration des pages.
  • Stratégie de contenus optimisés (articles de blog, pages de service, fiches produits, FAQ, etc.).
  • Stratégie de netlinking et acquisition de backlinks de qualité, idéalement contextualisés et locaux.
  • SEO local et optimisation de la fiche Google Business Profile.
  • Suivi, reporting, analyse des KPI et ajustements continus.

Pourquoi choisir une agence SEO locale à Marrakech ?

Pour une entreprise basée à Marrakech, choisir une agence marketing digital à Marrakech ou une agence SEO locale présente plusieurs avantages décisifs :

  • Connaissance approfondie du marché local : compréhension des périodes de haute et basse saison, des principaux événements (festivals, salons, congrès) et de leur impact sur la demande.
  • Adaptation fine aux besoins spécifiques : stratégie différenciée pour un riad, une agence de location de voitures, un restaurant gastronomique ou une école de langue.
  • Optimisation pour les requêtes géolocalisées : expressions comme « hôtel Marrakech médina », « restaurant traditionnel Marrakech », « agence immobilière Marrakech Guéliz », « excursions désert depuis Marrakech », etc.
  • Compréhension culturelle et linguistique : rédaction et optimisation possibles en français, en arabe et/ou en anglais, avec prise en compte des expressions réellement utilisées par les internautes au Maroc.
  • Proximité et accompagnement : réunions sur place, meilleure compréhension de votre activité, visites de vos locaux ou établissement, ce qui facilite la création de contenus authentiques.

L’importance du SEO local à Marrakech

Le SEO local est particulièrement crucial pour les entreprises qui possèdent un point de vente physique, un établissement touristique ou des bureaux accueillant du public à Marrakech ou dans sa région. Les internautes effectuent très souvent des recherches combinant un service et le nom de la ville, par exemple :

  • « restaurants traditionnels Marrakech »
  • « agence immobilière Marrakech centre »
  • « cours de français à Marrakech »
  • « excursion désert au départ de Marrakech »

Une bonne stratégie SEO à Marrakech axée sur le référencement local permet :

  • d’apparaître dans le pack local (résultats Google Maps) ;
  • d’augmenter les appels, les demandes de devis et les réservations ;
  • d’améliorer la visibilité auprès d’un public déjà fortement intéressé.

Bonnes pratiques pour réussir son SEO à Marrakech

Optimiser le contenu pour le SEO local

L’optimisation du contenu reste l’un des piliers du référencement naturel. Pour une entreprise basée à Marrakech, il est stratégique d’intégrer la dimension locale dans la ligne éditoriale.

  • Rédiger régulièrement des articles de blog sur des sujets en lien avec Marrakech et votre secteur (ex. « Que faire à Marrakech en 3 jours » pour un riad, « Comment choisir une agence immobilière à Marrakech » pour un cabinet immobilier).
  • Inclure des mots-clés pertinents mêlant service + localisation (ex. « visiter Marrakech en décembre », « location de voiture à Marrakech aéroport », « spa de luxe à Marrakech »).
  • Utiliser des titres (balise et balises <h1>, <h2 id="et-des-meta-descriptions-optimises-integrant-des-expressions-recherchees-et-un-appel-a-l-action-stru">) et des méta descriptions optimisés, intégrant des expressions recherchées et un appel à l’action.</li> <li>Structurer les contenus avec des sous-titres clairs, des listes, des paragraphes courts et des FAQ pour répondre précisément aux questions des internautes.</li> <li>Produire des contenus multilingues si votre clientèle est internationale (français, anglais, éventuellement espagnol ou arabe), tout en respectant les bonnes pratiques SEO pour les sites multilingues.</li> </ul> <h3>Améliorer la structure technique du site</h2> <p>Une structure technique saine est indispensable pour le bon référencement d’un site à Marrakech comme ailleurs. Google accorde une grande importance à l’expérience utilisateur, y compris sur mobile.</p> <ul> <li>Développer un site <strong>responsive</strong> (parfaitement compatible mobile et tablette), essentiel dans une ville où une grande partie des recherches se font depuis un smartphone.</li> <li>Optimiser la <strong>vitesse de chargement</strong> (Page Speed) en compressant les images, en utilisant un hébergement performant au Maroc ou dans une région proche, et en mettant en place un système de cache.</li> <li>Mettre en place un <strong>maillage interne</strong> logique, qui guide les utilisateurs et les robots de Google vers vos pages les plus importantes (pages services, pages catégories, pages locales).</li> <li>Corriger les erreurs techniques fréquentes : pages 404, redirections mal configurées, contenus dupliqués, problèmes d’indexation ou d’accès aux ressources.</li> <li>Utiliser un <strong>balisage de données structurées</strong> (schema.org) lorsque cela est pertinent (avis, événements, FAQ, produits, établissement local) pour enrichir vos résultats dans Google.</li> </ul> <h3 id="creer-du-contenu-de-qualite-oriente-utilisateur">Créer du contenu de qualité orienté utilisateur</h3> <p>Le contenu est roi en SEO, mais seulement s’il répond réellement aux attentes des internautes. À Marrakech, un contenu de qualité doit être à la fois informatif, rassurant et adapté au contexte local.</p> <ul> <li>Rédiger des guides complets sur des sujets d’intérêt local : « Les meilleurs souks de Marrakech », « Comment préparer son voyage à Marrakech », « Investir dans l’immobilier à Marrakech », etc.</li> <li>Proposer des contenus enrichis (infographies, vidéos explicatives, visites virtuelles, galeries photos professionnelles) pour se démarquer de la concurrence.</li> <li>Mettre en avant les avis clients, témoignages et études de cas pour renforcer la preuve sociale et la confiance.</li> <li>Animer une communauté sur les réseaux sociaux (Facebook, Instagram, TikTok, LinkedIn selon votre secteur) et relayer vos contenus SEO pour maximiser leur portée.</li> <li>Mettre régulièrement à jour les contenus existants (horaires, tarifs, prestations, photos) afin de garder votre site fiable et pertinent pour Google et pour vos visiteurs.</li> </ul> <h3 id="developper-une-strategie-de-netlinking-locale">Développer une stratégie de netlinking locale</h3> <p>Le <strong>netlinking</strong> (acquisition de backlinks) reste un levier puissant pour améliorer l’autorité de votre site. À Marrakech, il est pertinent de développer des liens provenant de sites marocains et locaux.</p> <ul> <li>Obtenir des liens depuis des blogs et médias locaux parlant de tourisme, lifestyle, business ou actualités à Marrakech.</li> <li>Collaborer avec des influenceurs, des partenaires touristiques, des offices de tourisme ou des associations professionnelles.</li> <li>Inscrire votre entreprise dans des annuaires locaux de qualité (en évitant les annuaires spammy ou de faible valeur).</li> <li>Publier des articles invités sur des sites pertinents traitant du Maroc, du voyage, de l’immobilier ou de votre niche spécifique.</li> <li>Surveiller régulièrement votre profil de liens et désavouer, si besoin, les backlinks toxiques.</li> </ul> <h3 id="optimiser-la-fiche-google-business-profile">Optimiser la fiche Google Business Profile</h3> <p>Pour le <strong>SEO local à Marrakech</strong>, votre fiche Google Business Profile (anciennement Google My Business) est un actif stratégique. Bien optimisée, elle vous permet d’apparaître en bonne position dans Google Maps et dans le bloc local des résultats.</p> <ul> <li>Renseigner toutes les informations essentielles : nom de l’établissement, adresse exacte, numéro de téléphone local, site web, horaires, services, photos professionnelles.</li> <li>Choisir des catégories pertinentes (par exemple « Hôtel », « Riad », « Restaurant marocain », « Agence de voyage », « Agence immobilière », etc.).</li> <li>Publier régulièrement des posts (promotions, événements, nouveautés, articles de blog) pour maintenir un profil actif.</li> <li>Encourager vos clients satisfaits à laisser des avis et y répondre systématiquement de manière professionnelle.</li> <li>Vérifier la cohérence des informations NAP (Name, Address, Phone) entre votre fiche, votre site et les annuaires où vous êtes présents.</li> </ul> <h2 id="outils-et-ressources-pour-une-strategie-seo-efficace-a-marrakech">Outils et ressources pour une stratégie SEO efficace à Marrakech</h2> <p>Pour piloter une stratégie SEO performante, une <strong>agence SEO à Marrakech</strong> combine son expertise humaine avec des outils spécialisés.</p> <ul> <li><strong>Google Search Console</strong> : suivi de l’indexation, analyse des requêtes tapées par les internautes, détection des erreurs techniques, inspection des URL et suivi des clics organiques.</li> <li><strong>Google Analytics</strong> : mesure du trafic, des sources d’acquisition, des conversions et du comportement des utilisateurs sur les différentes pages.</li> <li><strong>Ahrefs, SEMrush, SE Ranking ou équivalents</strong> : analyse concurrentielle, audit technique, recherche de mots-clés, suivi des positions dans Google, analyse de backlinks.</li> <li><strong>Outils de tracking d’appels et formulaires</strong> : attribution des leads au canal SEO, mesure du retour sur investissement.</li> <li><strong>Outils de rédaction assistée (Jasper, Copy.ai, etc.)</strong> : génération d’idées de contenus, trames d’articles, enrichissement de textes, toujours relus et retravaillés par un rédacteur humain.</li> <li><strong>Outils de gestion de projets</strong> : suivi des tâches SEO, coordination entre développeurs, rédacteurs et équipe marketing.</li> </ul> <h2 id="tarifs-d-une-agence-seo-a-marrakech-nbsp-les-vrais-ordres-de-grandeur">Tarifs d’une agence SEO à Marrakech : les vrais ordres de grandeur</h2> <p>La question du <strong>coût d’une prestation SEO à Marrakech</strong> est centrale pour la plupart des entreprises. Il est important de s’appuyer sur des fourchettes réalistes et représentatives du marché local, en distinguant les différents types de prestations.</p> <h3 id="prix-d-un-audit-seo-a-marrakech">Prix d’un audit SEO à Marrakech</h3> <p>Un audit SEO complet à Marrakech comprend généralement l’analyse technique, l’analyse du contenu, l’étude des mots-clés, le benchmark concurrentiel et des recommandations priorisées.</p> <ul> <li>Pour un site vitrine ou un site de taille moyenne, les <strong>audits complets</strong> se situent le plus souvent entre <strong>1 000 et 3 000 MAD</strong>, selon la profondeur de l’analyse et le niveau de détail du rapport.</li> <li>Pour des audits plus poussés, sur des sites complexes ou e-commerce, certains acteurs facturent l’audit autour de <strong>3 200 MAD</strong> (environ 300 €), voire davantage, notamment lorsqu’il inclut un accompagnement stratégique détaillé.</li> </ul> <p>Ces montants ne doivent pas être interprétés comme des prix fixes : ils varient en fonction de la taille du site, du niveau de concurrence sur vos mots-clés, de votre historique SEO et du périmètre analysé.</p> <h3 id="tarifs-mensuels-des-prestations-seo-a-marrakech">Tarifs mensuels des prestations SEO à Marrakech</h3> <p>Les <strong>prestations mensuelles SEO</strong> regroupent généralement l’optimisation on-page, le netlinking, la création de contenus, le suivi, les rapports et les ajustements de la stratégie.</p> <p>Les fourchettes de prix les plus constatées sur le marché marrakchi et marocain se situent autour des niveaux suivants :</p> <ul> <li><strong>Forfaits SEO classiques</strong> pour une stratégie sérieuse et continue (on-page + off-page + suivi) : environ <strong>3 000 à 10 000 MAD par mois</strong>, en fonction de la taille du site, des objectifs et de la concurrence.</li> <li><strong>Petits forfaits d’entrée de gamme</strong> ou offres très locales : environ <strong>1 500 à 3 000 MAD par mois</strong>. Ces offres conviennent plutôt à de petites structures avec des besoins limités et un périmètre restreint.</li> <li><strong>Segment premium et projets avancés</strong> (sites e‑commerce, sites multilingues, secteurs très concurrentiels) : les budgets peuvent dépasser <strong>10 000 MAD par mois</strong>, notamment pour des stratégies très complètes et orientées performance.</li> </ul> <p>Il est donc inexact de limiter le marché à une seule fourchette basse : les prix <strong>n’oscillent pas uniquement entre 1 500 et 6 000 MAD</strong>. Le marché intermédiaire et premium se situe clairement au‑delà pour les prestations les plus complètes.</p> <h3 id="comparaison-avec-les-tarifs-en-euros">Comparaison avec les tarifs en euros</h3> <p>Pour les entreprises ou investisseurs étrangers, il peut être utile de raisonner également en euros. Si l’on considère l’échelle plus large du marché du SEO :</p> <ul> <li>Au niveau international, une <strong>agence SEO</strong> facture fréquemment entre <strong>500 € et plus de 2 500 € par mois</strong> pour des prestations récurrentes, selon le pays et le niveau de service.</li> <li>Au Maroc, en convertissant les fourchettes en MAD, on retrouve souvent des budgets mensuels compris entre <strong>3 000 et 15 000 MAD</strong> pour des accompagnements professionnels.</li> </ul> <p>Dans cette optique, pour répondre de façon réaliste à la question du coût, il est plus pertinent d’indiquer une fourchette large tenant compte des différents niveaux de prestation. Ainsi, pour une <strong>agence SEO professionnelle à Marrakech</strong>, il est raisonnable de prévoir un budget mensuel situé, selon les projets, entre environ <strong>3 000 et 10 000 MAD</strong>, avec des offres d’entrée de gamme plus modestes et des offres premium pouvant aller au‑delà.</p> <h2 id="comment-choisir-la-bonne-agence-seo-a-marrakech-nbsp">Comment choisir la bonne agence SEO à Marrakech ?</h2> <p>Au‑delà du prix, plusieurs critères doivent guider votre choix d’<strong>agence de référencement à Marrakech</strong>.</p> <ul> <li><strong>Expérience et références locales</strong> : vérifier les études de cas, les secteurs d’activité déjà accompagnés (hôtellerie, tourisme, immobilier, e‑commerce, services B2B, etc.).</li> <li><strong>Transparence de la méthode</strong> : l’agence doit être capable d’expliquer clairement sa stratégie, ses actions prévues et les indicateurs de performance suivis.</li> <li><strong>Reporting régulier</strong> : rapports mensuels ou trimestriels détaillant les positions, le trafic organique, les leads générés et les actions menées.</li> <li><strong>Respect des bonnes pratiques (white hat)</strong> : éviter les méthodes de spam ou de manipulation susceptibles d’entraîner des pénalités Google.</li> <li><strong>Accompagnement stratégique</strong> : une bonne agence ne se contente pas d’optimiser des mots-clés ; elle s’intéresse à votre business model, à votre rentabilité et à vos objectifs commerciaux.</li> <li><strong>Contrat clair</strong> : durée minimale d’engagement, détail des prestations incluses, conditions de résiliation, modalités de facturation.</li> </ul> <h2 id="delais-pour-obtenir-des-resultats-seo-a-marrakech">Délais pour obtenir des résultats SEO à Marrakech</h2> <p>Le référencement naturel est un investissement à moyen et long terme. À Marrakech comme ailleurs, les premiers résultats significatifs demandent du temps.</p> <ul> <li>Pour un site correctement optimisé et dans un secteur moyennement concurrentiel, on commence généralement à observer des <strong>résultats entre 3 et 6 mois</strong> (augmentation du trafic organique, meilleures positions sur certains mots-clés, plus de demandes entrantes).</li> <li>Dans les secteurs très compétitifs (hôtellerie, excursions, immobilier de luxe), il faut souvent compter <strong>6 à 12 mois</strong> de travail continu pour atteindre des positions vraiment solides.</li> <li>Les actions techniques ou certaines optimisations on-page peuvent apporter des gains plus rapides, mais la consolidation de l’autorité du site via le contenu et le netlinking reste progressive.</li> </ul> <p>Une <strong>agence SEO Marrakech</strong> sérieuse expliquera ces délais dès le départ et positionnera le SEO comme un levier de croissance durable plutôt qu’une solution miracle immédiate.</p> <h2 id="faq-agence-seo-marrakech">FAQ – Agence SEO Marrakech</h2> <h3 id="pourquoi-choisir-une-agence-seo-locale-nbsp">Pourquoi choisir une agence SEO locale ?</h3> <p>Une agence SEO basée à Marrakech connaît mieux les spécificités du marché marocain, la saisonnalité, les comportements de recherche des internautes et la structure concurrentielle de la ville. Elle peut adapter ses stratégies aux besoins particuliers des entreprises locales : choix des mots-clés, contenus multilingues, visibilité sur Google Maps, partenariats locaux, etc. Cette proximité facilite également les échanges, les rendez-vous en présentiel et la compréhension fine de votre activité.</p> <h3 id="quel-est-le-cout-moyen-d-une-prestation-seo-a-marrakech-nbsp">Quel est le coût moyen d’une prestation SEO à Marrakech ?</h3> <p>Les tarifs varient selon l’ampleur du projet, la taille du site, la concurrence et le niveau d’accompagnement souhaité. Pour une <strong>agence SEO professionnelle à Marrakech</strong>, il est pertinent de prévoir un budget mensuel généralement compris entre <strong>3 000 et 10 000 MAD</strong> pour une stratégie continue incluant optimisation on-page, off-page et suivi. Des offres d’entrée de gamme peuvent commencer autour de <strong>1 500 à 3 000 MAD</strong>, alors que des projets complexes ou très concurrentiels peuvent nécessiter des budgets supérieurs à <strong>10 000 MAD</strong> par mois.</p> <h3 id="combien-coute-un-audit-seo-a-marrakech-nbsp">Combien coûte un audit SEO à Marrakech ?</h3> <p>Un audit SEO complet à Marrakech coûte en moyenne entre <strong>1 000 et 3 000 MAD</strong> pour un site vitrine ou institutionnel de taille classique. Pour des sites plus complexes ou e‑commerce, le montant peut être plus élevé, notamment lorsque l’audit inclut des recommandations détaillées par priorités, un plan d’action sur plusieurs mois et un accompagnement personnalisé.</p> <h3 id="combien-de-temps-faut-il-pour-voir-des-resultats-seo-nbsp">Combien de temps faut-il pour voir des résultats SEO ?</h3> <p>Les premiers résultats SEO sont généralement visibles entre <strong>3 et 6 mois</strong> de travail continu et cohérent, à condition que la stratégie soit correctement définie et exécutée (technique, contenu, netlinking, SEO local). Dans les niches très concurrentielles à Marrakech, des résultats vraiment solides peuvent demander jusqu’à <strong>12 mois</strong> ou plus. Le SEO doit être envisagé comme un investissement durable, dont les effets s’accumulent dans le temps.</p> <h3 id="pourquoi-mon-site-ne-se-positionne-t-il-pas-bien-nbsp">Pourquoi mon site ne se positionne-t-il pas bien ?</h3> <p>Les raisons d’un mauvais positionnement peuvent être multiples :</p> <ul> <li>Absence de stratégie de mots-clés claire ou ciblage de requêtes trop concurrentielles.</li> <li>Contenus insuffisants, peu qualitatifs, dupliqués ou non adaptés aux intentions de recherche.</li> <li>Problèmes techniques (vitesse de chargement lente, erreurs d’indexation, site non responsive, architecture confuse).</li> <li>Manque de popularité et de backlinks de qualité, notamment depuis des sites marocains ou traitant de Marrakech.</li> <li>Fiche Google Business Profile incomplète, mal optimisée ou peu active.</li> <li>Historique SEO problématique : anciennes techniques black hat, spam de liens, contenus automatisés de mauvaise qualité.</li> </ul> <p>Un audit complet réalisé par une <strong>agence SEO à Marrakech</strong> permet d’identifier précisément les freins à la visibilité et de prioriser les actions correctrices.</p> <h2 id="conclusion">Conclusion</h2> <p>En 2025, investir dans une <strong>agence SEO Marrakech</strong> sérieuse est plus que jamais essentiel pour booster sa visibilité en ligne, attirer une clientèle qualifiée et se démarquer de la concurrence locale et internationale. Le contexte numérique au Maroc est en pleine expansion, et Marrakech se positionne comme l’un des pôles majeurs du webmarketing dans le pays.</p> <p>En combinant une stratégie SEO adaptée aux spécificités locales, une optimisation technique irréprochable, des contenus de grande qualité et une gestion rigoureuse de votre présence sur Google Business Profile, votre entreprise peut obtenir des résultats durables : plus de trafic organique, davantage de demandes entrantes et une meilleure rentabilité de vos investissements marketing.</p> <p>Si vous avez besoin d’aide pour votre projet digital à Marrakech ou dans la région du Sud marocain, n’hésitez pas à contacter une équipe experte en marketing digital et en référencement naturel. Un accompagnement professionnel vous permettra de définir les bons objectifs, de choisir les bons indicateurs de performance et de mettre en place une stratégie SEO réellement alignée sur la croissance de votre entreprise.</p> </body> </html> </div> <!-- CTA Section --> <div class="mt-12 pt-8 border-t border-gray-200"> <div class="bg-gradient-to-r from-purple-600 to-blue-600 rounded-xl p-8 text-center text-white"> <h3 class="text-2xl font-bold mb-4">Besoin d'aide avec votre SEO ?</h3> <p class="mb-6 text-purple-100">Notre équipe d'experts peut vous aider à optimiser votre site e-commerce</p> <div class="flex flex-col sm:flex-row gap-4 justify-center"> <a href="/seo-ecommerce" class="bg-white text-purple-600 px-8 py-3 rounded-lg font-semibold hover:bg-purple-50 transition inline-block"> Découvrir nos services SEO </a> <a href="/#contact" class="bg-purple-800 text-white px-8 py-3 rounded-lg font-semibold hover:bg-purple-900 transition inline-block"> Nous contacter </a> </div> </div> </div> </article> <!-- Section Commentaires --> <div class="mt-12 max-w-4xl mx-auto bg-white rounded-2xl shadow-xl p-8 md:p-12"> <h2 class="text-3xl font-bold text-gray-900 mb-6 flex items-center gap-3"> <i class="fas fa-comments text-purple-600"></i> Commentaires </h2> <!-- Liste des commentaires approuvés --> <div id="comments-list" class="mb-8 space-y-6"> <!-- Les commentaires approuvés seront chargés ici via JavaScript --> </div> <!-- Formulaire de commentaire --> <div class="border-t border-gray-200 pt-8"> <h3 class="text-xl font-semibold text-gray-900 mb-4">Laisser un commentaire</h3> <form id="comment-form" class="space-y-4"> <input type="hidden" id="article-slug" value="agence-seo-marrakech"> <div class="grid md:grid-cols-2 gap-4"> <div> <label for="comment-name" class="block text-sm font-medium text-gray-700 mb-2">Nom *</label> <input type="text" id="comment-name" name="name" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent"> </div> <div> <label for="comment-email" class="block text-sm font-medium text-gray-700 mb-2">Email *</label> <input type="email" id="comment-email" name="email" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent"> </div> </div> <div> <label for="comment-message" class="block text-sm font-medium text-gray-700 mb-2">Message *</label> <textarea id="comment-message" name="message" rows="5" required class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent"></textarea> </div> <div class="text-sm text-gray-600"> <i class="fas fa-info-circle text-purple-600"></i> Votre commentaire sera soumis à modération avant publication. </div> <button type="submit" class="bg-gradient-to-r from-purple-600 to-blue-600 text-white px-8 py-3 rounded-lg font-semibold hover:from-purple-700 hover:to-blue-700 transition inline-flex items-center gap-2"> <i class="fas fa-paper-plane"></i> Publier le commentaire </button> </form> <div id="comment-status" class="mt-4 hidden"></div> </div> </div> <!-- Navigation Articles --> <div class="mt-12 max-w-4xl mx-auto"> <a href="/blog" class="inline-flex items-center gap-2 text-purple-600 hover:text-purple-800 transition font-semibold"> <i class="fas fa-arrow-left"></i> Retour au blog </a> </div> </div> </section> <!-- Script pour les commentaires --> <script> const articleSlug = 'agence-seo-marrakech'; // Charger les commentaires approuvés async function loadComments() { try { const response = await fetch(`/gestion-commentaires/get-comments.php?slug=${articleSlug}`); const data = await response.json(); const commentsList = document.getElementById('comments-list'); if (data.success && data.comments.length > 0) { commentsList.innerHTML = data.comments.map(comment => ` <div class="border-l-4 border-purple-600 pl-4 py-2"> <div class="flex items-center gap-2 mb-2"> <strong class="text-gray-900">${comment.name}</strong> <span class="text-sm text-gray-500">•</span> <span class="text-sm text-gray-500">${new Date(comment.date).toLocaleDateString('fr-FR')}</span> </div> <p class="text-gray-700">${comment.message}</p> </div> `).join(''); } else { commentsList.innerHTML = '<p class="text-gray-500 italic">Aucun commentaire pour le moment. Soyez le premier à commenter !</p>'; } } catch (error) { console.error('Erreur lors du chargement des commentaires:', error); } } // Gérer la soumission du formulaire document.getElementById('comment-form').addEventListener('submit', async function(e) { e.preventDefault(); const formData = { slug: articleSlug, name: document.getElementById('comment-name').value, email: document.getElementById('comment-email').value, message: document.getElementById('comment-message').value }; const submitBtn = this.querySelector('button[type="submit"]'); const originalText = submitBtn.innerHTML; submitBtn.disabled = true; submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Envoi en cours...'; try { const response = await fetch('/gestion-commentaires/submit-comment.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }); const result = await response.json(); const messageDiv = document.getElementById('comment-status'); if (result.success) { messageDiv.className = 'mt-4 p-4 bg-green-100 border border-green-400 text-green-700 rounded-lg'; messageDiv.textContent = 'Merci ! Votre commentaire a été soumis et sera publié après modération.'; messageDiv.classList.remove('hidden'); this.reset(); } else { messageDiv.className = 'mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg'; messageDiv.textContent = result.message || 'Une erreur est survenue. Veuillez réessayer.'; messageDiv.classList.remove('hidden'); } } catch (error) { const messageDiv = document.getElementById('comment-status'); messageDiv.className = 'mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded-lg'; messageDiv.textContent = 'Erreur de connexion. Veuillez réessayer plus tard.'; messageDiv.classList.remove('hidden'); } finally { submitBtn.disabled = false; submitBtn.innerHTML = originalText; } }); // Charger les commentaires au chargement de la page loadComments(); </script> <footer class="bg-gray-950 text-gray-400 py-12"> <div class="container mx-auto px-6"> <div class="flex flex-col md:flex-row justify-between items-center"> <div class="mb-6 md:mb-0 flex items-start gap-4"> <img src="/images/logo.png" alt="Logo VRAIVEX" class="h-32 w-32 md:h-40 md:w-40 object-contain"> <div> <a href="#" class="text-2xl font-bold block"> <span class="gradient-text">VRAIVEX</span> </a> <p class="mt-2 text-sm">Automatisation, IA et SEO au service de la performance e-commerce</p> </div> </div> <div class="flex flex-col items-center md:items-end"> <div class="grid grid-cols-2 md:flex md:flex-wrap gap-3 md:space-x-6 mb-4 text-center md:text-right"> <a href="/#about" class="hover:text-white transition text-sm">À propos</a> <a href="/#services" class="hover:text-white transition text-sm">Services</a> <a href="/#prestations" class="hover:text-white transition text-sm">Prestations</a> <a href="/#bestsellers" class="hover:text-white transition text-sm">Best Sellers</a> <a href="/#realisations" class="hover:text-white transition text-sm">Réalisations</a> <a href="/#brands" class="hover:text-white transition text-sm">Nos Sites</a> <a href="/creation-site-ecommerce" class="hover:text-white transition text-sm">Création Sites</a> <a href="/seo-ecommerce" class="hover:text-white transition text-sm">SEO E-commerce</a> <a href="/partenaires" class="hover:text-white transition text-sm">Partenaires</a> <a href="/#contact" class="hover:text-white transition text-sm">Contact</a> </div> <p class="text-sm text-center md:text-right">© 2026 VRAIVEX. Tous droits réservés.</p> </div> </div> </div> </footer> <!-- Back to Top Button --> <button id="backToTop" class="fixed bottom-8 right-8 bg-gradient-to-r from-purple-600 to-blue-600 text-white p-4 rounded-full shadow-lg hover:shadow-xl transform hover:scale-110 transition-all duration-300 z-50 hidden"> <i class="fas fa-arrow-up text-xl"></i> </button> <script> // Header scroll effect window.addEventListener('scroll', function() { const header = document.getElementById('header'); if (window.scrollY > 100) { header.classList.add('header-scrolled'); } else { header.classList.remove('header-scrolled'); } }); // Smooth scrolling for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); document.querySelector(this.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); }); // Mobile menu toggle const mobileMenuButton = document.getElementById('mobileMenuButton'); const mobileMenu = document.getElementById('mobileMenu'); const menuIcon = document.getElementById('menuIcon'); if (mobileMenuButton && mobileMenu) { mobileMenuButton.addEventListener('click', function() { mobileMenu.classList.toggle('hidden'); // Toggle icon between bars and times if (mobileMenu.classList.contains('hidden')) { menuIcon.classList.remove('fa-times'); menuIcon.classList.add('fa-bars'); } else { menuIcon.classList.remove('fa-bars'); menuIcon.classList.add('fa-times'); } }); // Close menu when clicking on a link const mobileLinks = mobileMenu.querySelectorAll('a'); mobileLinks.forEach(link => { link.addEventListener('click', function() { mobileMenu.classList.add('hidden'); menuIcon.classList.remove('fa-times'); menuIcon.classList.add('fa-bars'); }); }); } // Brands Carousel const brandsCarousel = document.getElementById('brandsCarousel'); const brandsContainer = document.getElementById('brandsContainer'); const brandsPrevBtn = document.getElementById('brandsPrevBtn'); const brandsNextBtn = document.getElementById('brandsNextBtn'); const brandsPrevBtnMobile = document.getElementById('brandsPrevBtnMobile'); const brandsNextBtnMobile = document.getElementById('brandsNextBtnMobile'); if (brandsContainer && brandsCarousel) { let currentIndex = 0; const cards = brandsContainer.querySelectorAll('.brand-card'); const gap = 24; const cardsPerView = { mobile: 1, tablet: 2, desktop: 3, large: 4 }; function getCardsPerView() { const w = window.innerWidth; if (w >= 1280) return cardsPerView.large; if (w >= 1024) return cardsPerView.desktop; if (w >= 768) return cardsPerView.tablet; return cardsPerView.mobile; } function getCardWidth() { const cpv = getCardsPerView(); const cw = brandsCarousel.offsetWidth; return (cw - gap * (cpv - 1)) / cpv; } function updateCarousel() { const cpv = getCardsPerView(); const cardW = getCardWidth(); const maxIdx = Math.max(0, cards.length - cpv); currentIndex = Math.min(currentIndex, maxIdx); const offset = currentIndex * (cardW + gap); brandsContainer.style.transform = `translateX(-${offset}px)`; const atStart = currentIndex === 0; const atEnd = currentIndex >= maxIdx; [brandsPrevBtn, brandsPrevBtnMobile].forEach(function(btn) { if (btn) { btn.style.opacity = atStart ? '0.4' : '1'; btn.style.pointerEvents = atStart ? 'none' : 'auto'; } }); [brandsNextBtn, brandsNextBtnMobile].forEach(function(btn) { if (btn) { btn.style.opacity = atEnd ? '0.4' : '1'; btn.style.pointerEvents = atEnd ? 'none' : 'auto'; } }); if (document.getElementById('brandsCounter')) { document.getElementById('brandsCounter').textContent = (currentIndex + 1) + ' / ' + (maxIdx + 1); } } function nextSlide() { const cpv = getCardsPerView(); const maxIdx = Math.max(0, cards.length - cpv); if (currentIndex < maxIdx) { currentIndex++; updateCarousel(); } } function prevSlide() { if (currentIndex > 0) { currentIndex--; updateCarousel(); } } if (brandsNextBtn) brandsNextBtn.addEventListener('click', nextSlide); if (brandsPrevBtn) brandsPrevBtn.addEventListener('click', prevSlide); if (brandsNextBtnMobile) brandsNextBtnMobile.addEventListener('click', nextSlide); if (brandsPrevBtnMobile) brandsPrevBtnMobile.addEventListener('click', prevSlide); function setCardWidths() { const cardW = getCardWidth(); cards.forEach(function(card) { card.style.width = cardW + 'px'; card.style.minWidth = cardW + 'px'; card.style.flexShrink = '0'; }); } let touchStartX = 0; let touchEndX = 0; brandsCarousel.addEventListener('touchstart', function(e) { touchStartX = e.changedTouches[0].screenX; }, { passive: true }); brandsCarousel.addEventListener('touchend', function(e) { touchEndX = e.changedTouches[0].screenX; const diff = touchStartX - touchEndX; if (Math.abs(diff) > 50) { diff > 0 ? nextSlide() : prevSlide(); } }, { passive: true }); setCardWidths(); updateCarousel(); let resizeTimeout; window.addEventListener('resize', function() { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(function() { setCardWidths(); currentIndex = 0; updateCarousel(); }, 250); }); } </script> <script> // Header scroll effect window.addEventListener('scroll', function() { const header = document.getElementById('header'); if (window.scrollY > 50) { header.classList.add('header-scrolled'); } else { header.classList.remove('header-scrolled'); } }); // Scroll animations const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver(function(entries) { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); } }); }, observerOptions); // Observe all fade-in-up elements document.querySelectorAll('.fade-in-up').forEach(el => { observer.observe(el); }); // Smooth scroll for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // Counter animation for stats function animateCounter(element, target, duration = 2000) { let start = 0; const increment = target / (duration / 16); const timer = setInterval(() => { start += increment; if (start >= target) { element.textContent = target + (element.textContent.includes('+') ? '+' : '') + (element.textContent.includes('K') ? 'K€' : ''); clearInterval(timer); } else { element.textContent = Math.floor(start) + (element.textContent.includes('+') ? '+' : '') + (element.textContent.includes('K') ? 'K€' : ''); } }, 16); } // Observe stats section const statsObserver = new IntersectionObserver(function(entries) { entries.forEach(entry => { if (entry.isIntersecting && !entry.target.classList.contains('animated')) { entry.target.classList.add('animated'); const statsCards = entry.target.querySelectorAll('.stats-card'); statsCards.forEach((card, index) => { setTimeout(() => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; setTimeout(() => { card.style.transition = 'all 0.6s ease'; card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, 100); }, index * 100); }); } }); }, { threshold: 0.3 }); const statsSection = document.querySelector('section.bg-gradient-to-r'); if (statsSection) { statsObserver.observe(statsSection); } </script> <script> // Gestion du formulaire de contact const contactForm = document.getElementById('contact-form'); const formMessage = document.getElementById('form-message'); const submitBtn = document.getElementById('submit-btn'); if (contactForm) { contactForm.addEventListener('submit', async function(e) { e.preventDefault(); // Désactiver le bouton pendant l'envoi submitBtn.disabled = true; submitBtn.textContent = 'Envoi en cours...'; // Récupérer les données du formulaire const formData = new FormData(contactForm); try { // Vérifier que les données sont bien dans le FormData const formDataObj = { name: formData.get('name'), email: formData.get('email'), subject: formData.get('subject'), message: formData.get('message') }; console.log('Données du formulaire:', formDataObj); // Vérifier que tous les champs sont remplis if (!formDataObj.name || !formDataObj.email || !formDataObj.subject || !formDataObj.message) { formMessage.classList.remove('hidden'); formMessage.className = 'mb-6 p-4 rounded-lg bg-red-600 text-white'; formMessage.textContent = 'Veuillez remplir tous les champs du formulaire.'; submitBtn.disabled = false; submitBtn.textContent = 'Envoyer le message'; return; } // Essayer d'abord avec JSON (plus fiable) // Siça ne fonctionne pas, on essaiera avec FormData let response; try { // Méthode 1 : Envoyer en JSON (plus fiable selon les forums) response = await fetch('gestion-formulaire-contact/send-email-json.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(formDataObj) }); } catch (jsonError) { console.warn('Erreur avec JSON, essai avec FormData:', jsonError); // Méthode 2 : Fallback avec FormData response = await fetch('send-email.php', { method: 'POST', body: formData }); } // Lire le texte de la réponse d'abord pour déboguer const responseText = await response.text(); console.log('Réponse serveur:', responseText.substring(0, 500)); // Vérifier si la réponse est OK if (!response.ok) { // Essayer de parser le JSON d'erreur try { const errorResult = JSON.parse(responseText); // Afficher le message d'erreur du serveur directement à l'utilisateur formMessage.classList.remove('hidden'); formMessage.className = 'mb-6 p-4 rounded-lg bg-red-600 text-white'; formMessage.textContent = errorResult.message || `Erreur ${response.status}: ${response.statusText}`; submitBtn.disabled = false; submitBtn.textContent = 'Envoyer le message'; return; // Sortir de la fonction pour ne pas continuer } catch (e) { throw new Error(`Erreur HTTP ${response.status}: ${response.statusText}. Réponse: ${responseText.substring(0, 200)}`); } } // Vérifier si PHP n'est pas exécuté (le serveur renvoie le code PHP brut) if (responseText.trim().startsWith('<?php') || responseText.includes('<?php')) { console.error('ERREUR: PHP n\'est pas exécuté par le serveur. Le code PHP est renvoyé brut.'); console.error('Le serveur web n\'est pas configuré pour exécuter PHP.'); // Utiliser la solution de secours : sauvegarder dans localStorage const messageData = { name: formData.get('name'), email: formData.get('email'), subject: formData.get('subject'), message: formData.get('message'), timestamp: new Date().toISOString() }; // Sauvegarder dans localStorage comme solution de secours const savedMessages = JSON.parse(localStorage.getItem('vraivex_messages') || '[]'); savedMessages.push(messageData); localStorage.setItem('vraivex_messages', JSON.stringify(savedMessages)); // Afficher un message spécial formMessage.classList.remove('hidden'); formMessage.className = 'mb-6 p-4 rounded-lg bg-yellow-600 text-white'; formMessage.innerHTML = '⚠️ PHP n\'est pas configuré sur le serveur. Votre message aété sauvegardé localement. <br>Veuillez nous contacter directement à <strong>contact@vraivex.fr</strong> ou consulter les messages sauvegardés dans la console du navigateur.'; // Afficher les messages sauvegardés dans la console console.log('Messages sauvegardés localement:', savedMessages); console.log('Pour consulter les messages, tapez dans la console: JSON.parse(localStorage.getItem("vraivex_messages"))'); return; // Sortir de la fonction } // Essayer de parser le JSON let result; try { result = JSON.parse(responseText); } catch (parseError) { console.error('Erreur de parsing JSON:', parseError); console.error('Réponse reçue:', responseText.substring(0, 500)); throw new Error('Le serveur a renvoyé une réponse invalide. Vérifiez la console pour plus de détails.'); } // Afficher le message de résultat formMessage.classList.remove('hidden'); if (result.success) { formMessage.className = 'mb-6 p-4 rounded-lg bg-green-600 text-white'; formMessage.textContent = 'Message envoyé avec succès ! Nous vous répondrons dans les plus brefs délais.'; contactForm.reset(); } else { formMessage.className = 'mb-6 p-4 rounded-lg bg-red-600 text-white'; let errorMsg = result.message || 'Une erreur est survenue. Veuillez réessayer.'; // Afficher le message de debug en développement (à retirer en production) if (result.debug) { console.error('Erreur détaillée:', result.debug); } formMessage.textContent = errorMsg; } } catch (error) { formMessage.classList.remove('hidden'); formMessage.className = 'mb-6 p-4 rounded-lg bg-red-600 text-white'; // Message d'erreur plus détaillé pour le débogage let errorMsg = 'Une erreur est survenue lors de la communication avec le serveur. '; errorMsg += 'Veuillez réessayer plus tard ou nous contacter directement à contact@vraivex.fr'; // En mode développement, afficher plus de détails if (error.message) { console.error('Erreur détaillée:', error); console.error('Message:', error.message); console.error('Stack:', error.stack); } formMessage.textContent = errorMsg; } finally { // Réactiver le bouton submitBtn.disabled = false; submitBtn.textContent = 'Envoyer le message'; // Masquer le message après 5 secondes setTimeout(() => { formMessage.classList.add('hidden'); }, 5000); } }); } // Back to Top Button functionality const backToTopButton = document.getElementById('backToTop'); // Show/hide button based on scroll position window.addEventListener('scroll', () => { if (window.pageYOffset > 300) { backToTopButton.classList.remove('hidden'); } else { backToTopButton.classList.add('hidden'); } }); // Smooth scroll to top when clicked backToTopButton.addEventListener('click', () => { window.scrollTo({ top: 0, behavior: 'smooth' }); }); </script> </body> </html>