Pourquoi le SEO programmatique pour les pages locales ?
Si vous êtes plombier à Lyon, serrurier à Marseille, ou consultant IT à Alger, vous avez besoin d'une page dédiée pour chaque ville que vous couvrez. Problème : rédiger 50 pages uniques à la main prend des semaines.
Le SEO programmatique pages locales résout ce problème en combinant une base de données structurée, des templates dynamiques et de l'IA générative pour produire du contenu unique à grande échelle.
Chez Otomy, nous avons déployé cette méthode pour des clients B2B en France et en Algérie. Résultat : +340% de trafic organique local en 3 mois sur un site de services IT.
L'architecture technique en 5 couches
Avant de foncer, voici l'architecture complète du système :
- Base de données → Supabase (PostgreSQL managé)
- Génération de contenu → Claude AI via API
- Orchestration → n8n (self-hosted) ou Make
- Frontend dynamique → Next.js déployé sur Vercel
- Monitoring SEO → Google Search Console + Screaming Frog
Étape 1 : Préparer la base de données des villes
Créez une table cities dans Supabase avec les colonnes suivantes :
CREATE TABLE cities (
id SERIAL PRIMARY KEY,
city_name TEXT NOT NULL,
department TEXT,
region TEXT,
population INTEGER,
slug TEXT UNIQUE NOT NULL,
meta_title TEXT,
meta_description TEXT,
content TEXT,
status TEXT DEFAULT 'draft'
);
Injectez vos 50 villes cibles. Pour la France, utilisez le fichier open data des communes de l'INSEE. Pour l'Algérie, la liste des wilayas suffit souvent.
Astuce Otomy : Ajoutez une colonne local_signals (TEXT) pour stocker des données contextuelles — nom du quartier principal, activité économique dominante, population. Claude AI utilisera ces signaux pour personnaliser chaque page.
Étape 2 : Générer le contenu avec Claude AI
Créez un workflow n8n avec les nœuds suivants :
- Trigger : Cron ou déclenchement manuel
- Supabase Node : Récupérer les villes avec
status = 'draft' - HTTP Request : Appeler l'API Claude (Anthropic) avec un prompt structuré
- Supabase Node : Mettre à jour la ligne avec le contenu généré
Voici le prompt que nous utilisons (adapté à votre activité) :
Tu es un rédacteur SEO expert. Rédige une page de service locale pour un {type_de_service} à {city_name} ({department}).
Contexte local : {local_signals}
Structure obligatoire :
- H1 incluant la ville et le service
- Introduction de 80 mots mentionnant la ville naturellement
- Section "Nos services à {city_name}" avec 4-5 puces
- Section "Pourquoi choisir [entreprise] à {city_name} ?" avec 3 arguments
- Paragraphe de 100 mots sur la zone géographique couverte
- CTA final avec mention de la ville
Contraintes :
- 500-700 mots
- Ton professionnel mais accessible
- Pas de contenu générique interchangeable entre villes
- Keyword principal : "{service} {city_name}"
Point crucial : Le champ local_signals fait toute la différence entre du contenu spinner et du contenu réellement utile. Mentionnez le marché local, les quartiers, les axes routiers. Google détecte le contenu interchangeable.
Étape 3 : Construire les pages dynamiques avec Next.js
Dans votre projet Next.js (App Router), créez une route dynamique :
app/services/[slug]/page.tsx
import { createClient } from '@supabase/supabase-js'
export async function generateStaticParams() {
const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_KEY!)
const { data: cities } = await supabase.from('cities').select('slug').eq('status', 'published')
return cities?.map((city) => ({ slug: city.slug })) || []
}
export default async function LocalPage({ params }: { params: { slug: string } }) {
const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_KEY!)
const { data: city } = await supabase.from('cities').select('*').eq('slug', params.slug).single()
return (
<article>
<h1>{city.meta_title}</h1>
<div dangerouslySetInnerHTML={{ __html: city.content }} />
</article>
)
}
Déployez sur Vercel avec ISR (Incremental Static Regeneration) pour que chaque nouvelle ville soit indexable immédiatement.
Étape 4 : Le maillage interne automatique
Le SEO programmatique pages locales ne fonctionne que si les pages sont interconnectées. Ajoutez automatiquement :
- Un footer local avec les liens vers les 5 villes les plus proches
- Une page hub
/services/listant toutes les villes avec ancres optimisées - Un sitemap dynamique généré par Next.js (
app/sitemap.ts)
// app/sitemap.ts
export default async function sitemap() {
const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_KEY!)
const { data: cities } = await supabase.from('cities').select('slug, updated_at').eq('status', 'published')
return cities?.map((city) => ({
url: `https://votresite.com/services/${city.slug}`,
lastModified: city.updated_at,
})) || []
}
Étape 5 : Contrôle qualité avant publication
Ne publiez jamais sans relecture. Voici notre checklist chez Otomy :
- Chaque page mentionne la ville au moins 5 fois naturellement
- Le
meta_titlefait moins de 60 caractères et inclut ville + service - La
meta_descriptionfait moins de 155 caractères - Aucune page n'est un copier-coller d'une autre (utilisez Screaming Frog pour détecter le near-duplicate)
- Les données structurées
LocalBusinesssont présentes (schema.org) - Les pages chargent en moins de 2 secondes (Vercel + ISR = OK)
Passez les 50 pages dans Screaming Frog en mode liste pour vérifier les balises, les duplications et les erreurs techniques en 10 minutes.
Calendrier réaliste : 1 semaine
| Jour | Tâche |
|---|---|
| Lundi | Recherche de mots-clés locaux + préparation de la BDD Supabase |
| Mardi | Configuration du workflow n8n + prompt engineering Claude AI |
| Mercredi | Génération des 50 contenus + première relecture |
| Jeudi | Développement du template Next.js + maillage interne |
| Vendredi | QA Screaming Frog + schema.org + déploiement Vercel |
Les erreurs qui tuent vos pages locales
- Contenu interchangeable : Si vous pouvez remplacer le nom de la ville sans que ça change le sens, Google le verra aussi.
- Pas de signaux locaux : Mentionnez les quartiers, les zones d'activité, les spécificités régionales.
- Oublier le mobile : 70% des recherches locales sont mobiles. Testez chaque template.
- Négliger la vitesse : Une page locale qui met 4 secondes à charger ne rankera pas. Le combo Next.js + Vercel + ISR règle ce problème.
Conclusion
Le SEO programmatique pages locales n'est plus réservé aux grandes entreprises. Avec Supabase, Claude AI, n8n et Next.js, une PME peut déployer 50 pages locales optimisées en une semaine — pour une fraction du coût d'une rédaction manuelle.
Chez Otomy, nous accompagnons les PME en France et en Algérie dans cette transformation. Si vous voulez dominer les résultats locaux de votre secteur, contactez-nous pour un audit gratuit.