Ai

Guide technique SEO local prêt-production : pratiques avancées

Damien LarqueyDamien Larquey
February 23, 2026
5 min read
Guide technique SEO local prêt-production : pratiques avancées




Guide technique SEO local prêt-production

Guide technique SEO local prêt-production

En 60–120 minutes, posez une base solide pour capter le « map pack », les requêtes « near me » et la recherche vocale/IA. Niveau intermédiaire/avancé. Focus : précision, performance, sécurité, observabilité.

1) Objectif

Livrer un site prêt-production optimisé pour le SEO local :

  • Cohérence NAP (Name, Address, Phone).
  • Pages de localisation et de services structurées.
  • Balisage JSON-LD LocalBusiness, FAQPage et AggregateRating complet et conforme aux directives Google.
  • Redirections et canonicals fiables (Nginx sans if, <link rel="canonical"> absolus).
  • Core Web Vitals mobile-first, HTTP/2, compression, cache long.
  • Sitemaps partitionnés et indexés.
  • Intégration API Google Business Profile (OAuth2 et service accounts, quotas dynamiques, backoff idempotent).
  • Observabilité : GA4, Search Console, GBP Insights, Lighthouse CI, audit logs.

2) Prérequis

  • Accès au code, serveur/proxy (Nginx compilé HTTP/2, Brotli ou CDN), DNS.
  • Comptes Google Search Console, GA4, identifiants OAuth2 et/ou service account (domain-wide delegation) pour GBP API.
  • Environnements dev/staging/prod, CI/CD, gestion des logs et alertes.
  • Budget estimé : audit 500–2 000 $, pages 50–200 $ l’unité.

3) Implémentation pas à pas

Étape 1 – TLS/HTTP2, redirections & canonicals

Évitez les if et l’en-tête Link dynamique ; préférez une règle de réécriture et des balises <link rel="canonical"> absolues.

Visualizing how local SEO connects a business with nearby customers across maps, search, and reviews.
Visualizing how local SEO connects a business with nearby customers across maps, search, and reviews.
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;
    ssl_certificate     /etc/ssl/certs/example.crt;
    ssl_certificate_key /etc/ssl/private/example.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    root /var/www/html;

    # Réécrire sans 'if' pour forcer le slash final
    rewrite ^([^.]*[^/])$ $1/ permanent;

    location / {
      try_files $uri $uri/ =404;
    }
}

Dans chaque <head> :

<link rel="canonical" href="https://example.com/chemin/page/" />

Étape 2 – Core Web Vitals mobile-first

  • Compression Brotli + gzip fallback :
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/javascript application/json image/svg+xml;
  • Cache-control long (1 an, immutable) pour assets.
  • Images AVIF/WebP, srcset, loading="lazy", fetchpriority.
  • Inline critical CSS, preconnect, defer/async JS.

Étape 3 – JSON-LD LocalBusiness, FAQPage, AggregateRating

Rendu server-side dans le <head> ou début du <body>. Exemple pour une boulangerie :

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Bakery",
  "name": "Boulangerie Dupont",
  "@id": "https://example.com/lyon/cordeliers/",
  "url": "https://example.com/lyon/cordeliers/",
  "image": ["https://example.com/static/storefront.webp"],
  "telephone": "+33 4 72 00 00 00",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "12 Rue des Cordeliers",
    "addressLocality": "Lyon",
    "addressRegion": "Auvergne-Rhône-Alpes",
    "postalCode": "69002",
    "addressCountry": "FR"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 45.7597,
    "longitude": 4.8340
  },
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
      "opens": "07:00",
      "closes": "19:00"
    }
  ],
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": 4.7,
    "reviewCount": 132
  },
  "sameAs": [
    "https://www.facebook.com/boulangeriedupont",
    "https://www.instagram.com/boulangeriedupont"
  ]
}
</script>

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Livrez-vous à domicile ?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Oui, livraison sur Lyon pour toute commande supérieure à 20 €."
      }
    }
  ]
}
</script>

Note : respectez les politiques Google sur les avis (minimum 5 avis pour AggregateRating, données modérées onsite). Évitez les balises dupliquées entre pages.

Diagram of the phased approach to building and scaling a local SEO program.
Diagram of the phased approach to building and scaling a local SEO program.

Étape 4 – Pages localisation & services

  • URL structurées (/ville/quartier/, /services/nom-service/), contenu riche > 300 mots.
  • Inclure intro locale, NAP, horaires, CTA (appel/itinéraire), carte, FAQ, visuels, témoignages.
  • Maillage interne : relier chaque service à ses localisations et vice-versa.

Étape 5 – API Google Business Profile & synchronisation

  • OAuth2 recommandée pour compte individuel (flow standard, accès/refresh tokens).
    Voir : https://developers.google.com/my-business/content/authorization
  • Service accounts : nécessite domain-wide delegation et n’est pas pris en charge pour tous les profils. Stocker tokens et clés privées dans un vault sécurisé, mettre en place rotation régulière.
  • Quotas : récupérer dynamiquement via l’API GET /quota, n’hésitez pas à ajuste le backoff
  • Idempotence : joindre un requestId (UUID v4) à chaque requête et/ou exploiter l’ETag pour des requêtes conditionnelles (If-Match, If-None-Match).
  • Backoff exponentiel avec jitter et plafonnement :
async function patchWithBackoff(payload) {
  const maxAttempts = 6;
  const baseDelay = 1000; // ms
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const requestId = uuidv4();
    const headers = { "X-Request-Id": requestId };
    if (etag) headers["If-Match"] = etag;
    const resp = await sendPatch(payload, headers);
    if (resp.ok) return resp;
    if (![429, 500, 502, 503, 504].includes(resp.status)) {
      throw new Error(`API error ${resp.status}`);
    }
    // Exponential backoff with jitter and cap
    const cap = 30000; 
    const delay = Math.min(cap, baseDelay * 2 ** (attempt - 1));
    const jitter = Math.random() * baseDelay;
    await sleep(delay + jitter);
  }
  throw new Error('Échec après plusieurs tentatives'); 
}

Étape 6 – Sitemaps & robots.txt

Partitionnez si > 50 000 URL, listez les sous-sitemaps dans sitemap-index.xml.

User-agent: *
Disallow: /search
Allow: /

Sitemap: https://example.com/sitemap-index.xml

Étape 7 – Crawl-budget & indexation

  • Identifiez les pages low-value (thin content) : noindex ou fusion.
  • Priorisez pages de conversion et zones stratégiques.
  • Attribuez priority et changefreq dans les sitemaps.

4) Vérification & tests automatisés

  • curl -I https://example.com/lyon/cordeliers/ → statut 200, HTTP/2, SSL ok, balise canonical.
  • Rich Results Test CLI/API pour LocalBusiness et FAQPage.
  • Lint JSON-LD (outil Google ou npm ld lint).
  • Lighthouse CI : perf ≥ 0.80, accès ≥ 0.90, LCP < 2.5 s, CLS < 0.1.
  • Search Console : couverture sans erreurs, sitemaps valides.
  • GA4 : événements et UTMs GBP remontés.
  • GBP : vérifiez la consistance des horaires et consultez les audit logs.

5) Dépannage courant

  • Contenu dupliqué : revérifiez vos canonical, enrichissez ou fusionnez.
  • Horaires site/GBP divergents : cron job de sync + alertes.
  • Rich results absents : assurez-vous du rendu SSR du JSON-LD.
  • Écarts CWV staging/prod : comparer cache, network et RUM.
  • Suspension GBP : ralentissez la cadence, conservez logs et requestId.
  • Problèmes NAP sur mobile : ne modifiez que l’affichage CSS, JSON-LD reste inchangé.

6) Prochaines étapes

Planifiez des revues mensuelles : audits Core Web Vitals, Rich Results, couverture SEO. Automatisez alertes via webhook Search Console, exportez GBP Insights. Formez l’équipe pour maintenir la cohérence NAP et les horaires à jour.

Connecting real-world local searches on mobile with website analytics and business outcomes.
Connecting real-world local searches on mobile with website analytics and business outcomes.

Damien Larquey

Damien Larquey

Author at Codolie

Passionate about technology, innovation, and sharing knowledge with the developer community.

Back to Blog