My Courses > CustomizeWoo > Module 6 > Lesson 03: Add Content to Order Emails

Add Content to Order Emails


You can use this exercise as a test. Stop the video after the project description and see if you can manage to find the PHP solution. Then continue watching the video to watch me code the task.


Please note: English captions are enabled by default (click on “CC” in the video player to disable). Also, you can click on the “gear” icon to manage quality and playback speed. Enjoy!

Sorry, this video is visible to logged in and fully registered students only.
If you already enrolled in this course, please LOG IN
Otherwise, please enroll in the FREE / PRO COURSE
For any other queries, feel free to get in touch

14 thoughts on “Add Content to Order Emails

  1. Hello, Rodolfo

    I would like to know how we can remove content from emails. For example, where should we look to remove these sections from email?

    Thank you!

    1. Hi Marcel! The first bit you can’t unfortunately. They are hardcoded into the email template without any hook which would have been useful to remove such content. You could find a workaround i.e. “translate” those strings into empty strings:

      For the other section, that one you can definitely remove it. Simply look at, find the add_action that is adding that order table, and use remove_action

      Hope this helps

  2. Hi Rodolfo,

    I try to add some information about a specific product on the email the customer receives. I wrote this code and it’s working, but I would like to know your opinion about how correct it is. Thank you.

    // Add some info about this product
    add_action( 'woocommerce_email_after_order_table', 'user_click_email_after_order_table', 10, 4 );
    function user_click_email_after_order_table( $order, $sent_to_admin, $plain_text, $email ) {
        global $woocommerce;
        $items = $order->get_items();
        foreach ( $items as $item ) {
            $product_id = $item['product_id'];
            if ( $product_id == 4366 ) {
               echo '	<p>Info about this product.</p>';
    1. Hi Marcel, looks good to me. You don’t need to declare the global, but that’s not throwing an error anyway

      1. For my understanding, when exactly should I declare

        global $woocommerce;

        Thank you!

  3. Posting my code again before watching the rest of the video. 🙂

    function add_order_status_new_order_email( $order, $sent_to_admin, $plain_text, $email ) {
        $order = $email->object;
        $status = $order->get_status();
        echo 'Order status: ' . $status;
    add_action( 'woocommerce_email_after_order_table', 'add_order_status_new_order_email', 10, 4 );
    1. So it looks like I wasn’t aware that I needed to check for the right order email! Oops. And so we learn.

      I also didn’t think about accessing $order via the arguments and did it another way. Rodolfo, are there any pros/cons when looking at the way you got the $order vs the way I did it (other than a line less of code)? It will help me understand better why to do something in a specific way.

      Why is better to say true == $sent_to_admin than $sent_to_admin == true?

      Thanks so much, useful exercise!

      1. Great questions!

        1) Given that you have $order available as a function argument, it’s much faster to use it as opposed to recalculating it from $email

        2) “true == variable” is better than “variable == true” because in this way you can avoid PHP errors that can cause issues. If you forget a “=”, which is very common, “true = variable” does nothing and it just returns an error, while “variable = true” assigns the value “true” to your variable, which is going to mess your conditional. So it’s only a way to avoid mistakes. Same applies to “25 == variable” and every “IF a == b” conditional checks

        1. Aaah thanks so much Rodolfo, knowing WHY something should be done a certain way really helps me understand it better.

  4. Hello, I am trying to remove the default woocommerce email header text and replace it with my own custom text. I’ve tried a few methods and nothing has worked so far. I understand how to add new content but to replace it, do I need to first use a remove_action to remove the original text and then use an add_action to replace the content? Thank you

    1. Thanks for your comment Phoebe! Which content are you talking about specifically?

      1. I am talking about the intro paragraph in the header above the order details table. For example on the ‘on-hold’ email I want to replace this default Woocommerce text:
        “Thanks for your order. It’s on-hold until we confirm that payment has been received. In the meantime, here’s a reminder of what you ordered:”

        1. That was what I was afraid of. No hook available there (as of now). Your only choice is to “translate” those strings:

          1. Okay thank you, I’ll try it out!

Questions? Feedback? Support? Leave your comment now!

If you are writing code, please wrap it between: [php]code_here[/php]

Your email address will not be published. Required fields are marked *