React で作る、あなたのストア向けカテゴリーレール
カテゴリーレール — ストアフロントのグリッドの上にある、タップ可能な部門の行 — は EC サイトの中で最もトラフィックの多いスクロールコンテナであり、それらはカルーセルではなくメニューです:すべてのタイルはリンクで、何もスナップせず、端で半分だけ見えるタイルがスクロールへと誘います。
レールをドラッグするか矢印を使ってみてください — 行の本当の端で無効になります。
なぜストアフロントではネイティブスクロールが勝つのか
ストアフロントのレールは、1 ポイントの Lighthouse スコアのために戦うページのファーストビューに存在します。カルーセルエンジンは、ブラウザがネイティブに行うことをするために数十キロバイトのジェスチャーエミュレーションを出荷します。このライブラリは min+gzip で ≈5.7 kB で、スクロールをプラットフォームに任せるため、ハイドレーションのカクつきがありません — レールは JavaScript が読み込まれる前からスクロールでき、それはクローラーが見るサーバーレンダリングされた HTML の中でも動作するということでもあります。このページ自体がサーバーレンダリングの証拠です:上のデモは JavaScript を無効にしてもスクロールします。
比較ページ に、Swiper、Embla、keen-slider、react-slick との全項目の比較表があります。
可視性トラッキングはストアフロントの機能
アイテムごとの可視性は、マーチャンダイジングに結びつけるまでは実装の細部に聞こえます:
- 画像の遅延読み込み —
useIsVisibleが画面内にあると報告するまでプレースホルダータイルをレンダリングします。 - インプレッション分析 —
getVisible()(ホームページの ヒーローデモ で実際に動いています)は、レールがレンダリングされたことだけでなく、どのカテゴリーが実際に見られたかを正確に教えてくれます。 - エッジ対応の矢印 — add-items の例 のように、カテゴリーが非同期で後から読み込まれても、本当の端で無効化・非表示になります。
あなたのデザインシステムに合わせる
タイルはあなたのコンポーネントです — 画像カード、円形、テキストピルなど — それぞれが itemId を持ちます。高さと幅はあなたの CSS 由来で、メニューは寸法を一切強制しません。one-item-scroll で商品スライダーのように 1 アイテムずつ進めたり、スクロールの 進捗インジケーター を表示したり、RTL の例 でアラビア語やヘブライ語のストア向けに RTL 対応で出荷したりできます — レールは設定ではなく構成の産物です。
パターン、最小構成
itemId を持つタイルと、可視性フックからの矢印 — レール全体は 40 行未満です。
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>
);
}または shadcn コンポーネントとしてインストール
ベースとなる scroll-menu レジストリアイテムがこのレールです — shadcn スタイルの矢印、ドラッグスクロール、非表示のスクロールバー — あなたの components/ui/ にインストールされ、あなたのトークンでスタイリングされます:
npx shadcn@latest add https://react-horizontal-scrolling-menu.dev/r/scroll-menu.json