Un rail de catégories pour votre boutique, en React
Les rails de catégories — la rangée cliquable de rayons au-dessus d'une grille de vitrine — sont les conteneurs de défilement les plus fréquentés en e-commerce, et ce sont des menus, pas des carrousels : chaque vignette est un lien, rien ne s'aligne, et une demi-vignette qui dépasse au bord est ce qui invite au défilement.
Faites glisser le rail ou utilisez les flèches — elles se désactivent aux véritables extrémités de la rangée.
Modifier cet exemple en direct dans Storybook
Pourquoi le défilement natif gagne sur une vitrine
Les rails de vitrine vivent au-dessus de la ligne de flottaison, sur des pages où vous vous battez pour chaque point Lighthouse. Un moteur de carrousel embarque des dizaines de kilo-octets d'émulation de gestes pour faire ce que le navigateur fait nativement ; cette bibliothèque pèse ≈5,7 kB min+gzip et laisse le défilement à la plateforme, donc il n'y a pas de saccade d'hydratation — le rail défile avant même le chargement de votre JavaScript, ce qui signifie aussi qu'il fonctionne dans le HTML rendu côté serveur que voient vos robots d'indexation. Cette page elle-même en est la preuve rendue côté serveur : la démo ci-dessus défile avec JavaScript désactivé.
La page de comparaison contient le tableau complet face à Swiper, Embla, keen-slider et react-slick.
Le suivi de visibilité est une fonctionnalité de vitrine
La visibilité par élément ressemble à un détail d'implémentation jusqu'à ce que vous la rapprochiez du merchandising :
- Images paresseuses — affichez une vignette d'espace réservé jusqu'à ce que
useIsVisiblesignale qu'elle est à l'écran. - Analytique d'impressions —
getVisible()(en direct dans la démo héro de la page d'accueil) vous indique exactement quelles catégories ont été vues, pas seulement que le rail s'est rendu. - Flèches conscientes des bords — se désactivent ou se masquent aux véritables extrémités, même après le chargement asynchrone de catégories, comme dans l'exemple d'ajout d'éléments.
Adaptez-le à votre système de design
Les vignettes sont vos composants — cartes images, cercles, pastilles de texte — chacune portant un itemId. La hauteur et la largeur viennent de votre CSS ; le menu n'impose aucune dimension. Avancez d'un élément à la fois comme un slider produit avec one-item-scroll, affichez un indicateur de progression de défilement, ou livrez-le en RTL pour les boutiques arabes et hébraïques avec l'exemple RTL — le rail est de la composition, pas de la configuration.
Le motif, minimal
Des vignettes avec un itemId, des flèches issues des hooks de visibilité — le rail complet fait moins de quarante lignes.
function CategoryRail({ categories }: { categories: Category[] }) {
return (
<ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}>
{categories.map((category) => (
<CategoryTile itemId={category.id} key={category.id} {...category} />
))}
</ScrollMenu>
);
}
function CategoryTile({ itemId, name, image }: CategoryTileProps) {
// Lazy images for free: placeholders until the tile is on screen.
const visibility = React.useContext<publicApiType>(VisibilityContext);
const isVisible = visibility.useIsVisible(itemId, false);
return (
<a href={`/category/${itemId}`} className="rail-tile">
{isVisible ? <img src={image} alt="" /> : <div className="ph" />}
<span>{name}</span>
</a>
);
}
function LeftArrow() {
const visibility = React.useContext<publicApiType>(VisibilityContext);
const atStart = visibility.useLeftArrowVisible();
return (
<button disabled={atStart} onClick={() => visibility.scrollPrev()}>
←
</button>
);
}Ou installez-le comme composant shadcn
L'élément de registre de base scroll-menu est ce rail — flèches stylées shadcn, glisser pour défiler, barre de défilement masquée — installé dans votre components/ui/ et stylé par vos tokens :
npx shadcn@latest add https://react-horizontal-scrolling-menu.dev/r/scroll-menu.json