Skip to content

Product Comparison

The page between a listing and a product detail, with the two questions a comparison table alone cannot answer: will it fit, and can I actually have it.

6 blocks53 lineslucide-reactAdded 10 Sept 2026

What's included

  • app/product-compare-page.tsx
  • 6 blocks it is built from, installed with it
  • Needs lucide-react

Works with

  • React
  • Next.js
  • Tailwind CSS
  • TypeScript

npx hoverlab add product-compare-page

Or over MCP, from your editor's agent — no account needed.

License

Free to read, copy and install, for personal and non-commercial projects. Shipping it in client work or a paid product needs Pro ($79 once). The source lands in your repo and stops being ours — no attribution, nothing to upgrade.

Was this useful?

Preview

The collection

Made to be repaired, not replaced

A grid of forty products with a one-line title is a search result. For anything considered, the reason the collection exists is what does the selling, and it belongs above the grid rather than on a linked story page nobody opens.

  • One factory, namedPorto, family-run, thirty years. The address is on the about page rather than implied by a photograph.
  • Repairs, not warrantiesSend it back at any age. Repair is charged at cost and typically beats replacing it.
  • Deadstock and offcutsWhich is why sizes run out and do not come back. The stock list says which.
  • Priced onceNo seasonal markdown, so nobody who bought in March is punished for it in July.

Comparing 3 of 3

2 rows are identical across all 3 and hidden.

Specifications compared across 3 products. 2 identical rows are hidden.
SpecificationField Over-Ear£249Field Over-Ear Lite£179Studio Reference£329
Price£249£179best£329
Battery life38 hours44 hoursbest30 hours
Weight286 g241 gbest324 g
Noise cancellingAdaptive, 3 levelsPassive onlyAdaptive, 5 levels
Driver40 mm dynamic40 mm dynamic50 mm planar
Water resistanceIPX4IPX4None
Warranty2 years2 years5 yearsbest

Specification

The numbers that decide it

A forty-row spec table is a place to hide the three figures someone is actually comparing. These are pulled out; the full table is still below for the person who wants it.

  • Weight1.24 kg with the battery, which is the only way anyone carries it.
  • Battery18 hours of mixed use, measured at 150 nits rather than at minimum brightness.
  • PortsTwo USB-C, one HDMI, one headphone. No dongle in the box and none needed.
  • RepairabilityBattery and SSD are user-replaceable. Parts and the manual are public.

Size guide — Heavyweight Oxford Shirt

Measurements are of the body, not the garment.

Units

The model is 1.78m and wears a medium.

9 in 10 buyers kept their usual size. The 1 in 10 who exchanged went up, not down.

Body measurements by size, in centimetres.
SizeChest (cm)Around the fullest part, under the arms, tape level and not pulled tight.Waist (cm)Around the narrowest part, usually just above the navel.Sleeve (cm)From the centre back of the neck, over the shoulder, to the wrist.
XS81–8666–7161
S86–9171–7663
Mworn by the model96–10181–8664
L106–11191–9666
XL116–121101–10667
XXL126–131111–11669

Between two sizes on chest and waist? This shirt is cut straight, so take the larger — that is what the exchanges above did.

What is actually available

"In stock" on a listing that means "one of nine variants is in stock" is the single most expensive lie in commerce UI — it is discovered at checkout, and the basket is abandoned there.

Tell me when it is back

A sold-out product page with a greyed-out button is a dead end and a lost address. One field turns it into the only useful thing left on the page.

One message when it restocks. This is not a reservation — stock is first come.

Only that size triggers the alert. Leave blank for any.

The real page, rendered in your current theme — every section below is a live block, not a screenshot.

Built from

All blocks
  1. Collection Story SplitThe editorial header above a collection grid, carrying the four facts that decide a considered purchase.
  2. Product Comparison TableThree products side by side with the row labels pinned through a horizontal scroll, an "only show differences" toggle that says how many rows it hid, and "best" marked only where better means something.
  3. Product Spec SplitThe specification table beside the product image, with the two or three figures that decide the purchase pulled out of it.
  4. Size GuideThe panel that decides whether the parcel comes back: what the model is wearing and what previous buyers did, above a table whose inches are converted rather than maintained twice.
  5. Stock Availability ListAvailability per variant stated before the cart, because discovering it at checkout is where the basket gets abandoned.
  6. Back In Stock FormThe capture that replaces a dead sold-out button, with the honest caveat that a notification is not a reservation.

Only want one section? Open it and copy that block instead — browse Product Listings.

Source

app/product-compare-page.tsx
/**
 * Deciding between three of a thing — the page between a listing and a
 * product detail.
 *
 * Comparison pages get built as a table and stop there, which loses the
 * two questions that actually decide the purchase: will it fit, and can I
 * have it. Both are here.
 *
 *   story        an editorial opener with a real tablist for the thumbnail
 *                strip, so arrow keys work. A comparison that opens on a
 *                grid of specs assumes the reader already knows what they
 *                are looking at
 *   table        three side by side, row labels pinned through the
 *                horizontal scroll, and an "only show differences" toggle
 *                that turns forty rows into the six that matter
 *   specs        the detail behind the row that made someone pause
 *   sizing       what the model is wearing and what previous buyers did —
 *                the panel that decides whether the parcel comes back
 *   stock        per-variant, because "in stock" for a product is not a
 *                fact about the size you want
 *   back in      and the form for when it is not
 *
 * The stock pair at the end is the part most comparison pages omit
 * entirely, and it is the one that costs money in both directions: a
 * reader who chooses the item that is unavailable buys nothing, and a
 * reader told it is unavailable with no way to be notified is a lost sale
 * that never appears in any funnel.
 */

import * as React from 'react'
import { CollectionStorySplit } from '@/components/collection-story-split'
import { ProductCompareTable } from '@/components/product-compare-table'
import { ProductSpecSplit } from '@/components/product-spec-split'
import { ProductSizeGuide } from '@/components/product-size-guide'
import { StockAvailabilityList } from '@/components/stock-availability-list'
import { BackInStockForm } from '@/components/back-in-stock-form'

export default function ProductComparePage() {
  return (
    <main className="min-h-screen bg-background text-foreground">
      <CollectionStorySplit />

      <ProductCompareTable />
      <ProductSpecSplit />
      <ProductSizeGuide />

      {/* The two blocks a comparison page usually forgets. */}
      <StockAvailabilityList />
      <BackInStockForm />
    </main>
  )
}

How to use it

  1. 1. Copy each of the 6 blocks above into components/ — each block page has its own copy button.
  2. 2. Drop this file at app/product-compare-page.tsx. The imports already point at @/components/…, so they resolve with no edits.
  3. 3. Delete the sections you do not want. Every block takes props, so the copy changes without the layout moving.

For AI

The component, its props, the design tokens it expects and the command that installs it — as one prompt. Paste it into Claude, Cursor, v0 or ChatGPT and what they build around it will match the rest of the catalog instead of inventing its own system.

See the prompt

More Commerce Pages

Open the full page for this page

Product Collection

Sticky filter sidebar, sort toolbar and product grid — with the facets dropped rather than stacked on mobile, so a shopping page does not open as a form.

Commerce Pages4 blocks68 lines
Open the full page for this page

Product Detail

Gallery, sticky buy box, details accordion and reviews — ordered by what a shopper needs before they can decide.

Commerce Pages6 blocks75 lines
Open the full page for this page

Shopping Bag

Editable lines beside a sticky summary, so the total and the checkout button survive a scroll through four quantity changes.

Commerce Pages3 blocks42 lines
Open the full page for this page

Checkout

Address and payment with the site navigation stripped and the order summary moved above the form on mobile — both aimed squarely at completion rate.

Commerce Pages2 blocks57 lines
Open the full page for this page

Order Confirmed

The post-purchase screen, with navigation restored and a rail that shows what to buy next rather than what was just bought.

Commerce Pages2 blocks56 lines
Open the full page for this page

Account Orders

Order history in the settings shell rather than a second sidebar layout — an account area and a settings area are the same shape.

Commerce Pages2 blocks42 lines
Open the full page for this page

Express Checkout

Checkout for the buyer who will not fill in a form: wallet buttons above the fields, and the address a wallet returns shown and changeable before the charge rather than after it.

Commerce Pages3 blocks57 lines
Open the full page for this page

Order Tracking

For the customer with an order number and no account — a lookup, an arrival range rather than a promised date, and the review form where the "how did we do" email actually lands.

Commerce Pages3 blocks40 lines