Blog Ecommerce 8 min read

WooCommerce Placeholder Image for Products Without Photos

Replace or customize the woocommerce placeholder image using filter hooks, a URL-based API, and proper dimensions so product grids look complete before photos are uploaded.

WooCommerce placeholder imageWooCommerce product photosWordPress ecommerceProduct image fallbackFilter hooks
WooCommerce Placeholder Image for Products Without Photos

WooCommerce ships with a built-in placeholder image that appears when products have no photos, but it is a static gray box that offers no product context and does not match custom theme aspect ratios. Replacing the woocommerce placeholder image via filter hooks takes less than ten lines of PHP.

This guide covers the woocommerce_placeholder_img_src filter, building dynamic URL-based placeholders from product metadata, handling variable products, and managing the performance implications of external placeholder requests in a catalog with thousands of products.

Default behavior

How WooCommerce handles missing product images

WooCommerce stores its default placeholder image in the plugin assets folder. When a product has no featured image, WooCommerce outputs this generic placeholder on all product loops, single product pages, cart items, and order emails. The path is controlled by the woocommerce_placeholder_img_src filter.

The default placeholder is a low-resolution JPG with a shopping bag icon. It does not include product name, category, or any identifying information. In a store during active inventory upload, dozens of products can show the same generic placeholder simultaneously, making it hard to distinguish incomplete entries.

Swapping it for a URL-based placeholder that encodes the product name or SKU makes QA significantly easier. Any incomplete product in the catalog is immediately identifiable by the text on its placeholder image.

Filter hook

Using woocommerce_placeholder_img_src to replace the default

The simplest customization is a global static replacement. Add the filter to your theme's functions.php or a site-specific plugin. This replaces the placeholder for every product without images in the entire store.

For a static placeholder that matches your brand colors, point the filter return value at a fixed fallback.pics URL with your preferred dimensions, background, and text. WooCommerce uses the returned URL in every context where it would normally show its default placeholder.

Implementation text
<?php
// Static replacement – functions.php or site plugin
add_filter( 'woocommerce_placeholder_img_src', function( $src ) {
  return 'https://fallback.pics/api/v1/400x400/F3F4F6/9CA3AF?text=No+Photo';
} );

// Optionally override the full <img> HTML for more control:
add_filter( 'woocommerce_placeholder_img', function( $html, $size ) {
  $sizes = [
    'thumbnail'      => '100x100',
    'shop_catalog'   => '300x300',
    'shop_single'    => '600x600',
    'shop_thumbnail' => '100x100',
  ];
  $dim = $sizes[ $size ] ?? '300x300';
  $src = 'https://fallback.pics/api/v1/' . $dim . '/F3F4F6/9CA3AF?text=No+Photo';
  return '<img src="' . esc_url( $src ) . '" alt="No product image" '
       . 'class="woocommerce-placeholder wp-post-image" />';
}, 10, 2 );

Dynamic labels

Product-specific placeholders from WooCommerce metadata

A static placeholder is fine for stores where all products eventually get photos. For stores that sell digital products or services without photos, or for B2B wholesale catalogs, a placeholder labeled with the product name or SKU is more useful long-term.

You cannot directly pass WooCommerce product data to the woocommerce_placeholder_img_src filter because it does not receive a product object. Instead, filter woocommerce_loop_add_to_cart_link or use the woocommerce_before_shop_loop_item action to inject a custom image tag where you do have access to the global $product.

Implementation text
<?php
// Access product data in the loop for dynamic placeholder text
add_action( 'woocommerce_before_shop_loop_item_title', function() {
  global $product;

  if ( $product && ! $product->get_image_id() ) {
    $name = urlencode( $product->get_name() );
    $sku  = $product->get_sku() ? ' (' . urlencode( $product->get_sku() ) . ')' : '';
    $src  = 'https://fallback.pics/api/v1/300x300/F3F4F6/6B7280?text=' . $name . $sku;
    echo '<img src="' . esc_url( $src ) . '" alt="' . esc_attr( $product->get_name() ) . '" '
       . 'width="300" height="300" class="woocommerce-placeholder" />';
  }
}, 5 );

Cart and emails

Placeholder images in cart, order, and email views

WooCommerce uses the placeholder image in cart line items, order confirmation pages, and order notification emails. The woocommerce_placeholder_img_src filter applies consistently across all of these contexts.

Email clients block external images by default in many corporate environments. For transactional email contexts, a plain colored rectangle with no text may be safer than a detailed labeled placeholder. Consider a separate simpler URL for email-specific contexts if you have the ability to hook into the email rendering flow.

In the cart, customers can see placeholder images for items they just added. This is acceptable if the placeholder is clean, but label it with 'No Image' or the product name so the cart line item is clearly associated with the right product.

Performance

CDN caching and performance for WooCommerce placeholder requests

Fallback.pics URLs are deterministic, which means the CDN caches the response at the edge. For a catalog with 500 products and no images, all 500 products that use the same static placeholder URL share a single CDN cache entry. The performance overhead is one HTTP request per unique URL.

For dynamic labeled placeholders where each product has a different text parameter, each URL is unique and caches separately. The CDN still handles these efficiently, but your catalog page will generate more distinct cache entries. This is usually a worthwhile tradeoff for the QA visibility gains.

Key takeaways

What to standardize before shipping

  • Use the woocommerce_placeholder_img_src filter for a global static replacement in under ten lines of PHP.
  • Filter woocommerce_placeholder_img when you need size-aware placeholders at different WooCommerce contexts.
  • Access the global $product in loop actions to build dynamic labeled placeholders from product names or SKUs.
  • Deterministic URLs for the same placeholder type share a single CDN cache entry, keeping performance overhead low.
  • Label cart and order placeholders clearly so customers and support staff can identify products from screenshots.

Production fallback layer

Use fallback.pics anywhere an image URL is accepted.

Start with one deterministic URL and standardize fallback behavior across your design system.

Read the docs