Le local pack tel qu'on le connaît est en train de mourir
Jusqu'ici, Google Maps fonctionnait comme un index classique : une requête, une liste de résultats triés par proximité, pertinence et prominence. Les tests récents d'Ask Maps — la couche conversationnelle intégrée à Google Maps — renversent ce paradigme. Au lieu de présenter 10 fiches ordonnées, l'interface génère des recommandations contextuelles : "Pour un brunch avec des enfants en bas âge, essayez X plutôt que Y, car Z propose une aire de jeux intérieure et des menus adaptés."
Ce n'est plus un classement. C'est une sélection éditoriale automatisée par un LLM, alimentée par vos données structurées, vos avis, vos photos et les signaux comportementaux de Maps. Et quand l'IA recommande trois établissements au lieu d'en lister vingt, la visibilité des dix-sept restants tombe à zéro.
Comment Ask Maps reconstruit la couche de ranking local
Du tri par score au filtrage par intention
Le local pack traditionnel repose sur trois piliers documentés par Google : la pertinence (matching entre la requête et la catégorie/attributs du Business Profile), la distance (proximité géographique), et la prominence (signaux web, volume d'avis, note moyenne). Ces trois facteurs produisent un score composite, et les résultats sont triés.
Ask Maps introduit une rupture : le modèle ne trie plus, il filtre puis synthétise. L'utilisateur pose une question en langage naturel — "Quel garage peut changer mes plaquettes de frein sur une BMW série 3 avant samedi ?" — et le système doit comprendre l'intention multi-facettes (service spécifique + marque du véhicule + contrainte temporelle), éliminer les résultats non qualifiés, puis formuler une réponse argumentée.
Cette mécanique ressemble fortement à ce qu'on observe dans les AI Overviews pour la recherche web : un passage d'un modèle de ranking (tous les résultats sont affichés, ordonnés) à un modèle de retrieval-augmented generation (seuls les résultats servant la réponse sont surfacés).
Les signaux qui gagnent en poids
Dans un système de recommandation IA, certains signaux deviennent critiques :
- Les attributs structurés du Business Profile : heures d'ouverture précises, services listés, attributs spécifiques (accessibilité PMR, terrasse, WiFi gratuit). Ce sont les données que le LLM utilise pour filtrer.
- Le contenu des avis : pas seulement la note moyenne, mais le texte des avis. Un LLM peut extraire "bon pour les familles" ou "spécialiste BMW" à partir de 500 avis, même si aucun attribut officiel ne le mentionne.
- Les photos et leur classification : Google applique déjà du computer vision sur les photos uploadées. Une terrasse visible sur les photos = un signal "terrasse" même sans attribut déclaré.
- La fraîcheur des données : un LLM qui génère une recommandation pour "ce samedi" doit s'appuyer sur des horaires à jour. Un établissement dont les horaires n'ont pas été mis à jour depuis six mois risque d'être exclu par précaution.
Ce shift est cohérent avec ce que Sundar Pichai décrit comme la transformation de Search en gestionnaire d'agents IA, et avec la montée en puissance du search agentic qui transforme les requêtes simples en tâches complexes décomposées.
Données structurées : le nouveau champ de bataille du local
LocalBusiness Schema — le minimum ne suffit plus
La plupart des fiches locales implémentent un LocalBusiness schema basique : nom, adresse, téléphone, horaires. Dans un modèle de listing classique, c'est suffisant — le tri se fait surtout côté Google Business Profile. Dans un modèle de recommandation, chaque attribut manquant est un critère de filtrage perdu.
Voici un exemple de schema enrichi pour un restaurant qui veut être surfacé dans les recommandations Ask Maps :
{
"@context": "https://schema.org",
"@type": "Restaurant",
"name": "Le Comptoir du Marais",
"address": {
"@type": "PostalAddress",
"streetAddress": "47 Rue de Bretagne",
"addressLocality": "Paris",
"postalCode": "75003",
"addressCountry": "FR"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 48.8631,
"longitude": 2.3619
},
"telephone": "+33142789012",
"servesCuisine": ["Française", "Bistronomique"],
"priceRange": "€€",
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "12:00",
"closes": "14:30"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "19:00",
"closes": "22:30"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Saturday"],
"opens": "12:00",
"closes": "23:00"
}
],
"amenityFeature": [
{"@type": "LocationFeatureSpecification", "name": "Terrasse", "value": true},
{"@type": "LocationFeatureSpecification", "name": "Accessible PMR", "value": true},
{"@type": "LocationFeatureSpecification", "name": "Chaise haute disponible", "value": true}
],
"acceptsReservations": true,
"hasMenu": {
"@type": "Menu",
"url": "https://lecomptoirdumarais.fr/carte",
"hasMenuSection": [
{
"@type": "MenuSection",
"name": "Menu Déjeuner",
"hasMenuItem": [
{
"@type": "MenuItem",
"name": "Formule entrée + plat",
"offers": {
"@type": "Offer",
"price": "18.50",
"priceCurrency": "EUR"
},
"suitableForDiet": "https://schema.org/GlutenFreeDiet"
}
]
}
]
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.6",
"reviewCount": "847"
}
}
Les champs amenityFeature, hasMenu avec les MenuItem détaillés et les indications diététiques (suitableForDiet) sont rarement implémentés. Pourtant, dans un système de recommandation, ce sont exactement les données qui permettent au LLM de répondre à "restaurant sans gluten avec terrasse dans le Marais pour un déjeuner à moins de 20€".
Vérifier l'implémentation à l'échelle
Pour une chaîne de 150 points de vente, vérifier manuellement que chaque page location a un schema complet et à jour est irréaliste. Un script d'audit automatisé est indispensable :
import requests
import json
from bs4 import BeautifulSoup
from urllib.parse import urljoin
STORE_URLS_FILE = "store_locator_urls.txt" # une URL par ligne
REQUIRED_FIELDS = [
"name", "address", "geo", "telephone",
"openingHoursSpecification", "amenityFeature",
"aggregateRating", "servesCuisine", "priceRange"
]
def extract_jsonld(html: str) -> list[dict]:
soup = BeautifulSoup(html, "html.parser")
scripts = soup.find_all("script", type="application/ld+json")
schemas = []
for script in scripts:
try:
data = json.loads(script.string)
if isinstance(data, list):
schemas.extend(data)
else:
schemas.append(data)
except json.JSONDecodeError:
continue
return schemas
def audit_local_schema(url: str) -> dict:
resp = requests.get(url, timeout=10, headers={"User-Agent": "SEO-Audit/1.0"})
schemas = extract_jsonld(resp.text)
local_schemas = [
s for s in schemas
if s.get("@type") in ["LocalBusiness", "Restaurant", "Store",
"AutoRepair", "HealthAndBeautyBusiness"]
or (isinstance(s.get("@type"), list) and
any(t in ["LocalBusiness", "Restaurant", "Store"] for t in s["@type"]))
]
if not local_schemas:
return {"url": url, "status": "NO_LOCAL_SCHEMA", "missing": REQUIRED_FIELDS}
schema = local_schemas[0]
missing = [f for f in REQUIRED_FIELDS if f not in schema or not schema[f]]
# Vérifier la fraîcheur des horaires (présence de tous les jours)
hours = schema.get("openingHoursSpecification", [])
declared_days = set()
for spec in hours:
days = spec.get("dayOfWeek", [])
if isinstance(days, str):
days = [days]
declared_days.update(days)
all_days = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}
missing_days = all_days - declared_days
return {
"url": url,
"status": "OK" if not missing else "INCOMPLETE",
"missing_fields": missing,
"missing_days": list(missing_days),
"review_count": schema.get("aggregateRating", {}).get("reviewCount", 0)
}
# Exécution
with open(STORE_URLS_FILE) as f:
urls = [line.strip() for line in f if line.strip()]
results = [audit_local_schema(url) for url in urls]
incomplete = [r for r in results if r["status"] != "OK"]
print(f"Audit terminé : {len(incomplete)}/{len(results)} fiches incomplètes")
for r in incomplete:
print(f" {r['url']} — manque: {r['missing_fields']} — jours manquants: {r['missing_days']}")
Ce script vérifie la présence des champs critiques et détecte les horaires incomplets (un dimanche non déclaré = un risque d'exclusion pour une requête "brunch dimanche"). Pour un site headless qui génère ses pages location via une API, le même type de vérification devrait s'intégrer dans le pipeline CI/CD.
Scénario concret : chaîne de fitness avec 85 salles en France
Prenons FitPulse, une chaîne fictive mais réaliste de 85 salles de sport en France. Chaque salle a sa page sur fitpulse.fr/salles/{ville}-{quartier}, générée dynamiquement via une stack Next.js + API headless. Le trafic organique local représente 38% des inscriptions (mesuré via attribution Google Analytics 4 avec segmentation par landing page /salles/*).
L'état avant Ask Maps
- 85 pages location, chacune avec un schema
LocalBusinessbasique (nom, adresse, téléphone, horaires) - Note Google moyenne : 4.2 (12 400 avis au total)
- Positions moyennes dans le local pack pour "{sport} + {ville}" : 2.8
- Trafic organique local : ~18 000 visites/mois
- Pas d'attributs détaillés dans le Google Business Profile (types de cours, équipements spécifiques)
Ce qui change avec le modèle recommandation
Un utilisateur demande à Ask Maps : "Salle de sport avec piscine et cours de yoga le soir à Lyon 6ème". Le LLM doit croiser :
- La catégorie (salle de sport)
- Un équipement spécifique (piscine)
- Un service spécifique (cours de yoga)
- Une contrainte horaire (le soir)
- Un périmètre géographique (Lyon 6ème)
Si la fiche GBP de FitPulse Lyon 6ème ne mentionne pas explicitement "piscine" comme attribut, et si le schema de la page location ne liste pas les cours avec leurs horaires, la salle est invisible pour cette requête — même si elle a la meilleure note du quartier.
Le plan d'action technique
Phase 1 — Enrichissement du schema (semaine 1-2)
Passer de LocalBusiness à SportsActivityLocation (sous-type de LocalBusiness dans schema.org). Ajouter les amenityFeature pour chaque équipement. Créer des Event imbriqués pour les cours récurrents avec Schedule :
{
"@context": "https://schema.org",
"@type": "SportsActivityLocation",
"name": "FitPulse Lyon 6ème",
"address": { "...": "..." },
"amenityFeature": [
{"@type": "LocationFeatureSpecification", "name": "Piscine 25m", "value": true},
{"@type": "LocationFeatureSpecification", "name": "Sauna", "value": true},
{"@type": "LocationFeatureSpecification", "name": "Parking gratuit", "value": true}
],
"event": [
{
"@type": "ExerciseAction",
"name": "Yoga Vinyasa",
"location": {"@type": "Place", "name": "Salle 2"},
"eventSchedule": {
"@type": "Schedule",
"byDay": ["https://schema.org/Tuesday", "https://schema.org/Thursday"],
"startTime": "19:30",
"endTime": "20:30",
"repeatFrequency": "P1W"
}
}
]
}
Phase 2 — Synchronisation GBP (semaine 2-3)
Utiliser l'API Google Business Profile pour pousser les attributs structurés en masse. Compléter tous les attributs disponibles dans la catégorie "salle de sport" : types d'équipements, accessibilité, services spécifiques. S'assurer que les horaires de chaque salle sont à jour (un script CRON hebdomadaire qui compare les horaires en base avec ceux du GBP via l'API).
Phase 3 — Monitoring des régressions (continu)
Le problème des données locales à 85 points de vente : elles se dégradent. Un manager local modifie ses horaires dans le CMS mais pas sur GBP. Un déploiement front casse le schema JSON-LD d'une page. Un avis négatif non répondu fait baisser la note sous le seuil critique.
Un outil de monitoring comme Seogard permet de détecter automatiquement la disparition d'un schema LocalBusiness sur une page location, ou un changement dans les horaires structurés qui ne serait pas reflété côté GBP. Sans ce type de surveillance, les régressions passent inaperçues pendant des semaines — exactement le temps qu'il faut pour disparaître des recommandations Ask Maps.
Impact estimé
Après enrichissement, FitPulse peut raisonnablement s'attendre à :
- Couverture de requêtes long-tail locale multipliée : au lieu de matcher seulement "salle de sport Lyon 6", la salle devient éligible pour des dizaines de combinaisons (piscine + yoga + soir, musculation + parking + matin, etc.)
- Augmentation du CTR local de 15-25% (les recommandations Ask Maps incluent des justifications textuelles — "cette salle propose des cours de yoga en soirée et dispose d'une piscine" — ce qui est un format beaucoup plus engageant qu'un simple listing)
- Mais aussi un risque : si un concurrent enrichit mieux ses données, le système de recommandation peut le préférer même s'il est moins bien noté
Comment surveiller votre visibilité dans un monde post-listing
Les métriques Google Search Console à re-interpréter
Search Console n'offre pas encore de rapport spécifique "Ask Maps recommendations". Mais plusieurs signaux indirects sont exploitables :
- Rapport Performances > Apparence dans les résultats : surveillez les impressions pour le type "Résultats locaux". Une chute sans changement de position classique peut indiquer une exclusion des recommandations IA.
- Requêtes longues : filtrez les requêtes par longueur (6+ mots). Si votre trafic sur les requêtes courtes ("restaurant Paris") se maintient mais que les requêtes long-tail ("restaurant terrasse sans gluten dimanche midi Paris 3") ne génèrent plus d'impressions, vous êtes probablement filtré par le système de recommandation.
- Rapport "Insights" dans le GBP dashboard : les tendances de recherche par catégorie montrent comment les utilisateurs trouvent votre fiche. Un shift de "recherche directe" vers "recherche par catégorie" indique une dépendance accrue au matching par attributs.
Pour aller plus loin dans l'analyse des écarts d'intention, la méthodologie décrite dans cet article sur la mesure des intent gaps via GSC est directement applicable au local : identifiez les requêtes où vous avez des impressions mais un CTR anormalement bas, ce sont celles où le système de recommandation vous a listé mais pas recommandé.
Scraper les résultats Ask Maps pour votre catégorie
Pour les équipes qui veulent aller plus loin, un monitoring des résultats Ask Maps via SerpAPI ou un scraping maison permet de tracker qui est recommandé pour vos requêtes cibles :
// Exemple simplifié avec Puppeteer pour capturer les résultats Ask Maps
// Attention : respectez les ToS de Google et utilisez des proxies appropriés
import puppeteer from 'puppeteer';
const QUERIES = [
"salle de sport avec piscine Lyon 6",
"meilleur yoga studio Lyon Part-Dieu",
"gym avec parking gratuit Villeurbanne"
];
async function captureAskMapsResults(query: string) {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
// Simuler un mobile (Ask Maps est principalement mobile)
await page.setViewport({ width: 412, height: 915, isMobile: true });
await page.setUserAgent(
'Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36'
);
await page.goto(`https://www.google.com/maps/search/${encodeURIComponent(query)}`, {
waitUntil: 'networkidle2',
timeout: 30000
});
// Attendre le chargement des résultats Ask Maps (sélecteur susceptible de changer)
await page.waitForSelector('[data-result-type="recommendation"]', { timeout: 10000 })
.catch(() => console.log(`Pas de recommandations IA pour: ${query}`));
// Extraire les business recommandés
const results = await page.evaluate(() => {
const items = document.querySelectorAll('[data-result-type="recommendation"]');
return Array.from(items).map((item, index) => ({
position: index + 1,
name: item.querySelector('[class*="fontHeadlineSmall"]')?.textContent?.trim(),
justification: item.querySelector('[class*="fontBodyMedium"]')?.textContent?.trim(),
rating: item.querySelector('[aria-label*="stars"]')?.getAttribute('aria-label'),
}));
});
await browser.close();
return { query, results, timestamp: new Date().toISOString() };
}
// Exécution séquentielle pour éviter le rate limiting
(async () => {
for (const query of QUERIES) {
const data = await captureAskMapsResults(query);
console.log(JSON.stringify(data, null, 2));
await new Promise(r => setTimeout(r, 5000)); // pause 5s entre chaque requête
}
})();
Ce type de monitoring est fragile (les sélecteurs CSS changent fréquemment), mais il donne une vision directe de qui est recommandé et pourquoi — la "justification" générée par le LLM est particulièrement instructive pour comprendre quels signaux le modèle exploite.
Les limites et trade-offs du modèle recommandation
Le risque de concentration winner-takes-all
Dans un listing de 20 résultats, être en position 8 génère encore du trafic. Dans une recommandation qui ne mentionne que 3 établissements, être le 4ème = être invisible. Ce modèle accentue mécaniquement la concentration du trafic local vers les top performers.
Pour les petits commerces sans ressources SEO, c'est une menace directe. Pour les chaînes avec une équipe technique, c'est une opportunité de creuser l'écart — à condition d'investir dans la qualité des données structurées.
L'hallucination appliquée au local
Les LLM hallucinent. Appliquer un LLM à des recommandations locales signifie qu'il peut inventer des attributs ("ce restaurant dispose d'une terrasse chauffée" alors que ce n'est pas le cas), recommander un établissement fermé, ou confondre deux adresses. Google mitige ce risque en s'appuyant sur des données structurées vérifiées (GBP), mais le risque zéro n'existe pas.
En tant que business, cela signifie que vos données structurées doivent être irréprochables — non seulement pour être recommandé, mais aussi pour éviter qu'une hallucination ne génère une recommandation erronée à votre sujet.
La question de l'attribution
Comment mesurer si une visite en magasin provient d'une recommandation Ask Maps plutôt que d'un listing classique ? Aujourd'hui, Google ne fournit pas cette granularité dans les rapports GBP. L'attribut utm_source n'est pas applicable (l'utilisateur clique sur "Itinéraire" dans Maps, pas sur un lien web). C'est un angle mort analytique que Google devra résoudre pour que le modèle soit viable commercialement (les annonceurs locaux veulent savoir ce qu'ils payent).
Ce que ça change pour le contenu de vos pages location
Les pages location ne doivent plus être de simples wrappers autour d'une carte et d'une adresse. Dans un monde où le LLM extrait des signaux textuels pour qualifier une recommandation, le contenu de la page location devient un signal de premier ordre.
Concrètement :
- Descriptions détaillées des services : pas "nous proposons des cours collectifs", mais "17 cours collectifs par semaine dont Yoga Vinyasa (mardi et jeudi 19h30), HIIT (lundi/mercredi/vendredi 7h00), et Pilates Reformer (samedi 10h00)".
- FAQ structurées : les questions que les utilisateurs posent à Ask Maps ("est-ce qu'il y a un parking ?", "est-ce adapté aux débutants ?") doivent avoir des réponses explicites sur la page, balisées en
FAQPageschema. - Avis intégrés : le contenu des avis Google repris sur la page (avec le balisage
Reviewschema) fournit un signal textuel supplémentaire au crawler.
C'est un changement de paradigme pour les équipes qui gèrent des store locators : la page location passe d'un asset SEO secondaire (juste pour capter "{service} + {ville}") à un hub de données structurées qui alimente directement le système de recommandation Maps.
Pour les sites e-commerce avec des points de retrait, le même raisonnement s'applique aux product feeds : les données produit structurées alimentent les recommandations shopping dans Maps ("magasin qui a {produit} en stock près de moi").
L'intersection avec les agents IA et le futur du local
Ask Maps n'est pas un produit isolé. Il s'inscrit dans la trajectoire que Google trace depuis les AI Overviews jusqu'aux agents IA capables d'exécuter des tâches. Demain, un utilisateur ne demandera plus "quel restaurant pour ce soir" — il dira "réserve-moi une table dans un restaurant italien avec terrasse pour 4 personnes samedi à 20h, budget 40€ par personne, à moins de 15 minutes de chez moi". L'agent Ask Maps devra sélectionner, recommander et réserver.
Ce scénario rend l'optimisation pour les moteurs de réponse IA directement applicable au local SEO. Les business qui structurent leurs données pour être lisibles par des agents — disponibilité en temps réel, réservation via API, menus à jour — seront recommandés. Les autres seront progressivement exclus du funnel de conversion.
La transition d'Ask Maps des listings vers les recommandations n'est pas un test de plus. C'est le signal que le local SEO entre dans l'ère agentique. Les fiches Google Business Profile deviennent des interfaces machine-to-machine avant d'être des interfaces humaines. Structurez vos données en conséquence — et mettez en place un monitoring continu avec un outil comme Seogard pour détecter le moindre attribut manquant ou la moindre régression de schema avant que l'IA ne vous filtre silencieusement.