Skip to content
ThemesIonic — home
WooCommerce

Customising the WooCommerce Product Archive

Four different layers can control your shop page, and only one of them is the Customiser. Knowing which layer owns a setting is the difference between a five-minute change and an afternoon of fighting a theme.

4 min read intermediate

The shop page is an archive, not a page, and that single fact explains most of the frustration. You can open it in the editor, type content into it, save, and see none of it on the front end — because WooCommerce takes the page's identity and then renders archive-product.php in place of its content.

Before changing anything, work out which of four layers owns the setting you want. They are not alternatives; they stack, and the later one always wins.

The four layers, in the order they override each other

Layer What it controls Wins over
WooCommerce settings Shop page, image sizes, catalogue behaviour Nothing
Customiser or Site Editor Columns, rows, sorting, what the archive shows WooCommerce defaults
Theme options and page builders Whatever the theme decided to take over Both of the above
Hooks and template overrides Anything, including the loop itself Everything

The trap is starting at the bottom. People write a filter to force three columns without noticing the theme already offers a setting for it, and then a theme update silently reverses their change. Work down the list, not up.

What the Customiser still handles

In a classic theme, Appearance → Customise → WooCommerce → Product Catalogue typically offers the shop page display mode, what category pages show, default sorting, products per row and rows per page. The panel exists because the theme declared WooCommerce support; a theme can also declare the minimum and maximum column counts the panel is allowed to offer, which is why some themes show a range of two to four and others two to six.

The related image settings sit in the same panel and are the correct place to change catalogue thumbnail behaviour rather than fighting it in CSS.

If the panel is missing entirely, the theme has not registered it. That is not a bug to fix — it usually means the theme moved the same options into its own panel, and setting them in two places is how conflicts start.

Block themes moved the whole thing

A block theme retires most of the Customiser. Product archives become templates you edit visually in Appearance → Editor → Templates, with the loop rendered by a Product Collection block whose inner Product Template defines the card.

That is a genuine improvement for layout work: columns, ordering, query filters and which elements appear on each card are all editable without touching PHP, and the card structure is the same one discussed in product card design. It is a regression for anyone with existing hook-based customisations, because a block-rendered loop does not fire the classic loop hooks in the way the PHP template did. Test your snippets against the block template rather than assuming they carry over. If you are unsure which kind of theme you are running, what a block theme is settles it in a minute.

Hooks: change the archive without owning the template

For a classic theme, the archive is deliberately assembled from actions so you can add and remove pieces without copying files. The shop loop is bracketed by woocommerce_before_shop_loop and woocommerce_after_shop_loop, and each card by woocommerce_before_shop_loop_item and woocommerce_after_shop_loop_item, with woocommerce_after_shop_loop_item_title as the usual insertion point between the name and the price.

Two filters cover most layout requests: loop_shop_columns for the column count and loop_shop_per_page for how many products the query returns. Sorting options in the dropdown are filterable through woocommerce_catalog_orderby, and the actual query arguments the chosen sort produces through woocommerce_get_catalog_ordering_args — that second one is what you need for anything the built-in sorts do not express, such as promoting in-stock items.

Removing a default element is remove_action with the same hook, callback name and priority WooCommerce used. Get the priority wrong and nothing happens, which is the most common reason a removal snippet appears to be ignored.

Template overrides, last

Copy a WooCommerce template into yourtheme/woocommerce/ only when hooks genuinely cannot express the change — a restructured card markup, for example. The copy is now yours to maintain, and WooCommerce → Status will tell you when your version has fallen behind core. Outdated overrides are a leading cause of archives that break after an update, so treat that list as a maintenance queue rather than a warning to dismiss.

Put the overrides in a child theme, not the parent, following the approach in customising a WordPress theme.

Start with the symptom, not the tool

If products are missing rather than badly laid out, this is the wrong article — that is a query, visibility or stock problem, covered in products not showing. If you want a product grid somewhere that is not an archive at all, use a block or a products shortcode rather than reshaping the shop template. And if the request is really "let people narrow this list down", the answer is filtering, not columns.

Frequently asked

Either the active theme is a block theme, in which case the Customiser is largely retired and archives are edited in the Site Editor, or the theme has not declared WooCommerce support and registered the product catalogue panel. Both are normal; the settings simply moved.
A theme or plugin is filtering the column count after the Customiser value is read, or the theme renders its own product loop instead of the WooCommerce one. Check by switching to a default theme; if the setting works there, the override is in your theme.
Not as a normal page. WooCommerce uses the page only for its title and identity, then renders an archive template instead of the page content. Builders that support it ship a dedicated archive or loop template type for exactly this reason.

Related guides