WooCommerce adds hundreds of its own action and filter hooks on top of WordPress’s core hooks. Knowing the key ones saves a lot of time when you need to modify checkout fields, product output, order processing, or emails without overriding template files.
Problem: How do you find the correct WooCommerce hook to customise a specific part of the product page, cart, checkout, or order email without modifying plugin files?
Solution: WooCommerce provides hundreds of documented action and filter hooks. The reference below groups the most commonly needed ones by context — product pages, cart, checkout, and transactional emails — so you can find the right hook without reading source code.
Product page hooks:
// Add content before the product title
add_action( 'woocommerce_single_product_summary', 'before_product_title', 4 );
// After product title (priority 5), price (10), excerpt (20), add-to-cart (30)
add_action( 'woocommerce_single_product_summary', 'my_callback', 25 );
// After the add-to-cart button
add_action( 'woocommerce_after_add_to_cart_button', 'after_add_to_cart' );
Checkout hooks:
// Add a custom checkout field
add_filter( 'woocommerce_checkout_fields', 'add_checkout_field' );
function add_checkout_field( $fields ) {
$fields['billing']['billing_vat'] = [
'type' => 'text',
'label' => __( 'VAT Number', 'textdomain' ),
'placeholder' => 'EU123456789',
'required' => false,
'class' => [ 'form-row-wide' ],
'priority' => 120,
];
return $fields;
}
// Save the custom field
add_action( 'woocommerce_checkout_update_order_meta', 'save_checkout_vat_field' );
function save_checkout_vat_field( $order_id ) {
if ( ! empty( $_POST['billing_vat'] ) ) {
update_post_meta( $order_id, '_billing_vat', sanitize_text_field( $_POST['billing_vat'] ) );
}
}
Order status hooks:
// Fires when an order transitions to "processing"
add_action( 'woocommerce_order_status_processing', function( $order_id ) {
$order = wc_get_order( $order_id );
// send a notification, update stock, etc.
} );
// Fires when any order status changes
add_action( 'woocommerce_order_status_changed', function( $order_id, $old_status, $new_status ) {
// log the transition
}, 10, 3 );
NOTE: Template overrides should be a last resort — hooks cover the vast majority of customisation needs and are much easier to maintain across WooCommerce updates. Check the official hook documentation before touching a template file.