A product page has to answer three things before the buy button: what it is, whether it fits me, and what happens after I pay. Put clear photos, the name, price and options above the fold on desktop, then delivery, returns and details below, and mark up price and availability with Product structured data.
| Part | Job | Common miss |
|---|---|---|
| Gallery | Shows the item from every angle, in use and to scale | Only one studio shot |
| Name and price | Confirms it is the right thing at a known cost | Price hidden until checkout |
| Options | Size, colour, quantity with clear stock state | Out of stock found after choosing |
| Add to cart | The single main action | Competing buttons of equal weight |
| Delivery and returns | Removes the after-purchase worry | Policy only in the footer |
| Details and specs | Materials, dimensions, care | Wall of text with no headings |
| Questions | Answers that block the decision | Missing entirely |
Updated
Instead of screenshots of other shops, this guide builds a product page for an invented ceramics studio in plain HTML and CSS, part by part. Use the checklist to score your own page and copy the structured data that fits Google's current rules.
Tick what your product page already does. The score shows what is left to fix; nothing is saved or sent anywhere.
Gallery left, buy box right on wide screens; they stack on phones. The sold-out size says so in words, not only in grey.
<style>
* { box-sizing: border-box } body { font-family: system-ui, sans-serif; color: #1c1917 }
.wrap { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)) }
.main { aspect-ratio: 1; border-radius: 14px; background: linear-gradient(135deg, #d6d3d1, #a8a29e); display: grid; place-items: center; color: #44403c }
.thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 8px }
.thumbs span { aspect-ratio: 1; border-radius: 8px; background: #e7e5e4 }
h1 { font-size: 24px; margin: 0 } .price { font-size: 20px; font-weight: 700; margin: 6px 0 14px }
fieldset { border: 0; padding: 0; margin: 0 0 14px } legend { font-weight: 600; margin-bottom: 6px }
.opt { display: inline-block; margin: 0 6px 6px 0 } .opt input { margin-right: 4px }
button { width: 100%; padding: 14px; border: 0; border-radius: 10px; background: #1c1917; color: #fff; font: 600 16px system-ui }
button:focus-visible { outline: 3px solid #2563eb; outline-offset: 2px }
ul { padding-left: 18px; color: #44403c; font-size: 14px }
</style>
<div class="wrap">
<div><div class="main" role="img" aria-label="Speckled stoneware mug, front view">Main photo</div>
<div class="thumbs" aria-hidden="true"><span></span><span></span><span></span><span></span></div></div>
<div>
<h1>Speckled Stoneware Mug</h1>
<p class="price">£24</p>
<fieldset><legend>Size</legend>
<label class="opt"><input type="radio" name="s" checked>Regular, 300 ml</label>
<label class="opt"><input type="radio" name="s" disabled>Large, 450 ml (sold out)</label>
</fieldset>
<button>Add to basket</button>
<ul><li>Delivery in 2 to 4 working days, £3.95</li><li>Free returns within 30 days</li><li>Dishwasher safe</li></ul>
</div>
</div>Short headed sections are easier to scan than one long description. The first one is open because it answers the most common question.
<style>
details { border-top: 1px solid #e7e5e4; padding: 10px 2px; font-family: system-ui }
summary { font-weight: 600; cursor: pointer } p, dl { margin: 8px 0 0; color: #44403c }
dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px } dt { font-weight: 600 }
</style>
<details open><summary>Size and capacity</summary>
<dl><dt>Height</dt><dd>9.5 cm</dd><dt>Width</dt><dd>8 cm, 11 cm with handle</dd><dt>Holds</dt><dd>300 ml</dd></dl></details>
<details><summary>Materials and care</summary><p>Hand-thrown stoneware with a food-safe glaze. Dishwasher and microwave safe.</p></details>
<details><summary>Delivery and returns</summary><p>Packed in recycled card. Return unused items within 30 days for a full refund.</p></details>name, image and offers with price and priceCurrency are the required merchant listing fields; availability and the rest are recommended. Values must match the page.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Speckled Stoneware Mug",
"image": ["https://example.com/photos/mug-front.jpg", "https://example.com/photos/mug-in-use.jpg"],
"description": "Hand-thrown 300 ml stoneware mug with a speckled glaze.",
"brand": { "@type": "Brand", "name": "Example Ceramics" },
"offers": {
"@type": "Offer",
"url": "https://example.com/mugs/speckled",
"price": 24.00,
"priceCurrency": "GBP",
"availability": "https://schema.org/InStock"
}
}
</script>
Plan the gallery as a set: front, back or side, close-up of the material, the item in use, and one with something for scale. Each image needs alt text that describes what that view shows.
Reserve the gallery's space with width and height or aspect-ratio, so the page does not jump as images load.
Group the price, options, quantity and button together with the delivery and returns summary right under them. That one block should answer most questions without scrolling.
Disabled options need more than grey text. Add the words Sold out to the label so the state is clear to everyone, including screen reader users.
Dimensions, materials, care instructions and what is in the box belong in scannable sections with headings. A short size or fit note prevents many wrong orders.
Answer the two or three questions customers ask most right on the page, and link to the full FAQ for the rest.
On desktop: the main photo, product name, price, the option pickers and the add to cart button. On phones the photo usually fills the first screen, so make sure the name and price follow right after it, with the button close behind.
For pages where people can buy, Google's merchant listing docs require Product with name, image and offers, and an Offer with a price above zero and a priceCurrency. Availability, shipping details, return policy, brand and GTIN are recommended.
Product snippets are for pages where people cannot buy directly, such as reviews, and need a name plus one of review, aggregateRating or offers. Merchant listings are for pages that sell the product and need the price and currency.
If you have real ones, yes, near the price or under the details. Never invent reviews or ratings, and only add aggregateRating markup when the rating is shown on the page and comes from real customers.
Related: How to build an ecommerce website, Structured data examples, Product description generator, Abandoned cart email examples.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.