Customizing WooCommerce email templates can be tricky if you’re unsure where to hook your code. WooCommerce uses well-placed action hooks throughout its email templates—letting developers add content like upsell messages, order instructions, and dynamic blocks without touching core files.

This guide gives you a visual breakdown of WooCommerce email hook positions and provides developer-ready code snippets to help you extend and personalize your store’s emails efficiently.

Why Use Hooks Instead of Overriding Templates?

  • No need to duplicate and manage template files
  • Better compatibility with WooCommerce updates
  • Easier to maintain and version in code repositories
  • Great for plugin developers or child theme authors

Email Template Structure with Hooks

Here’s a hook layout inside a typical WooCommerce order email (customer_completed_order, new_order, etc.):

 woocommerce_email_header                              → Email header area                          

 woocommerce_email_before_order_table             
     → Custom message or notification             

 [ Order table: Items, totals, etc. ]             

 woocommerce_email_after_order_table              
     → Additional notes, recommendations          

 woocommerce_email_order_meta                     
     → Shipping method, custom order meta         

 woocommerce_email_customer_details               
     → Billing and shipping details               

 woocommerce_email_footer                        
    → Branding, contact info, social links      

Example 1: Add Message After Order Table

Let’s inject a dynamic thank-you note after the order table:

add_action( 'woocommerce_email_after_order_table', 'devguide_custom_email_note', 20, 4 );

function devguide_custom_email_note( $order, $sent_to_admin, $plain_text, $email ) {
    if ( $email->id === 'customer_completed_order' ) {
        echo '<p style="font-size:16px; color:#3c763d;">
            Thanks for your order! Use <strong>WELCOME10</strong> for 10% off next time.
        </p>';
    }
}

Example 2: Add Content Only for Admin’s New Order Email

Use $email->id to conditionally hook into a specific template:

add_action( 'woocommerce_email_after_order_table', 'devguide_admin_note', 10, 4 );

function devguide_admin_note( $order, $sent_to_admin, $plain_text, $email ) {
    if ( $email->id === 'new_order' && $sent_to_admin ) {
        echo '<p><strong>🛠 Note:</strong> This order contains custom attributes. Check before dispatch.</p>';
    }
}

Example 3: Recommend a Product in Emails

Add upsell product suggestions dynamically:

add_action( 'woocommerce_email_after_order_table', 'devguide_recommended_product', 25, 4 );

function devguide_recommended_product( $order, $sent_to_admin, $plain_text, $email ) {
    if ( $email->id !== 'customer_completed_order' ) return;

    $product_id = 123; // Change to your product ID
    $product = wc_get_product( $product_id );

    if ( $product ) {
        echo '<hr><h3>You might also like:</h3>';
        echo '<p><a href="' . get_permalink( $product_id ) . '">' . esc_html( $product->get_name() ) . '</a></p>';
    }
}

Hookable Email IDs for Reference

Email Trigger$email->id Value
New Order (admin)new_order
Cancelled Ordercancelled_order
Failed Orderfailed_order
Customer Invoicecustomer_invoice
Order Note to Customercustomer_note
Processing Ordercustomer_processing_order
Completed Ordercustomer_completed_order
Refunded Ordercustomer_refunded_order
Reset Passwordcustomer_reset_password
New Account Registrationcustomer_new_account

Use these IDs with $email->id checks to conditionally execute logic inside your hooks.

Optional: Customize the Email Footer

Enhance branding or add social links in the footer:

add_action( 'woocommerce_email_footer', 'devguide_custom_footer', 10 );

function devguide_custom_footer() {
    echo '<p style="text-align:center; font-size:14px;">
        Follow us on <a href="https://twitter.com/yourhandle">Twitter</a> for updates.
    </p>';
}

Want to Customize Templates Instead?

You can override templates directly via your theme:

/yourtheme/woocommerce/emails/email-order-details.php

But using hooks is safer, more maintainable, and works better for plugin-based solutions.

Summary

  • Use WooCommerce email hooks to inject content into transactional emails without touching templates.
  • Use $email->id to target specific email types.
  • Use add_action() with proper priority to control positioning.
  • Prefer this method over template overrides for long-term maintainability.