50 jours de SEO en B2B nettoyage : 194 pages dans Yandex et +86 % de clics GSC

50 jours ouvrés depuis le relancement du site : 194 pages indexées dans Yandex, +86 % de clics GSC, Lighthouse 93/100. Zéro lien payant, zéro agence.

Le 22 mars 2026, j’ai lancé un nouveau site pour l’entreprise de propreté où je travaille comme directeur marketing en interne. 50 jours ouvrés plus tard : 194 pages dans l’index Yandex, +86 % de clics et +90 % d’impressions d’un mois sur l’autre dans Google Search Console, Lighthouse Performance 93/100 sur mobile, CLS 0,002. Zéro lien payant, zéro agence, zéro prestataire. Site PHP 8.4 fait maison, 245 URLs dans le sitemap.

En bref

  • 245 URLs en 50 jours : 51 services, 18 quartiers de Saint-Pétersbourg, 70 stations de métro, 12 villes satellites, 50+ articles de blog.
  • 194 pages en Yandex Searchable. Au départ le 13 avril : 111. Au 5 mai : 194-201 (ça oscille).
  • 92 pages récupérées de l’état ‘Excluded by noindex’ via recrawl API + IndexNow + lastmod.
  • +86 % de clics GSC et +90 % d’impressions d’un mois sur l’autre (52 → 97 clics, 2 826 → 5 359 impressions).
  • Lighthouse mobile : Performance 93, SEO 100, CLS 0, LCP 2,4 s, TBT 60 ms.
  • SEO Health Score interne : 62 → 84 en 18 jours.

Ci-dessous, semaine par semaine : ce que j’ai fait, quelles corrections ont vraiment bougé les chiffres, et là où j’ai trébuché.

Le point de départ, 22 mars

22 mars, c’était l’initial commit d’un projet PHP vide fait maison. Pas de CMS, pas de build pipeline, pas de node_modules. Six pages système (accueil, tarifs, à propos, contacts, licences, confidentialité) et 18 pages services. Le reste, devant moi.

J’ai choisi une stack volontairement simple :

  • PHP 8.4 sur hébergement mutualisé, sans CMS
  • .htaccess en routeur, pattern /uborka-metro-{slug}/uborka-metro-{slug}.php
  • MySQL pour le blog, les leads et l’AggregateRating dynamique
  • CSS directement dans le repo, JS vanilla, pas de bundler, pas de transpileur
  • Inter auto-hébergé (woff2), pas de Google Fonts

Pourquoi cette stack. L’entreprise avait déjà un site - vieux et lourd. Je ne pouvais pas me permettre une migration de six mois vers une ‘stack moderne’. Il me fallait un démarrage rapide, le contrôle de chaque octet du markup, et la capacité à corriger le schema sans bataille avec les plugins CMS. Le PHP fait maison couvre les trois, et sert du HTML en millisecondes.

Semaine par semaine

Semaines 1-2 : technique et formulaires

Première chose : l’anti-spam des formulaires. Six filtres, sans captcha : un honeypot <input name="website" style="display:none">, regex pour URLs dans le commentaire, longueur du téléphone entre 10 et 11 chiffres, ratio de non-cyrillique sur les commentaires de plus de 5 caractères, rate-limit à 5 requêtes par heure par IP, log dans un spam_log.txt protégé. Le captcha ajoute +5 de friction utilisateur ; ces filtres bloquent 99 % du spam sans captcha.

Ensuite CSP avec une whitelist pour GA4, Yandex Metrica, Roistat, AmoCRM, Beget CDN. HSTS preload, Referrer-Policy, X-Frame-Options. Tokens CSRF sur chaque POST.

Toute l’analytics enveloppée dans requestIdleCallback(fn, {timeout: 3000}) - GA4, Metrica et Roistat ne bloquent pas le rendu. Le preconnect pour l’analytics n’a pas marché - la connexion expirait avant utilisation, gâchant des ressources. dns-prefetch a suffi.

À la fin de la semaine 2 : Inter auto-hébergé avec @font-face size-adjust: 107%; ascent-override: 90% basé sur Arial - a tué le décalage FOUT qui rongeait le CLS.

Semaine 3 : premier audit, cartographie du site

5 avril : premier audit SEO complet via 7 sous-audits parallèles : contenu / E-E-A-T, technique SEO, on-page, schema, Core Web Vitals, AI Search Readiness, images. Pondérations : 23/22/20/10/10/10/5 %. Score 62/100. Principaux trous : schema (LocalBusiness dupliqué sur 30+ pages), CLS 0,377, XSS inline dans js/main.js, mot de passe admin en MD5.

Au 8 avril, tout fermé : un bloc LocalBusiness multi-type avec @id dans le footer, les pages référencent par @id au lieu de répéter ; CLS 0,377 → 0,002 en une journée ; XSS corrigé via createElement + textContent ; mot de passe admin passé en SHA-256 + salt. Au 10 avril, score 72.

En parallèle, passage du site dans Screaming Frog, 474 URLs trouvées : 245 utiles, le reste des versions obsolètes et des stubs de templates. 43 pages métros avec contenu mince (~230 mots) retirées du sitemap.

Semaine 4 : Programmatic SEO - 100 pages

À partir du 16 avril, journée programmatic : j’ai rempli 39 stations de métro + 18 quartiers + 12 villes satellites avec du contenu unique. Un template, du contenu unique - $district_content, $metro_content, $city_content injectés dans metro-template.php, district-template.php, lo-template.php partagés. Seuil d’unicité par page : au-dessus de 45 %, vérifié via Screaming Frog Near Duplicates.

Pour éviter le risque doorway, chaque page a :

  • Un H1 et H2 uniques (pas de phrases template style ‘Nettoyage dans le quartier X’)
  • Une section ‘Spécificités locales’ de 200 à 300 mots sur le quartier ou le métro
  • 3-5 FAQ spécifiques à la localisation
  • Tarifs, délai d’intervention de l’équipe, adresse du site actif le plus proche

Mon Programmatic SEO Score interne est ressorti à 95/100. C’est sur le template, pas sur le ranking réel - ça je vérifierai dans les impressions GSC dans 3-4 mois.

Semaine 5 : vague blog

9 avril : vague une, 21 articles publiés en une journée. 17 avril : vague deux, 10 de plus. Fin avril, 50+ articles dans le blog, 1 500 à 4 000 mots chacun, chacun avec :

  • Schema BlogPosting + FAQPage + QAPage
  • 4-5 questions FAQ, vraies requêtes tirées de Wordstat et People Also Ask
  • 3+ liens internes : un vers un service, un vers un autre article, un vers /price/ ou contacts
  • Un Author Person avec rel="author" sur dimaserbun.ru
  • Une bannière Pexels (licence libre), plus une version JPEG séparée pour Yandex Zen

Cadence après les deux vagues : 2-3 articles par semaine. Pas plus de 5 par jour, et pas de backdating de 50 articles sur un mois - ça crame les templates de filtres des moteurs. Le 6 mai j’ai redistribué 11 posts prêts sur la plage 20-30 avril pour que la densité de publication paraisse régulière.

Semaine 6 : citabilité IA et récupération Excluded

24-26 avril, trois chantiers en parallèle.

Récupération des Excluded. 13 avril : 56 pages en Excluded sur Yandex. 22 avril : 92. La moitié du site. Via Yandex Webmaster API → /recrawl/queue j’ai envoyé 37 articles de blog en recrawl (quota : 620 URLs par jour) plus IndexNow ping pour 70 URLs métro. Au 5 mai : 1 page restante en Excluded sur 93. La plupart sont revenues en Searchable, maintenant 194-201.

Audit GEO et AI Overviews. Scores par plateforme : Google AIO 58, ChatGPT web search 48, Perplexity 62, Bing Copilot 64. Total 61/100. Principales corrections : passages de 134 à 167 mots sous H2 sur 5 pages clés, avec la réponse directe dans les 40 à 50 premiers mots + classe .answer-block pour speakable ; H2 reformulés en questions (‘Quel nettoyage convient à votre type d’appartement ?’ au lieu de ‘Nettoyage par type d’appartement’) ; crawlers IA autorisés dans robots.txt - GPTBot, OAI-SearchBot, ClaudeBot, anthropic-ai, Google-Extended, PerplexityBot, CCBot, YouBot, cohere-ai, Bytespider, meta-externalagent. Plus llms.txt à la racine du site au format llmstxt.org - H1, blockquote de description, sections H2 avec listes, immatriculation / ISO / notes.

Glossaire. 26 avril : page /glossary/ avec 45 termes du nettoyage + schema DefinedTermSet. Maillage interne - 188 liens vers /glossary/#anchor depuis le corps des pages - ça envoie un signal structurel ‘ce site a son propre vocabulaire’ et ouvre la voie aux citations IA.

Semaine 7 : niveau A et B, expansion des templates

5 mai : pack confiance et YMYL.

Niveau A (confiance) : preconnect vers le domaine CDN, preload mobile de l’image hero, AggregateRating dynamique depuis MySQL dans le schema, tableau AreaServed de 31 villes (18 quartiers de Saint-Pétersbourg + 12 oblast de Leningrad + Saint-Pétersbourg). Retrait des marques du corps des pages quand elles n’étaient pas strictement factuelles - Karcher, Koch Chemie, autres - gardées seulement où elles sont de vrais faits produits.

Niveau B (YMYL) : sur les pages nettoyage après décès et nettoyage post-incendie - liens vers la licence Rospotrebnadzor, SanPiN 3.3686-21, 1.2.3685-21, 2.1.3684-21, en lien hypertexte vers consultant.ru. Pour les niches YMYL, c’est critique : Google et Yandex pénalisent durement les pages sans validation d’autorité.

6 mai : expansion des templates uborka-N-komnatnoj via analyse SERP des concurrents : 1 500 → 1 700-1 900 mots, FAQ 5 → 10. Expansion du template métro : FAQ 3 → 5, ajout d’une section ‘Préparation’, SEO-text. Recrawl de 70 URLs via IndexNow.

7 mai : check croisé GSC + Yandex Webmaster. 39 URLs envoyées en recrawl, correction du flux RSS Yandex Zen (suppression du h1 en double, conversion des tableaux en listes).

Les cinq corrections qui ont vraiment bougé les chiffres

Si je dois choisir les cinq décisions à plus fort impact :

DécisionEffet
Un bloc LocalBusiness avec @id dans le footerSchema plus dupliqué sur 30+ pages, Rich Results Test propre
Inter auto-hébergé avec fallback size-adjust:107 %CLS 0,377 → 0,002 en une journée
100 pages programmatic quartiers/métros à 45 %+ d’unicité+44 pages dans l’index Yandex en 11 jours (111 → 155)
Yandex Webmaster API recrawl + IndexNow + lastmodRécupération de 92 sur 93 pages depuis Excluded
Passages de 134-167 mots avec réponse directe dans les 40-50 premiersGain de position sur le cluster ‘nettoyage appartements Saint-Pétersbourg’ : moyenne 28,8 → 16-24

Les chiffres

MétriqueDépart (mars)24 avril5 mai
Clics GSC / mois5297 (+86 %)en croissance
Impressions GSC / mois2 8265 359 (+90 %)jusqu’à 595/jour
Position moyenne GSC28,827,316-24
Yandex Searchable111 (13.04)155194-201
Yandex Excluded56 (13.04)921
CLS0,377-0
LCP mobile~4,5 s-2,4 s
Lighthouse Performance~60-70-93/100
SEO Health Score6272 (10.04)84 (23.04)

Top requêtes Yandex par impressions au 7 mai : ‘services de nettoyage Saint-Pétersbourg prix’ - 103 impressions, ‘nettoyage industriel prix au m²’ - 79, ‘coût nettoyage’ - 77, ‘nettoyage Saint-Pétersbourg’ - 72. Sur les clics : requêtes de marque dans le top-3, plus ‘nettoyage entreprises industrielles’ et ‘nettoyage parkings souterrains’ (27 impressions en position 6, après la réécriture H2 et FAQ).

La suite

Sur ma liste à la fin de la séquence 50 jours :

  • Chaîne YouTube + 5 vidéos - corrélation avec les citations IA à 0,737, le signal le plus fort
  • Entrée Wikidata pour l’entreprise
  • Reddit - 10 à 15 réponses d’expert par mois
  • Page LinkedIn entreprise
  • 6 annuaires en première vague : Cleannow, Orgpage, Cataloxy, Rosfirm, Spr, Profi.ru
  • 1-2 publications dans la presse business de Saint-Pétersbourg → ensuite Wikipedia ru
  • llms-en.txt - version anglaise pour les IA globales

Bilan. Un nouveau site peut atteindre un état où Yandex maintient 200 pages dans l’index et où les clics GSC doublent, en 50 jours, sans budget liens. Conditions : tout à la main, pas de thème CMS clé en main pour la niche, contrôle direct sur schema et performance, discipline de cadence blog, recrawl via API.

Si vous avez un site B2B sur une niche locale et qu’il faut accélérer le SEO de manière structurelle, écrivez-moi sur Telegram @dimik90.

À lire aussi : comment je travaille - sans blabla, sans propositions de 40 pages.

Questions fréquentes

Combien coûte le SEO d'une entreprise de propreté à Saint-Pétersbourg, en partant de zéro ?
Dans ce cas, le budget pour les liens payants et les agences SEO est de zéro. Je gère le marketing en interne comme directeur marketing, et j'écris moi-même le code, le contenu, le schema et le maillage interne. Outils : Google Search Console, Yandex Webmaster, Yandex Metrica, Wordstat, Screaming Frog (licence freelance), quelques serveurs MCP. À titre de comparaison : une offre agence 'SEO pour services à partir de 50 000 roubles par mois' couvre la partie technique, le contenu et les ajustements réguliers - c'est le marché de Saint-Pétersbourg en 2026.
Combien de temps avant de voir les premiers résultats dans Yandex pour un nouveau site ?
Les premières impressions et clics arrivent dès la semaine 2-3 après le lancement, mais ce sont des requêtes para-marque. La vraie croissance sur les mots-clés de niche démarre en semaine 5-6, une fois que j'ai bouclé le cluster programmatic de 100 pages quartiers et métros, et la vague blog de 21 articles. Au jour 50 : 194 pages en Searchable Yandex, +86 % de clics GSC. Pour un nouveau domaine, sans historique et sans backlinks payants.
Liens ou contenu, par quoi commencer ?
Ni l'un ni l'autre, dans mon cas. La première chose c'est la technique : anti-spam des formulaires, schema correct, sitemap propre, balises title et description correctes, CLS en zone verte, crawlers IA autorisés dans robots.txt. Sans ça, liens et contenu coulent dans un seau percé. Le contenu, je l'ai monté en parallèle de la technique. Les liens, je les ai laissés pour plus tard - annuaires un par jour, plus 5 mentions 'best of' dans des classements de niche.
Peut-on faire pareil dans une autre niche, pas le nettoyage ?
L'approche oui, les chiffres non. Le template programmatic quartiers/métros marche dans les niches services locaux : nettoyage, rénovation, livraison, désinfection, transport. La cadence blog 2-3 articles par semaine est universelle. La checklist performance et schema est générale. Mais les volumes de requêtes et la densité de la concurrence varient par niche, donc il faut trouver les points de levier dans votre propre recherche de mots-clés.
Quels outils ont apporté le plus ?
Yandex Webmaster API pour le recrawl (quota : 620 URLs par jour) - a ramené 92 pages depuis Excluded vers Searchable. IndexNow - Bing et Yandex voient une nouvelle URL en heures plutôt qu'en semaines. Screaming Frog - a trouvé 43 pages avec contenu mince, retirées du sitemap, réécrites et remises. API Wordstat - a constitué un noyau de 861 phrases sur 20 clusters. Lighthouse - relancé jusqu'au vert après chaque lot de corrections. Sans ces outils, j'aurais bossé à l'aveugle.