SEO for online stores on WordPress and WooCommerce
SEO for online stores is won mostly on category pages and product pages: categories for broad searches like "linen shirts for men", products for specific ones like a model name or SKU. On WooCommerce, the main work is making those pages unique and complete, keeping filtered URLs from flooding the index, and getting product structured data right once, not twice.
Product markup is also one of the few structured data types with fully active rich results in Google. Price, availability, ratings and shipping details can all appear in search, and product pages where visitors can buy qualify for merchant listings.
Pages every online stores site needs
- Category pages. The pages that rank for broad, high-volume searches. They need a short introduction, useful filters, and internal links to subcategories, not only a product grid.
- Product pages. Your own description, several images, specifications, price, stock status, shipping and returns. Each needs a unique title and meta description.
- Buying guides. Content that answers comparison questions ("merino vs synthetic base layers") and links into the right categories.
- Brand pages. If you stock several brands, a page per brand catches searches that combine brand and product type.
- Shipping and returns pages. Clear policies support merchant listings and answer the questions that stop checkouts.
Product markup without duplicates
WooCommerce prints Product JSON-LD on product pages by itself, and themes and SEO plugins sometimes add another. Two Product blocks with different prices confuse Google, so view the page source, search for "Product", and keep exactly one complete block.
For merchant listings, the page needs name, image and an offers object with price and priceCurrency; add availability, gtin where the product has one, shippingDetails and a return policy (a store-wide one in Organization markup is accepted). Keep the structured price identical to the visible price, including sales. Ratings belong in aggregateRating only when the reviews are shown on the page. Connecting a Google Merchant Center feed adds free listings on top of what markup provides. Full details: Product schema.
Category pages that deserve to rank
A default WooCommerce category is a title and a grid, which gives little to rank against competitors who explain the range. Add a short introduction above the grid and, if useful, a longer buying note below it. Write it for shoppers: what the range covers, how to choose, sizing notes.
Keep categories in a sensible hierarchy with breadcrumbs. In Hydrogen SEO, the breadcrumbs Show shop page setting adds the shop to product and category trails (Home › Shop › Shirts › Linen Shirt), and a product in several categories follows its primary category. Avoid building near-identical categories and tags for the same products; they compete with each other. See optimize WooCommerce category pages.
Faceted navigation and out-of-stock products
Filters for size, color and price create a new URL for every combination, such as ?filter_color=blue&filter_size=m. Left alone, that can mean more filtered URLs than real products, which wastes crawling and creates duplicates. Let filtered pages canonicalize to the unfiltered category, or noindex them; only give a filter combination its own indexable page when people search for it ("black linen shirts") and you add unique content. Blocking filters in robots.txt stops crawling, but then Google cannot see a noindex on them. See faceted navigation.
For products that are temporarily out of stock, keep the page live and set availability to OutOfStock. For discontinued products, redirect to the replacement or closest category with a 301 in the Redirection Manager, or let the page return 404 or 410 if nothing is similar.
Product schema example
A starting point for your site. Replace every value with your own, and only mark up what is visible on the page.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Coastline Linen Shirt",
"image": [
"https://example.com/images/coastline-linen-sand-1x1.jpg",
"https://example.com/images/coastline-linen-sand-4x3.jpg"
],
"description": "A relaxed-fit shirt in washed European linen with a button-down collar.",
"sku": "CL-LIN-SND-M",
"gtin13": "0765432109876",
"brand": {
"@type": "Brand",
"name": "Harbor & Pine"
},
"offers": {
"@type": "Offer",
"url": "https://example.com/shop/shirts/coastline-linen-shirt/",
"price": 78,
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition",
"shippingDetails": {
"@type": "OfferShippingDetails",
"shippingRate": {
"@type": "MonetaryAmount",
"value": 0,
"currency": "USD"
},
"shippingDestination": {
"@type": "DefinedRegion",
"addressCountry": "US"
}
}
}
}
Checklist
- Check product pages for more than one Product JSON-LD block
- Keep the structured price identical to the visible price
- Add GTINs for products that have them
- Write your own product descriptions instead of the manufacturer's
- Add an introduction to every category page
- Enable breadcrumbs with the shop page in product trails
- Canonicalize or noindex filtered and sorted URLs
- Keep temporarily out-of-stock products live with OutOfStock availability
- Redirect discontinued products to a replacement or category
- Publish shipping and returns policies and mark them up
- Connect a Merchant Center feed for free listings
Common questions
Does WooCommerce add product schema by default?
Yes, WooCommerce prints Product structured data on product pages. Check the page source before adding more from another plugin so you do not end up with two conflicting blocks.
Should product variations have separate URLs?
Usually not. One product page with selectable variants keeps signals together. Separate pages make sense only when variants are searched for and sold as distinct products.
Should I put Product schema on category pages?
No. Google's Product features are for a page about one product. Category pages benefit from breadcrumbs and good content instead.
Can I show Trustpilot ratings as stars on my products?
Not through your markup. aggregateRating should summarize reviews collected and shown on the product page itself.