1 of 54

Stratégie d’Architecture SEO pour le ecommerce

2 of 54

Qui suis-je ?

Bruno vial

10+ xp en SEO (ciblo, iProspect, cruiseline.eu)

Focus technical : data, programmation

Ex SEO, Actuellement consultant digital & data chez converteo

@zenobral sur twitter

J’écris parfois sur le blog de madeline pinthon (@razbithume) : http://www.canyouseome.com/

3 of 54

Qu’est ce qu’un site bien architecturé ?

  • TOUT son bon contenu d’indexé
  • RIEN que son bon contenu d’indexé
  • Facile à analyser
  • Facile à corriger
  • Favorise la circulation du PageRank Interne (PRI)
  • Qui vous laisse vous concentrer sur le développement des opportunités et non pas sur le comblement des lacunes

4 of 54

Les vraies difficultés arrivent car le site vit

  • Création de nouvelles fonctionnalités
  • Les mises en prod du vendredi
  • Les migrations
  • Les catégories qui bougent

5 of 54

Et l’enfer, c’est les autres

On va tout migrer en Août sur MongoDB, tous les urls vont changer. C’est le meilleur moment il n’y a personne

Freddy CTO

On a réorganisé toutes les catégories du site, parce que l’internaute n’y comprenait rien. Si j’ai regardé les stats de nav sur GA ? Il y a ça dedans ?

Jason UX

On a renommé tous les titres des guides et des produits pendant tes vacances. Si les URLs ont changé ? C’est quoi un URL ?

Reine (alien) de l’édito

6 of 54

On se parle de quoi ?

  • La base de tout : les urls
  • Optimiser le PRI avec le cryptage de liens

7 of 54

Patterns d’urls

8 of 54

Pourquoi se soucier du format des urls ?

Pour placer des keywords dans l’url ? -> NON !

Plutôt pour :

  • éviter la duplication de contenu
  • les catégoriser facilement
  • gérer des urls expirés
  • gérer facilement le multilingue
  • gérer une migration facilement

9 of 54

Ce qu’on retrouve couramment

Produit ou catégorie ?

/homme/chaussures/adidas-predator

duplicate ?

/homme/chaussures/adidas-predator

/adidas/chaussures/adidas-predator

C’est bien le même contenu dans deux langues différentes ? Comment faire le matching automatiquement quand j’analyse ? Et mon hreflang il est bon ou pas ?

site.fr/homme/chaussures/adidas-predator

site.it/uomo/scarpe/adidas-predator

Mais c’est qui lui ? un doublon ?

/homme/chaussures/addidas-predator

Et lui ?

/homme/chaussures/adidas-predator-2

10 of 54

Tu l’as voulu ? tu l’as eu !

Ton idée de départ

Ton site

11 of 54

Idée générale sur le format des urls

Rester au plus proche des concepts imposés par le framework du site

  • plus rapide à développer
  • plus facile à recetter
  • moins de chance à casser lors des itérations de développement

L’URL devrait illustrer au plus proche :

  • quelle table est utilisée
  • quel id
  • quelle vue

12 of 54

Framework mvc

13 of 54

Avec un produit c’est plus clair ?

Url Produit

Template de la page produit

Entrée produit dans la database

14 of 54

La database doit probablement ressembler à ceci

Id

nale

desc

category id

brand id

Id

name

desc

Id

name

desc

table produit

table marque

table catégorie

Id

name

desc

text

table éditos

15 of 54

Keep it simple: un exemple de format

Id

name

desc

category id

brand id

5

adidas predator

table produit

url

16 of 54

Et ca donne ?

  • /produit-5-adidas-predator
  • /marque-5-adidas
  • /edito-124-choisir-sa-taille-de-chaussures
  • /categorie-4-chaussures-homme

17 of 54

L’indicateur de table peut être réduit au minimum

  • /p-5-adidas-predator
  • /m-5-adidas
  • /e-124-choisir-sa-taille-de-chaussures
  • /c-4-chaussures-homme

Idéal pour le multilingue, car on s’épargne la traduction de la correspondance de la route/contrôleur

18 of 54

Avec variante multilingue

Id

category id

lang

name

desc

1

4

fr

chaussures home

2

4

it

scarpe uomo

table catégorie langue

Id

internal name

4

chaussures homme

table categorie

site.fr/c-4-chaussures-homme

site.it/c-4-scarpe-uomo

19 of 54

Qu’est ce que j’y gagne ?

Produit ou catégorie ? → produit

/p-5-adidas-predator

duplicate ? → oui

/c-4-homme/c-7-chaussures/p-5-adidas-predator

/m-7-adidas/c-7-chaussures/p-5-adidas-predator

Et mon hreflang il est bon ou pas ? → tout bon gaston

site.fr/c-4-homme/c-7-chaussures/p-4-adidas-predator

site.it/c-4-uomo/c-7-scarpe/p-4-adidas-predator

Mais c’est qui lui ? un doublon ? → oui

/c-4-homme/c-7-chaussures/p-4-addidas-predator

Et lui ? → non

/c-4-homme/c-7-chaussures/p-35-adidas-predator-2

20 of 54

Duplication liée à l’arborescence

Je n’utilise jamais de folders dans l’url pour représenter l’arborescence dans le site

21 of 54

Eliminez l’arbo du site dans l’url !

/c-4-homme/c-7-chaussures/p-5-adidas-predator → /p-5-adidas-predator

/m-7-adidas/c-7-chaussures/p-5-adidas-predator → /p-5-adidas-predator

Aussi simple que ca !

22 of 54

Des fois, d’autres s’en mêlent….

Mais on a besoin de l’arbo dans l’url pour analyser les performances du contenu !

Faites réaliser une vraie configuration dans Google Analytics pour analyser les contenus… l’outil est fait pour ca

(c’est moi)

23 of 54

Génération et lecture

Id

name

desc

category id

brand id

5

adidas predator

table produit

url

Quand le site “génère” l’url, il va utiliser les trois informations : table, id slug

En revanche, quand on “demande” l’url depuis le navigateur, seules les informations de table et d’id sont importantes pour retrouver l’entrée.

Le slug est purement décoratif !

Id

name

desc

category id

brand id

5

adidas predator

table produit

url

générer

lire

24 of 54

Changement de slug et redirection auto

Avec ce pattern d’url il est TRES SIMPLE de gérer les redirections automatique en cas de changement de slug

request url

does request url match generated url ?

return page

301 to generated url

yes

no

25 of 54

Et la vie est plus belle

On a changé tous les titres des éditos. Il faut peut être que fasses une repasse globale sur les urls ! (j’ai appris entre temps)

Tout est géré automatiquement. Bon, je te rappelle je suis au bar

(c’est encore moi)

26 of 54

Du coup les urls restent toujours “flats” ?

Pas forcément, mais la constitution de l’url ne devrait pas dépendre de la manière dont les pages sont rattachées les unes aux autres “éditorialement”.

Pensez par exemple à des “liseuses”

On peut les rattacher à un univers “livres”?

→ /u-5-livres/c-18-liseuses

Mais pourquoi pas un univers “tablettes” ?

-> /u-23-tablettes/c-18-liseuses

27 of 54

La règle du sous ensemble

My Rule : Je peux mettre un répertoire dans l’URL dès que je recense des éléments qui sont un sous ensemble de l’élément parent.

  • Les produits de la marque X qui sont en promotion
  • Les produits de la catégorie Y qui sont de la marque X

Vous avez dit facettes ?

28 of 54

Croisement avec une autre table

Si vous avez déjà des entrées pour chacune des tables pour le site, alors représentez l'intersection avec la même nomenclature

m-5-adidas

c-12-baskets

/c-12-baskets/m-5-adidas

29 of 54

Sélection sur un critère

Si c’est simplement un critère, il faut “inventer” une “route-slug” et s’y tenir

m-4-adidas

WHERE promo=True

/m-4-adidas/promotion

30 of 54

On retombe sur de la duplication de contenu ?

Il est courant que l’on puisse descendre par différents parcours sur le site.

Les parcours “marque->catégorie” et “catégorie -> marque” sont hyper classiques

On aboutit à des trucs non désirables comme ca :

/m-5-adidas

/c-12-baskets

/m-5-adidas/c-12-baskets

/c-12-baskets/m-5-adidas

/c-12-baskets

/m-5-adidas

31 of 54

Solution : ordonnancement des routes

Définissez en amont un ordre des routes qui définira comment elles doivent se chevaucher si elles se croisent. Cela peut être simplement alphabétique, ou stocké dans une table

  1. c (les catégories
  2. destockage
  3. e (edito)
  4. m (les marques)
  5. p (les produits)
  6. promotions (promotions)
  • c + m → c>m
  • c + destockage → c>destockage
  • promotion + m → m>promotion

32 of 54

Résolution des intersections

Il suffit ensuite de faire la spec au dev pour qu’il respecte l’ordre des routes lors des croisements

No more duplicates !

/m-5-adidas

/c-12-baskets

/c-12-baskets/m-5-adidas

/c-12-baskets

/m-5-adidas

33 of 54

Et on peut dormir tranquille

On a refait toute l’arborescence des catégories pendant tes vacances, il parait qu’il vaut mieux lancer un crawl? (j’ai fait des progrès en seo)

Les catégories ne sont pas liées les unes aux autres dans les urls. Normalement, rien ne doit avoir bougé. Je te laisse, je finis ma bière

34 of 54

Ah non merde on l’avait oublié

Bon la migration c’est le 17 Août, c’est ok de ton côté ?

Je te montre un truc

35 of 54

Gérer une migration avec ces formats

Lors d’une migration de site, on a tendance généralement à conserver les mêmes typologies de pages

Le vrai “risque” est que les ids changent, car changement de base de données.

Toutefois les développeurs font (quasi) systématiquement un import automatique, et il est relativement simple de conserver une table de référence “ancien id <-> nouvel id”

Là encore l’id dans l’url est votre ami !

36 of 54

Les redirections avec apache: rewritemap

Apache possède une fonctionnalité appelée rewritemap : https://httpd.apache.org/docs/2.4/fr/rewrite/rewritemap.html

Il suffit pour chaque typologie de page de créer une map de correspondance d’ids:

  • marques → marques.map
  • products → products.map
  • categories → categories.map
  • editos → editos.map

37 of 54

rewriterules

Le fichier de conf (htaccess ou vhost) devra ensuite posséder une rewriterule pour chaque typologie d’url

  • rewriterule m-(\d+)-([^/]+) /m-${marques.map:$1}-$2 (toutes les marques)
  • rewriterule c-(\d+)-([^/]+) /c-${categories.map:$1}-$2 (toutes les categories)
  • rewriterule c-(\d+)-([^/]+)/m-(\d+)-([^/]+) /c-${categories.map:$1}-$2/m-${marques.map:$3}-$4 (catégories + marque)
  • etc …

Cela parait barbare, mais c’est en réalité très simple pour la personne dont c’est le métier et peu prompt à erreurs

38 of 54

Normalement c’est tranquille

C’est bon, j’ai lu la doc, c’est easy pour nous. Tu payes ta bière après ?

Lets go !

39 of 54

Cryptage de liens

40 of 54

Différencier cryptage et cloaking

Cloaking

  • sanctionnable par Google si identifié comme tromperie délibérée de l’internaute
  • en identifiant googlebot (user-agent + reverse DNS) et en délivrant une réponse différente à l’internaute et au moteur
  • Généralement pour (pas bien) :
    • protéger son réseau de liens
    • Indexer des pages de bouillie et rediriger l’internaute vers la money page
  • Parfois pour ( ok) :
    • Laisser passer ggbot sur des pages bloquées par des règles d’ip ( Vidéos non diffusables aux usa)
    • Présenter des pages optimisées facilitant le travail de ggbot ( prerender pour site full JS, masquer des liens inutiles)

Cryptage

  • A priori autorisé
  • en “transformant” des balises standards en lien html sur action de l’utilisateur
  • Pour :
    • empêcher google d’aller crawler des pages “inutiles” de votre site
    • Maîtriser le nombre de vrais liens par page

41 of 54

Crypter ou robots.txt

Robots.txt

Pour :

  • simple à éditer
  • résout le problème de budget de crawl

Contre :

  • Perte de PRI : les liens bloqués comptent mais sont perdus
  • Difficile de faire du fine tuning par type et valeur de facette

Cryptage

Pour :

  • Résout le problème de budget de crawl
  • Conserve le PRI
  • Fine tuning complet

Contre :

  • Potentiellement long et complexe à mettre en place si le site est gros

42 of 54

Comment fonctionne (basiquement) ggbot ?

  1. récupère l’url à explorer depuis le sched/queue
  2. download la page
  3. parse le html de la page
  4. extrait les liens (où ce qui y ressemble)
  5. les ajoute à au sched/queue
  6. boucler

En temps 2 :

  1. rendering JS des pages crawlées
  2. parsing
  3. extraction des liens
  4. mise en queue des nouveaux éléments

43 of 54

Pas de lien pour google

Google n’est pas capable de “deviner” des actions utilisateur à réaliser

Donc si on veut cacher un lien :

  • On crée un élément html standard (<span> par exemple)
  • On le stylise avec des CSS comme un lien (ou bouton, etc…)
  • Au clic on déclenche une fonction qui va rediriger l’internaute, ou charger le nouveau contenu dans la page (ajax)

html element styled as link

click

function(){

document.location.href= …

}

44 of 54

Level 1 : Version simple

  • Le lien est encodé en base64
  • au clic on décode le lien et on redirige

<span data-content=”aHR0cHM6Ly93d3cuc2VvZ29vZHZpYmVzLmNvbS8=” data-crypted>anchor text</span>

base64 encoded url

45 of 54

Level 2 : more control

Si on se base sur le format d’url précédemment appris, on peut générer un url à partir des attributs définis dans le html du <span>

<span

data-controler=”p”

data-id=”7”

data-slug=”polo-blanc”

data-crypted

>anchor</span>

46 of 54

Level 3+ : imagination is your limit

Des sites utilisent des systèmes complexe avec récupération du contexte du lien, de la page, postent les infos vers une API qui répond avec le contenu.

Cdiscount, par exemple, utilise simplement une méthode “updateJsonPage” pour gérer les facettes non désirées (pas forcément dédiée qu’aux facettes)

Au sein d’un même groupe de filtre (marque par ex) , on a tantôt un vrai lien, tantôt un <span>

To study : https://www.cdiscount.com/bricolage/outillage/outillage-electroportatif/ponceuse/l-166010103.html

47 of 54

La décoration de lien

  • La décoration de lien est une technique semblable
  • On a de base un vrai lien !
  • Au clic on emmène sur une version “enrichie” avec un paramètre
  • Pour conserver le “jus” vers le lien original

Lien original

/c-32-pantalon

Lien décoré

/c-32-pantalon?param=value

48 of 54

Ne perdez pas de temps à crypter n’importe quoi

Le “nous contacter” dans le Footer !!

Cela ne sert à rien !!

(Voir les formations des frères Peyronnet sur le surfer raisonnable)

49 of 54

On crypte les facettes inutiles

Les facettes mal utilisées sont un gaspillage énorme de crawl et PageRank interne.

Posez vous la question :

  • Est-ce que ma facette est recherchée ?
  • Est-ce que j’ai suffisamment de produits pour que l’internaute soit satisfait ?

Le bon taux d’ouverture dépend essentiellement de la popularité de votre site.

Si tout est fermé ouvrez doucement… et inversement

Checkez vos logs et vos statistiques de visite

Les facettes mériteraient une présentation à part

50 of 54

La pagination...

  • Toujours un paramètre : p, page → gratuit lors d’une redirection
  • L’accessibilité des produits ne “doit” pas se reposer sur la pagination, pour des raisons de sémantique
  • Est-ce que ca intéresse google /c-99-homme?p=37 ? Bof…
  • Segmentez correctement votre site
  • Et cryptez la pagination !
  • On peut assurer un “fallback” en la laissant au dernier niveau de profondeur

51 of 54

Le méga menu ?

  • Avoir 600 liens dans un menu sur toutes les pages met votre siloing complètement à plat
  • En général je préfère ne pas crypter :
    • Liens uniquement vers les catégories de niveau 1
    • reste du menu chargé en ajax
    • siloing assuré par un menu contextuel (menu latéral) sur les pages internes
  • Si vraiment on n’a pas le choix :
    • Tous niveaux accessibles depuis la home
    • Dès qu’on est dans une page de level1+ on crypte les entrées du menu auxquelles la page n’est pas “liée”
  • Des variantes sont bien sûr possibles

52 of 54

On décore les liens contextualisant un produit

L’ux impose parfois d’ouvrir un produit dans un certain contexte :

  • Un ingrédient dans une recette
  • Une vidéo dans une playlist
  • Un produit avec une certaine photo mise en avant
  • Un hôtel avec un prix mis en avant pour une date donnée

On gère cela de cette manière :

  • param pour le contexte : /p-75-levis-501?color=black
  • canonical vers la page source : /p-75-levis-501
  • On décore le lien permettant d’y accéder

53 of 54

Le mot de la fin

  • Appliquer ces recommandations rend beau et heureux
  • Cela reste un point de vue, il y a d’autres méthodes viables
  • Ne cassez pas tout tout de suite et n’appliquez pas bêtement, comprenez l’esprit
  • Mais s’il y a une refonte, c’est le moment de s’y mettre

NB : j’aime les UX, les Editos, et surtout les Devs qui sont toujours mes potes

54 of 54

Merci !

Des questions ?