Pilote Orléans · configuration, pas un fork · aucun lieu inventé

Livrable 21

SEO

URLs

/{city}
/{city}/maintenant
/{city}/ce-soir
/{city}/ce-week-end
/{city}/{categorySlug}          seulement si la catégorie est dans city_categories et indexable
/{city}/zones/{slug}            seule URL de zone. Pas de /quartiers.
/{city}/etablissements/{slug}
/{city}/evenements/{slug}
/{city}/guides/{slug}

restaurants, bars, concerts sont des exemples de categorySlug, pas des routes codées. Orléans brouillon n'a pas la catégorie concerts : l'URL n'existe pas tant qu'un city manager ne l'ajoute pas. Le libellé « quartier » est du vocabulaire ; le chemin reste /zones/.

city = slug (orleans). Une ville draft ou soft_launch : pas dans GET /cities public. soft_launch : URL directe réservée au staff, noindex. Anonyme : 404. Seul published est indexable.

Indexation

Indexables seulement si la page a un contenu propre et non vide :

  • accueil ville publiée ;
  • maintenant / ce soir / week-end s'il y a au moins un résultat réel au dernier rendu ; sinon noindex (une page « rien ce soir » dupliquée 365 fois est du thin content) ;
  • catégorie si assez d'entités pour être une page utile (jugement éditorial, pas un quota inventé) ;
  • zone si description ou entités réelles (un quartier est cette même page) ;
  • fiche lieu publiée ;
  • événement à venir ;
  • guide CMS publié, unique, lié à des entités.

noindex :

  • recherche interne et filtres combinés ;
  • carte interactive (/carte) — application, pas une landing ;
  • favoris, plans, compte, pro, admin ;
  • événements passés ou annulés ;
  • brouillons ;
  • pages de filtres (?terrasse=1 etc.).

Canonique : l'URL nue de l'entité. Pas de canonique vers une autre ville.

Programmatique

Autorisé si page utile, données suffisantes, intention distincte. Interdit de générer des milliers de pages quasi identiques (combinaisons zone × catégorie × heure).

Rendu

Cible prompt : SSR/ISR pour l'indexable, client pour la carte et les filtres.

Arbitrage stack : cet environnement est TanStack Start (SSR), pas Next.js. Les pages indexables sont rendues serveur. Le bloc « live » d'une fiche peut être frais ; le texte stable (nom, adresse, description) est cacheable. Il n'y a pas d'ISR Next. Équivalent : cache HTTP court sur Now, plus long sur le guide, Cache-Control différent par route. Ne pas servir une page « ce soir » figée 24 h.

Sitemap : seulement URLs indexables, généré par job, villes published. Pas de sitemap fantôme.

Données structurées

Quand les champs existent vraiment :

  • Event si dates et lieu ;
  • Restaurant / BarOrPub / NightClub / LocalBusiness selon catégorie — un seul type principal ;
  • Organization pour l'éditeur du site ;
  • BreadcrumbList.

Ne pas émettre un champ aggregateRating sans avis réels. Ne pas émettre offers.price si prix inconnu. Conformité Google : à vérifier au moment du balisage, pas affirmée ici.

Hreflang

FR seulement au MVP. Structure prête (default_locale), pas de fausses langues.

Décisions

D1 — Le live n'est pas une ferme SEO

  • Choix : pages stables indexées ; états instantanés en noindex si vides.
  • Risque : moins de long-tail. Assumé (règle anti-thin).
  • Multi-ville : le template est unique ; Google voit des villes seulement quand elles sont published.

D2 — Slugs français figés pour le pilote

etablissements, evenements. Un changement de slug = redirections 301 à prévoir, donc on ne les « internationalise » pas dans l'URL au MVP.

Flags

  • Aucune performance SEO affirmée.
  • Contenu Orléans : EXTERNAL DATA REQUIRED avant indexation.