Qualité du code HTML
Structure sémantique du HTML public de Giggr : un seul titre de niveau 1 par page, repères ARIA, microdata Schema.org (Person, Event, Organization) et images responsives.
Sémantique HTML
Chaque page publique s'appuie sur des repères de structure explicites :
header,
nav,
main et
footer sur toutes les pages, plus
article et
section pour les contenus listés
(cartes profil, annonces). La navigation porte un
aria-label explicite et un lien
d'évitement « Aller au contenu principal » ouvre chaque page.
La hiérarchie de titres suit une règle stricte : un seul
h1 par page. Sur les
pages applicatives, ce h1 est le
titre du site (« Bienvenue sur Giggr. », masqué visuellement mais lu par
les lecteurs d'écran) ; le titre de la page est alors un
h2. Les pages d'authentification,
au gabarit dédié, portent directement leur propre
h1 (« Se connecter », « Créer un
compte »). La validation fine est faite avec Total Validator.
Erreurs connues
Les 73 erreurs relevées sont en réalité une seule et même
erreur, répétée : E620,
« attribute is not allowed ». Et chacune porte sur un attribut ajouté
par Livewire
(wire:navigate,
wire:current…) ou
Alpine.js
(x-data,
@click,
:aria-expanded…). Ce sont les
attributs par lesquels ces frameworks branchent l'interactivité dans le
HTML : ils ne font pas partie de la spécification que Total Validator
contrôle, d'où le signalement. L'outil les range d'ailleurs lui-même
parmi les attributs « destinés à JavaScript ».
Rien de tout cela ne touche à la sémantique du document : la hiérarchie de titres, les repères de structure et la microdata restent valides, le DOCTYPE est bien HTML5, et aucune erreur ne concerne la structure elle-même. Reste qu'un rapport aussi rouge, ça pique un peu les yeux.
Plans de titres des pages publiques
Relevé réel des titres, page par page. Un seul
h1, puis une descente de niveaux
sans saut. Les titres de repères de navigation (en-tête et pied de page)
sont présents pour les lecteurs d'écran, mais masqués visuellement
(sr-only).
- h1 Bienvenue sur Giggr. titre de site, sr-only
- h2 La musique est une passion qui se partage
- h2 Ils nous font confiance
- h2 Le projet qui t'attend est déjà en ligne
- h2 Les annonces du moment
- h3 titre de chaque annonce répété par carte
- h2 Tout ce qu'il te faut, au même endroit
- h3 Trouve ton partenaire
- h3 Publie une annonce
- h3 Rejoins la communauté
- h2 Trouve le profil qu'il te manque
- h2 Ils sont déjà sur Giggr.
- h3 nom de chaque profil répété par carte
/explorer/profils
- h1 Bienvenue sur Giggr. sr-only
- h2 Explorer titre de page
- h2 Filtres
- h3 Rayon
- h3 Instruments
- h3 Genres
- h2 Profils
- h3 nom de chaque profil répété par carte
/explorer/annonces
- h1 Bienvenue sur Giggr. sr-only
- h2 Explorer titre de page
- h2 Filtres
- h3 Rayon
- h3 Instruments
- h3 Genres
- h2 Annonces
- h3 titre de chaque annonce répété par carte
- h1 Bienvenue sur Giggr. sr-only
- h2 Contact
- h2 Envoyez-nous un message
- h2 Questions fréquentes
- h1 Bienvenue sur Giggr. sr-only
- h2 Politique de confidentialité
- h2 Préambule
- h2 Données que nous collectons
- h2 Finalités du traitement
- h2 Durée de conservation
- h2 Partage avec des tiers
- h2 Tes droits
- h2 Nous contacter
- h1 Se connecter resp. « Créer un compte », gabarit auth, titre de page direct
- h2 Rejoins la scène
Microdata
Les contenus pertinents exposent des données structurées
Schema.org en microdata (attributs
itemscope,
itemtype,
itemprop dans le HTML), vérifiables
au Rich Results Test de Google et au Schema Markup Validator.
| Type Schema.org | Où | Propriétés principales |
|---|---|---|
| Person | Cartes profil, fiche musicien | name, url, image, address, knowsAbout |
| Event | Cartes annonce, fiche annonce | name, description, location, organizer |
| Organization | Pied de page | name, url, logo |
| PostalAddress, Place | Imbriqués (localisation) | address, addressLocality |
Exemple réel : la carte d'un profil décrit une
Person avec une
PostalAddress imbriquée pour la
ville.
<div itemscope itemtype="https://schema.org/Person">
<link itemprop="url" href="{{ route('profile', ['id' => $profile->id]) }}">
<img src="{{ $profile->medium }}" alt="Photo de {{ $name }}" itemprop="image">
<h3 itemprop="name">{{ $name }}</h3>
<span itemprop="address" itemscope itemtype="https://schema.org/PostalAddress">
<span itemprop="addressLocality">{{ $profile->city->name }}</span>
</span>
</div>
Images responsives
Deux stratégies, selon l'origine de l'image.
Visuels éditoriaux (hero, sections illustrées) : servis
en plusieurs variantes via srcset
et sizes, au format
WebP, avec dimensions déclarées
(width/height)
pour éviter tout décalage de mise en page. Les variantes sont produites au
build par Vite.
<img
src="{{ Vite::asset('resources/img/hero-guy.webp') }}"
srcset="{{ Vite::asset('resources/img/hero-guy-640w.webp') }} 640w,
{{ Vite::asset('resources/img/hero-guy.webp') }} 1280w"
sizes="(min-width: 768px) 576px, 100vw"
alt="Musicien entouré d'instruments de musique"
width="723" height="636"
fetchpriority="high" decoding="async"
/>
Contenus utilisateurs (avatars, galerie média) :
redimensionnés côté serveur avec
intervention/image (v4), de manière
asynchrone via les jobs
ProcessAvatarImage et
ProcessMediaImage à l'upload :
plusieurs tailles sont générées, et les cartes consomment la variante
adaptée (par exemple $profile->medium),
sans repasser par le fichier d'origine.