Merchlint
Available now
Next, in this order
  • DeutschDE
  • EspañolES
  • FrançaisFR
  • ItalianoIT
  • PortuguêsPT
  • NederlandsNL
  • SvenskaSV
  • TürkçeTR

A language shows up here once its pages are actually written. Nothing on this site is machine-translated.

Install free
← All checks

WooCommerce product not showing on the shop page

It sold well, and then somebody hid it — visibility set to Hidden, or the status back to Draft. Almost never a decision, usually a bulk edit or an import.

Group
Money
Confidence
F — fact from the database
Version
Free
Updated
Code
A3

The symptom

A product that sold steadily all year is no longer anywhere in the shop. Not out of stock — the stock is there. It is simply not in the catalogue: either its visibility is set to hidden, or its status went back to draft or private.

The URL still works, so anyone with the old link sees a normal product page. Everyone else cannot find it at all, and nobody reported it, because a product that quietly disappears generates no error and no complaint.

Video, 1:13 — WooCommerce product not showing in the shop? Check these two fields

What it costs

This is the finding where the number is not an estimate. The product earned a known amount over the past twelve months; today it earns nothing, and the difference started on the day it was hidden.

It is also the finding people are most surprised by. Nobody remembers hiding it, because usually nobody decided to:

  • A bulk edit on a filtered product list where the filter matched more than expected.
  • An import that carried a status column and set everything in the file to draft — what to look at after one: WooCommerce CSV import.
  • A staging copy promoted to production with statuses from a half-finished editing session.
  • Someone hiding a product for one afternoon during a photo shoot, three months ago.

The tell is clustering. If forty products were hidden within the same minute, you are not looking at forty decisions.

How to check it yourself

In the admin. Above the product list there are Drafts and Private links — each shows the products with that status, which customers cannot see in your shop. A link only appears when there are such products. The list does not show catalog visibility and cannot be filtered by it: you can check it in the product itself (the Publish box, Catalog visibility) or in Quick Edit (the Visibility field), one product at a time. Search results only hides the product from the shop and category pages just like Hidden does — it is only findable through the search box.

If both fields look right — the product is published and visible — and it still does not show:

  • It is out of stock, and the shop hides such products. WooCommerce → Settings → Products → Inventory, Hide out of stock items from the catalog. With that box ticked, a product at zero stock disappears from the shop until it is restocked. A product that sold all year and cannot be bought today has its own check: A1.
  • The status is Scheduled. The publish date is in the future, and the product appears on that date, not before.
  • A page cache still serves the old shop page. After the change, clear the cache of the cache plugin or the host.

All at once, from the command line (for developers). Since WooCommerce 3.0, catalogue visibility is not postmeta — it is the product_visibility taxonomy, with terms such as exclude-from-catalog and exclude-from-search. That trips up most hand-written queries:

wp db query "SELECT p.ID, p.post_title, p.post_status, p.post_modified, t.slug
  FROM wp_posts p
  LEFT JOIN wp_term_relationships tr ON tr.object_id = p.ID
  LEFT JOIN wp_term_taxonomy tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
       AND tt.taxonomy = 'product_visibility'
  LEFT JOIN wp_terms t ON t.term_id = tt.term_id
  WHERE p.post_type = 'product'
    AND ( p.post_status IN ('draft','private')
          OR t.slug = 'exclude-from-catalog' )
  ORDER BY p.post_modified DESC"

Read the post_modified column carefully — that is where the clustering shows. Products changed within the same minute were changed by one action.

To see which of them mattered, cross-reference with sales. WooCommerce keeps a lookup table for exactly this:

wp db query "SELECT product_id, SUM(product_net_revenue) AS revenue
  FROM wp_wc_order_product_lookup
  WHERE date_created > DATE_SUB(NOW(), INTERVAL 12 MONTH)
  GROUP BY product_id ORDER BY revenue DESC"

How to fix it

  1. Start from the revenue list, not the product list. Restoring the three products that earned real money is an afternoon’s work with a measurable result; going through all two hundred hidden products is a week with no result.
  2. Restore visibility, then check the product is actually complete — price, stock, image. A product hidden mid-edit may have been hidden for a reason that was valid at the time.
  3. Find the action, not the products. If they cluster by post_modified, undo the cause: correct the import mapping, or note which filter the bulk edit used.
  4. For genuinely discontinued lines, hidden is the right state and keeping the product is correct — it preserves order history. Hide the finding so it stops coming back.

When it is a false positive

  • Products sold only through a direct link — a bundle reachable from another product, an upsell, a private offer for one customer. Hidden is exactly right for those.
  • Seasonal lines put away deliberately until next year.
  • Discontinued products kept for order history, which is the correct thing to do rather than deleting them.

All three are decisions. This check exists to separate them from the ones that were not.

How Merchlint finds it

Merchlint reads each product’s status and its product_visibility terms, and joins that against what the product earned over the past twelve months, taken from WooCommerce’s own order lookup table. It reports only products with a sales history — a hidden product that never sold is not interesting, and reporting it would bury the ones that are.

The finding shows the status, the visibility term, the date the product was last modified, and the revenue figure with the period it covers.

Confidence: F — fact from the database. A status and a taxonomy term are read; the revenue is summed from recorded orders.

Revenue is never added across currencies. A store selling in more than one gets a figure per currency, because adding them without a rate would be inventing a number.

Run this check on your store

Disagrees with what you see in your store? Write to us — we read every message. contact@merchlint.com