WooCommerce Shop Page Hooks: Visual Guide with Code Examples


Published: 29 Aug 2026


WooCommerce Shop Page Hooks

If you’ve ever wanted to add a banner, a promo message, a custom badge, or extra product info to your WooCommerce shop page without installing another plugin, WooCommerce shop page hooks are how you do it. This guide maps out every hook on the shop page, shows you exactly where each one fires, and walks through real code examples you can copy straight into your site.

WooCommerce shop page hooks are predefined points in the shop/archive page template where you can insert or modify content using,add_action() or add_filter(), without touching WooCommerce’s core files. They work the same way as the hooks on the single product page, just applied to the page that lists your products instead of the page that shows one.

This post is the second in our woocommerce hooks series. If you haven’t already, our single product page hooks guide covers the same concept for individual product pages, and the two work well together if you’re customizing a full store.

What Counts as the “Shop Page” in WooCommerce

Before getting into the hooks themselves, one thing trips up a lot of beginners: the “shop page,” a category page, a tag page, and an attribute page all share the exact same underlying template (archive-product.php). So every hook in this guide fires identically whether someone’s browsing your main shop page, a specific category like “T-Shirts,” or a tag like “Sale.” You don’t need separate customization for each; one hook placement covers all of them, unless you deliberately add conditional logic to target just one.

What You Need Before Customizing WooCommerce Shop Page Hooks

  • A basic understanding of actions vs. filters. Actions let you insert new content at a point on the page; filters let you modify content that’s already there before it displays. Our WooCommerce single product page hooks cover this distinction in more depth if you’re new to it.
  • A safe place to add code. Either a code snippets plugin (like WPCode or Code Snippets), which is the safer option since it doesn’t touch theme files, or your child theme’s functions.php file. Never edit a parent theme’s functions.php, since an update will wipe it out.
  • A staging site or backup, if you’re comfortable with one. Hook code is generally low-risk, but it’s still good practice before editing a live store.

Visual Map: Where Every Shop Page Hook Sits

Here’s the sequence of hooks, from the top of the shop page to the bottom:

woocommerce_before_main_content → woocommerce_archive_description (shop title and description) → woocommerce_before_shop_loop (result count, sorting dropdown) → the product loop, where woocommerce_before_shop_loop_item, woocommerce_before_shop_loop_item_title, woocommerce_shop_loop_item_title, woocommerce_after_shop_loop_item_title, and woocommerce_after_shop_loop_item fire once per product → woocommerce_after_shop_loop (pagination) → woocommerce_after_main_content.

woocommerce_before_main_content

WooCommerce shop page

woocommerce_archive_description
woocommerce_before_shop_loop

Showing 1–2 of 10 results

woocommerce_before_shop_loop_item
woocommerce_before_shop_loop_item_title
Woo
woocommerce_shop_loop_item_title

Product title

woocommerce_after_shop_loop_item_title

$18.00

woocommerce_after_shop_loop_item
woocommerce_before_shop_loop_item
woocommerce_before_shop_loop_item_title
Woo
woocommerce_shop_loop_item_title

Product title

woocommerce_after_shop_loop_item_title

$18.00

woocommerce_after_shop_loop_item
woocommerce_after_shop_loop
woocommerce_after_main_content

Here’s the full list of hooks shown above, for reference and for easy scanning:

  • woocommerce_before_main_content
  • woocommerce_archive_description
  • woocommerce_before_shop_loop
  • woocommerce_before_shop_loop_item
  • woocommerce_before_shop_loop_item_title
  • woocommerce_shop_loop_item_title
  • woocommerce_after_shop_loop_item_title
  • woocommerce_after_shop_loop_item
  • woocommerce_after_shop_loop
  • woocommerce_after_main_content

The Complete List of Shop Page Hooks

HookPosition on the Shop PageTemplate File
woocommerce_before_main_contentBefore the shop page content startsarchive-product.php
woocommerce_archive_descriptionBelow the “Shop” (or category) titlearchive-product.php
woocommerce_before_shop_loopBefore the product grid, above result count and sortingarchive-product.php
woocommerce_before_shop_loop_itemBefore each individual product in the gridcontent-product.php
woocommerce_before_shop_loop_item_titleAbove each product’s imagecontent-product.php
woocommerce_shop_loop_item_titleAbove each product’s titlecontent-product.php
woocommerce_after_shop_loop_item_titleBelow each product’s title (price usually renders here)content-product.php
woocommerce_after_shop_loop_itemAbove the Add to Cart button on each productcontent-product.php
woocommerce_after_shop_loopAfter the entire product grid, where pagination sitsarchive-product.php
woocommerce_after_main_contentAfter all shop page contentarchive-product.php

Practical Examples: Using Shop Page Hooks

Adding a Storewide Announcement Banner

Use woocommerce_before_main_content to show a banner above everything else on the shop page, useful for sales, shipping deadlines, or seasonal promotions.

add_action( 'woocommerce_before_main_content', 'techpro_shop_banner', 5 );

function techpro_shop_banner() {
    echo '<div class="techpro-shop-banner">🎉 Free shipping on orders over $50 — today only!</div>';
}

Writing a Custom Shop Description

woocommerce_archive_description is where WooCommerce prints your shop or category description by default. You can add extra content alongside it:

add_action( 'woocommerce_archive_description', 'techpro_shop_intro', 15 );

function techpro_shop_intro() {
    if ( is_shop() ) {
        echo '<p>Browse our full collection below, sorted by what's new first.</p>';
    }
}

The is_shop() conditional check matters here; without it, this text would also print on every category and tag page, not just the main shop page.

woocommerce_before_shop_loop_item_title fires once per product, right above its image, making it the right spot for a badge that should appear on every item in the grid:

add_action( 'woocommerce_before_shop_loop_item_title', 'techpro_new_badge', 5 );

function techpro_new_badge() {
    echo '<span class="techpro-new-badge">New</span>';
}

Showing Stock Count Under the Product Title

woocommerce_after_shop_loop_item_title is a common spot for extra product info, since it sits right where price and ratings already render:

add_action( 'woocommerce_after_shop_loop_item_title', 'techpro_stock_count', 15 );

function techpro_stock_count() {
    global $product;
    if ( $product->is_in_stock() && $product->managing_stock() ) {
        echo '<p class="techpro-stock-count">' . $product->get_stock_quantity() . ' left in stock</p>';
    }
}

Targeting Only One Category’s Products

Sometimes you only want a hook to apply to products inside a specific category, not the whole grid. Wrap the function in a conditional check:

add_action( 'woocommerce_before_shop_loop_item_title', 'techpro_category_specific_badge', 5 );

function techpro_category_specific_badge() {
    if ( has_term( 'clearance', 'product_cat' ) ) {
        echo '<span class="techpro-clearance-badge">Clearance</span>';
    }
}

How to Remove a Default Hook

To remove something WooCommerce already outputs, use remove_action() with the exact hook name, function name, and priority it was originally added with. For example, to remove the default result count and sorting dropdown:

remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 );
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );

If you’re not sure of a default function’s exact priority, our single product page hooks visual guide includes the full default-actions reference for the summary section, and the same lookup approach works here; check WooCommerce’s own template files if you need to confirm one for the shop page.

Extra Tips and Best Practices

  1. Remember the shop, category, and tag pages share one template. Any hook you add applies everywhere unless you add a conditional check like is_shop() or is_product_category().
  2. Match priority numbers carefully. If your custom content shows up in the wrong order relative to the default elements, adjust the priority number rather than switching hooks entirely.
  3. Test after every theme or page builder change. Themes like Divi, Flatsome, and Avada, and builders like Elementor, sometimes override WooCommerce’s default hooks with their own; if a hook stops working after a theme switch, this is almost always why.
  4. Use a code snippets plugin over editing functions.php directly, especially while you’re still testing. It’s easier to disable a snippet instantly if something looks off.
  5. Keep shop page and single product page customizations visually consistent. A badge or banner style you introduce on the shop page should usually carry over to the product page too, so the shopping experience feels intentional rather than patched together.

Common Problems and Fixes

My hook isn’t firing at all. This is almost always a theme or page builder override. Themes like Divi, Flatsome, Avada, and OceanWP sometimes replace WooCommerce’s default template functions with their own. Try switching to a default theme like Storefront temporarily; if the hook works there, your theme is the cause, and you’ll need to find its equivalent custom hook instead.

My content shows up on every category page, not just the shop page. woocommerce_archive_description and similar hooks fire on the shop page, every category page, and every tag page, since they all share the same template. Add an is_shop() conditional check inside your function to restrict it to just the main shop page.

The hook works on desktop, but the position looks wrong on mobile. Some hook placements that look fine at wider grid widths crowd the layout at 1-2 columns per row on mobile. Check your site on an actual phone after adding any new hook content, not just in a resized browser window.

I added a filter, but the content disappeared entirely. Filters must return a value, or whatever they were supposed to modify vanishes. This is one of the most common mistakes when working with filter hooks specifically: double-check your function ends with a return statement.

Caching is showing me an old version of the shop page. If you’ve added a hook and don’t see the change, clear your site’s cache (and your browser cache) before assuming the code is broken.

Where to Go From Here

You now have a complete map of every hook on the WooCommerce shop page, along with working code for the customizations store owners ask for most: banners, badges, stock counts, and category-specific content. Combined with our single product page hooks guide, you have the two most-customized pages in any WooCommerce store fully covered.

If you run into a hook behaving unexpectedly on your specific setup, drop a comment below; theme and plugin conflicts vary a lot from store to store, and it helps other readers hitting the same issue too.

Frequently Asked Questions

What is the difference between shop page hooks and single product page hooks?

Shop page hooks control the page that lists multiple products (the main shop, category, and tag pages), while single product page hooks control the page for one individual product. Some hook names look similar, but they fire on different templates and can’t be used interchangeably.

Do shop page hooks work the same on category and tag pages?

Yes. The shop page, category pages, and tag pages all share the same archive-product.php template, so every hook in this guide fires identically across all three unless you add a conditional check to target just one.

Can I use shop page hooks without editing my theme files?

Yes. A code snippets plugin like WPCode or Code Snippets lets you add hook code without touching any theme file directly, which is safer since it won’t get wiped out by a theme update.

Why isn’t my hook code showing up on the shop page?

The most common cause is your theme or page builder overriding WooCommerce’s default templates. Divi, Flatsome, Avada, and similar themes sometimes replace the default hook functions with their own equivalents.

Can I add different content to just one product category on the shop page?

Yes. Wrap your hook function in a conditional check like has_term() or is_product_category() to target a specific category instead of applying the change to every product in the grid.

Is there a hook to change how many products display per row?

Products-per-row and per-page settings are typically controlled through your theme’s customizer or WooCommerce’s product catalogue settings, rather than a hook. Hooks are better suited for adding or modifying content, not changing grid dimensions.


Haj Bibi Avatar
Haj Bibi

Hi, I’m Haj Bibi. I specialize in WordPress and SEO, helping websites perform better, rank higher, and reach the right audience. I share practical tips and strategies to make managing and optimizing websites easier for everyone.


Please Write Your Comments
Comments (0)
Leave your comment.
Write a comment
INSTRUCTIONS:
  • Be Respectful
  • Stay Relevant
  • Stay Positive
  • True Feedback
  • Encourage Discussion
  • Avoid Spamming
  • No Fake News
  • Don't Copy-Paste
  • No Personal Attacks
`