In short. Customize WooCommerce product structured data with its product or offer filter, return the modified array, and validate the page output.
Definition: Customizing WooCommerce's product structured data means changing the machine-readable product information embedded in a page as JSON-LD markup. As of 17 October 2026, WooCommerce documents PHP filters for changing the offer data and the complete product data before output.
Key facts
- WooCommerce's product structured data reference names
woocommerce_structured_data_product_offerfor offers andwoocommerce_structured_data_productfor the complete product array. - The WooCommerce implementation passes the markup array and the product object to both filters.
- WordPress's
add_filter()reference requires the accepted argument count to match the callback; its default is one argument. - WooCommerce's customization guidance recommends the Code Snippets plugin for adding small PHP snippets and keeping them through theme updates.
Which filter controls the required data?
The WooCommerce product reference describes woocommerce_structured_data_product_offer as the filter for prices represented as offers. The offer array's format varies with the product type. woocommerce_structured_data_product receives the complete product array and supports changing or adding values.
The structured data class applies the offer filter before placing its result inside the product's offers array. It applies the product filter after assembling the product data, so that callback also has access to the assembled offers.
The same class exposes broader extension points. woocommerce_structured_data_type_for_page filters the list of data types selected for output on a page. woocommerce_structured_data_context filters the context array containing @context, which identifies the vocabulary used by the markup. These hooks act at the page selection and data assembly stages. The class attaches product generation to woocommerce_single_product_summary and outputs the assembled markup through wp_footer.
How is a product callback registered?
WooCommerce's reference example assigns the product ID to the product identifier field sku for a store that does not use SKUs. The following adaptation includes the argument count required by WordPress:
add_filter( 'woocommerce_structured_data_product', function( $markup, $product ) {
$markup['sku'] = $product->get_id();
return $markup;
}, 10, 2 );
WordPress's add_filter() documentation defines 10 as the default priority and the final argument as the number of arguments accepted by the callback. Here, 2 allows the function to receive both $markup and $product. Returning $markup supplies the modified array to WooCommerce. The reference's shorter registration omits that final argument even though its callback declares both parameters.
This example replaces the markup's SKU with the product ID for each product that reaches the filter. It is appropriate only where that identifier matches the store's product information. Google's structured data guidelines require current information and prohibit marking up content hidden from readers.
For installation, WooCommerce's customization guidance describes adding PHP through Code Snippets, with controls to activate or deactivate each snippet.
How is the resulting markup checked?
The WooCommerce reference instructs readers to view a product page's source and search for this script type:
application/ld+json
The generated data can include products and breadcrumbs. Checking the product object reveals whether the callback changes the intended field.
Google's Rich Results Test help documents testing either a full page URL or a code snippet through the Code option. Its results identify detected items and provide details for errors and warnings. URL tests require page resources that an anonymous internet user can access.
Related terms
- Where does WooCommerce generate Product JSON-LD?
- Where do I enter a product's identifiers in WooCommerce?
- Product structured data
- JSON-LD
FAQ
Can I change only the offer data?
Yes. WooCommerce's product reference documents woocommerce_structured_data_product_offer for this purpose. Its input is an offer array whose format depends on the product type.
Why does my callback need the final argument count?
If your callback expects both the markup and the product object, register it with 2 accepted arguments. WordPress's add_filter() reference documents a default of one accepted argument.
Does this example change the stored product SKU?
The WooCommerce implementation sends the filtered array to set_data(), which stores the structured data for output. The example assigns a value to $markup['sku'] and reads the product ID; it performs no product save.
Sources
- WooCommerce, "Structured data for products", updated 16 April 2019
- WooCommerce, "class-wc-structured-data.php", undated
- WordPress, "add_filter()", undated
- WooCommerce, "Customizing WooCommerce: Best Practices", undated
- Google Search Central, "General structured data guidelines", updated 10 July 2026
- Google Search Console Help, "Rich Results Test", undated
Check how a page reads to answer engines. Open the GEO score analyzer