Bundles grouped view email notification template updates

As of Dec 6, 2024, orders that contain bundles now display as a nested group of line items in many of your email templates.

Any notification templates that use the default template have automatically updated to display the grouped view for product bundles. If you've customized any of your email notifcation templates before Dec 6, 2024, then your notification templates aren't updated. To update your notification templates to the bundles view, you can use the following methods:

  • For all notifications in the Settings > Notifications section, you can use either of the following methods:
    • Back up your customizations, revert the templates, and then re-apply your customizations.
    • Update your current customizations by editing the code to add the bundles component Liquid object to your templates.
  • For abandoned checkout automations with Shopify Email, you can edit the existing templates in your automations to revert them.

Considerations for updating customized email templates

Review the following considerations before making any changes to your email notification templates:

  • The notification templates in the Settings > Notifications section of your Shopify admin contain Liquid, Shopify's templating language, HTML, and CSS. Edit the code for a notification template only if you know HTML and CSS, and have a basic understanding of Liquid.
  • Saving changes to your notification templates overrides the previous template code. You can revert the template back to default, but if you do revert the template, then your previous customizations to the template code are lost and can't be recovered.
  • If you want to update your templates but don't have experience editing the notification template code, then you might be able to get assistance:

Before and after the grouped view changes

Before updating your email notification templates, product bundles are display as individual line items:

Before the grouped view changes

After updating your email notification templates, product bundles display in a nested group of line items:

After the grouped view changes

List of updated email notifications for product bundles

The following notification templates display either a grouped view, or a flat view for product bundles.

Customer notifications

Description of updated email notifications for grouped view of product bundles
Notification templateAdmin locationDisplay type
Order confirmationOrder processingBundles display as a nested group.
Order invoiceOrder exceptionsBundles display as a nested group.
Pending payment errorPaymentsBundles display as a nested group.
Pending payment successPaymentsBundles display as a nested group.
POS email to customerPoint of saleBundles display as a nested group.
POS and mobile receiptPoint of saleBundles display as a nested group.
Return createdReturnsEach product in a bundle displays as separate item.
Return request receivedReturnsEach product in a bundle displays as separate item.
Return request approvedReturnsEach product in a bundle displays as separate item.
Return request declinedReturnsEach product in a bundle displays as separate item.

Staff notifications

Description of updated email notifications for grouped view of product bundles
Notification templateDisplay type
New orderBundles display as a nested group.
New return requestEach product in a bundle displays as separate item.
Sales attribution editedEach product in a bundle displays as separate item.
New draft orderBundles display as a nested group.
Abandoned checkout (in Shopify Email)Bundles display as a nested group.

Revert customized notification templates

To update customized notification templates in the Settings > Notifications section of your Shopify admin, you can manually back up any customizations to the email template, revert the template back to default, and then re-apply your customizations.

Steps:

Desktop
  1. From your Shopify admin, go to Settings > Notifications.

  2. Click Customer notifications or Staff notifications.

  3. Click the notification that you want to update.

  4. Click Edit code.

  5. Back up your existing customizations by highlighting the customizations in the template that you want to keep, copying the code, and saving it somewhere safe, such as a text file.

  6. Click Revert to default. After you revert, your customizations can't be recovered, so ensure that you've safely backed up your changes.

  7. In the dialog, click Revert changes to confirm.

  8. Re-apply your customizations to the updated template.

  9. Click Save.

iPhone
  1. From the Shopify app, tap the button.

  2. Tap Settings > Notifications.

  3. Tap Customer notifications or Staff notifications.

  4. Tap the notification that you want to update.

  5. Tap the </> button to edit the template code.

  6. Back up your existing customizations by highlighting the customizations in the template that you want to keep, copying the code, and saving it somewhere safe, such as a text file.

  7. Tap Revert to default. After you revert, your customizations can't be recovered, so ensure that you've safely backed up your changes.

  8. In the dialog, tap Revert changes to confirm.

  9. Re-apply your customizations to the updated template.

  10. Tap Save.

Android
  1. From the Shopify app, tap the button.

  2. Tap Settings > Notifications.

  3. Tap Customer notifications or Staff notifications.

  4. Tap the notification that you want to update.

  5. Tap the </> button to edit the template code.

  6. Back up your existing customizations by highlighting the customizations in the template that you want to keep, copying the code, and saving it somewhere safe, such as a text file.

  7. Tap Revert to default. After you revert, your customizations can't be recovered, so ensure that you've safely backed up your changes.

  8. In the dialog, tap Revert changes to confirm.

  9. Re-apply your customizations to the updated template.

  10. Tap .

Edit the code for your customized email templates

If you've customized the code for your email templates, then you can manually update the code to support the grouped view for product bundles. The default template code differs between templates. To update customized notification templates in the Settings > Notifications section of your Shopify admin, you can follow the instructions for each template that you need to edit.

Update order email notifications

Follow these steps to update your customized templates for the following order email notifications:

  • Order confirmation
  • New order email
  • Order invoice
  • Pending payment success
  • Pending payment error
  • POS and mobile receipt

Steps:

Desktop
  1. From your Shopify admin, go to Settings > Notifications.

  2. Click Customer notifications or Staff notifications.

  3. Click the notification that you want to update.

  4. Click Edit code.

  5. Back up your existing customizations by highlighting the customizations in the template that you want to keep, copying the code, and saving it somewhere safe, such as a text file. You can also highlight the entire template, copy it, and save it somewhere safe.

  6. Find the line item loop in the template by searching for subtotal_line_items. It will look something like this:

        {% for line in subtotal_line_items %}
  7. Wrap all of the code inside of the subtotal_line_items loop with an if condition by adding {% if line.groups.size == 0 %} right below the opening subtotal_line_items loop, and then close the the if condition by adding a {% endif %} right above the closing {% endfor %} loop.

        {% if line.groups.size == 0 %}
            <Your old code>
        {% endif %}
  8. Your code should look something like this:

        {% for line in subtotal_line_items %}
            {% if line.groups.size == 0 %}
                <Your old code>
            {% endif %}
        {% endfor %}
  9. Paste the following code after below the closing {% endfor %} tag of the subtotal_line_items line item loop:

        {% for line_item_group in line_item_groups %}
    
            {% assign final_line_price = 0 %}
            {% assign original_line_price = 0 %}
            {% assign discount_keys_str = "" %}
    
            {% for component in line_item_group.components %}
            {% assign final_line_price = final_line_price | plus: component.final_line_price %}
            {% assign original_line_price = original_line_price | plus: component.original_line_price %}
    
            {% for da in component.discount_allocations %}
                {% if da.discount_application.target_selection != 'all' %}
                {% assign discount_key = da.discount_application.title | append: da.discount_application.type %}
                {% assign discount_keys_str = discount_keys_str | append: discount_key | append: "," %}
                {% endif %}
            {% endfor %}
            {% endfor %}
    
            {% assign discount_keys = discount_keys_str | split: "," | uniq %}
    
            <tr class="order-list__item">
            <td class="order-list__item__cell">
                <table>
                    <td class="order-list__parent-image-cell">
                    {% if line_item_group.image %}
                        <img src="{{ line_item_group | img_url: 'compact_cropped' }}" align="left" width="60" height="60" class="order-list__product-image"/>
                    {% else %}
                        <div class="order-list__no-image-cell">
                        <img src="{{ 'notifications/no-image.png' | shopify_asset_url }}" align="left" width="60" height="60" class="order-list__no-product-image"/>
                        </div>
                    {% endif %}
                </td>
                <td class="order-list__product-description-cell">
                    <span class="order-list__item-title">{{ line_item_group.title }}&nbsp;&times;&nbsp;{{ line_item_group.quantity }}</span><br/>
    
                    {% for discount_key in discount_keys %}
                    {% assign discount_amount = 0 %}
    
                    {% for component in line_item_group.components %}
                        {% for da in component.discount_allocations %}
                        {% assign key = da.discount_application.title | append: da.discount_application.type %}
                        {% if da.discount_application.target_selection != 'all' and key == discount_key %}
                            {% assign discount_amount = discount_amount | plus: da.amount %}
                            {% assign discount_title = da.discount_application.title %}
                        {% endif %}
                        {% endfor %}
                    {% endfor %}
    
                    <p>
                        <span class="order-list__item-discount-allocation">
                        <img src="{{ 'notifications/discounttag.png' | shopify_asset_url }}" width="18" height="18" class="discount-tag-icon" />
                        <span>
                            {{ discount_title | upcase }}
                            (-{{ discount_amount | money }})
                        </span>
                        </span>
                    </p>
                    {% endfor %}
    
                    {% for component in line_item_group.components %}
                    <table>
                        <tr class="order-list__item">
                        <td class="order-list__bundle-item">
                            <table>
                            <td class="order-list__image-cell">
                                {% if component.image %}
                                <img src="{{ component | img_url: 'compact_cropped' }}" align="left" width="40" height="40" class="order-list__product-image"/>
                                {% else %}
                                <div class="order-list__no-image-cell small">
                                    <img src="{{ 'notifications/no-image.png' | shopify_asset_url }}" align="left" width="40" height="40" class="order-list__no-product-image small"/>
                                </div>
                                {% endif %}
                            </td>
    
                            <td class="order-list__product-description-cell">
                                {% if component.product.title %}
                                {% assign component_title = component.product.title %}
                                {% else %}
                                {% assign component_title = component.title %}
                                {% endif %}
    
                                <span class="order-list__item-title">{{ component.quantity }}&nbsp;&times;&nbsp;{{ component_title }}</span><br>
    
                                {% if component.variant.title != 'Default Title'%}
                                <span class="order-list__item-variant">{{ component.variant.title }}</span>
                                {% endif %}
                            </td>
                            </table>
                        </td>
                        </tr>
                    </table>
                    {% endfor %}
                </td>
    
                    <td class="order-list__parent-price-cell">
                    {% if original_line_price != final_line_price %}
                    <del class="order-list__item-original-price">{{ original_line_price | money }}</del>
                    {% endif %}
                    <p class="order-list__item-price">
                        {% if final_line_price > 0 %}
                        {{ final_line_price | money }}
    
                        {% else %}
                        Free
                        {% endif %}
                    </p>
                    </td>
                </table>
            </td>
            </tr>
            {% endfor %}
            </table>
    
                        <table class="row subtotal-lines">
            <tr>
                <td class="subtotal-spacer"></td>
                <td>
                <table class="row subtotal-table">
    
            {% assign total_order_discount_amount = 0 %}
            {% assign has_shipping_discount = false %}
            {% assign epsilon = 0.00001 %}
    
            {% for discount_application in discount_applications %}
            {% if discount_application.target_selection == 'all' and discount_application.target_type == 'line_item' %}
                {% assign order_discount_count = order_discount_count | plus: 1 %}
                {% assign total_order_discount_amount = total_order_discount_amount | plus: discount_application.total_allocated_amount %}
            {% endif %}
            {% if discount_application.target_type == 'shipping_line' %}
                {% assign has_shipping_discount = true %}
                {% assign shipping_discount_title = discount_application.title %}
                {% if discount_application.total_allocated_amount == 0 %}
                {% assign discount_value_price = discount_application.value | times: 100 %}
                {% else %}
                {% assign discount_value_price = discount_application.total_allocated_amount %}
                {% endif %}
                {% assign shipping_amount_minus_discount_value_price = shipping_price | minus: discount_value_price %}
                {% assign shipping_amount_minus_discount_value_price_abs = shipping_amount_minus_discount_value_price | abs %}
                {% assign discount_application_value_type = discount_application.value_type | strip %}
                {% if shipping_amount_minus_discount_value_price_abs < epsilon or discount_application_value_type == 'percentage' and discount_application.value == 100 %}
                {% assign free_shipping = true %}
                {% else %}
                {% assign discounted_shipping_price = shipping_amount_minus_discount_value_price %}
                {% endif %}
            {% endif %}
        {% endfor %}
  10. Click Save.

Update draft order and abandoned checkout email notifications

Follow these steps to update your customized templates for the following email notifications:

  • New draft order
  • Abandoned cart
  • Draft order invoice
  • POS email to customer

Steps:

Desktop
  1. From your Shopify admin, go to Settings > Notifications.

  2. Click Customer notifications or Staff notifications.

  3. Click the notification that you want to update.

  4. Click Edit code.

  5. Back up your existing customizations by highlighting the customizations in the template that you want to keep, copying the code, and saving it somewhere safe, such as a text file.

  6. Find the line item loop in the template by searching for subtotal_line_items. It will look something like this:

        {% for line in subtotal_line_items %}
  7. Paste the following code right after the opening {% for line in subtotal_line_items %} loop:

        {% assign expand_bundles = true %}
  8. Find the block that renders a product image. It should look something like this:

        <td class="order-list__image-cell">
            {% if line.image %}
                <img src="{{ line | img_url: 'compact_cropped' }}" align="left" width="60" height="60" class="order-list__product-image"/>
            {% else %}
                <div class="order-list__no-image-cell">
                <img src="{{ 'notifications/no-image.png' | shopify_asset_url }}" align="left" width="60" height="60" class="order-list__no-product-image"/>
                </div>
            {% endif %}
        </td>
  9. Modify the order-list__image-cell class by wrapping it in an {% if expand_bundles and line.bundle_parent? %} if condition, and adding an alternate class. This changes the image template so that if the {% assign expand_bundles = true %} variable is true, then the image class changes from order-list__parent-image-cell to order-list__image-cell. Your template code should look like this:

        <td 
            {% if expand_bundles and line.bundle_parent? %}
                class="order-list__parent-image-cell"
            {% else %}
                class="order-list__image-cell"
            {% endif %}
            >
            {% if line.image %}
                <img src="{{ line | img_url: 'compact_cropped' }}" align="left" width="60" height="60" class="order-list__product-image"/>
            {% else %}
                <div class="order-list__no-image-cell">
                <img src="{{ 'notifications/no-image.png' | shopify_asset_url }}" align="left" width="60" height="60" class="order-list__no-product-image"/>
                </div>
            {% endif %}
        </td>
  10. Find the code that renders the variant title. It should look something like this:

        {% if line.variant.title != 'Default Title' %}
            <span class="order-list__item-variant">{{ line.variant.title }}</span><br/>
        {% endif %}
  11. To hide the variant title for the product bundle, add and line.bundle_parent? == false to the {% if line.variant.title != 'Default Title' %} if condition, and then add an elsif condition. It should look like this:

        {% if line.variant.title != 'Default Title' and line.bundle_parent? == false %}
            <span class="order-list__item-variant">{{ line.variant.title }}</span><br/>
        {% elsif line.variant.title != 'Default Title' and line.bundle_parent? and expand_bundles == false %}
            <span class="order-list__item-variant">{{ line.variant.title }}</span><br/>
        {% endif %}
  12. Optional: Find the code that renders the price. It should have the order-list__price-cell class. The Abandoned cart email notification doesn’t have this, but Draft orders notification templates. It should look something like this:

        <td class="order-list__price-cell">
  13. Add an if statement and additional class for the price to update the price for the main bundle. It should look like something like this:

        <td 
        {% if expand_bundles and line.bundle_parent? %}
            class="order-list__parent-price-cell"
        {% else %}
            class="order-list__price-cell"
        {% endif %}
        >
  14. Search for either flat view or Part of: code in a {% for group in line.groups %} for loop. Old email templates might not have this code.

        {% for group in line.groups %}
            <span class="order-list__item-variant">Part of: {{ group.display_title }}</span><br/>
        {% endfor %}
  15. Replace the entire {% for group in line.groups %} loop with the following code:

        {% if expand_bundles %}
            {% for component in line.bundle_components %}
                <table>
                <tr class="order-list__item">
                    <td class="order-list__bundle-item">
                    <table>
                        <td class="order-list__image-cell">
                        {% if component.image %}
                            <img src="{{ component | img_url: 'compact_cropped' }}" align="left" width="40" height="40" class="order-list__product-image small"/>
                        {% elsif component.image_url %}
                            <img src="{{ component.image_url }}" align="left" width="40" height="40" class="order-list__product-image small"/>
                        {% else %}
                            <div class="order-list__no-image-cell small">
                            <img src="{{ 'notifications/no-image.png' | shopify_asset_url }}" align="left" width="40" height="40" class="order-list__no-product-image small"/>
                            </div>
                        {% endif %}
                        </td>
    
                        <td class="order-list__product-description-cell">
                        {% if component.product.title %}
                            {% assign component_title = component.product.title %}
                        {% else %}
                            {% assign component_title = component.title %}
                        {% endif %}
    
                        {% assign component_display = component.quantity %}
    
                        <span class="order-list__item-title">{{ component_title }}&nbsp;&times;&nbsp;{{ component_display }}</span><br>
    
                        {% if component.variant.title != 'Default Title'%}
                            <span class="order-list__item-variant">{{ component.variant.title }}</span>
                        {% endif %}
                        </td>
                    </table>
                    </td>
                </tr>
                </table>
            {% endfor %}
            {% else %}
            {% for group in line.groups %}
                <span class="order-list__item-variant">Part of: {{ group.display_title }}</span><br/>
            {% endfor %}
        {% endif %}
  16. Click Save.

Update Abandoned cart or Abandoned checkout emails by editing the workflow

If you set up abandoned checkout automations, then you can update your abandoned checkout email to display grouped views of product bundles by editing your existing Recover abandoned checkout email template.

Steps:

Desktop
  1. From your Shopify admin, go to Marketing > Automations.

  2. Click on the marketing flow that you want to edit.

  3. Click Edit.

  4. Click Turn off automation.

  5. In the dialog, click Turn off.

  6. Click Edit.

  7. In the flow automation, click Send Marketing Email.

  8. Click Edit email.

  9. In the Editing this email will revert it to draft dialog, click Continue.

  10. Make any of the following edits to your email template:

    • Add a subject to the Subject line
    • Add any additional text or sections to your template
  11. Optional: To review your email, click Send test and enter the email address that you want receive the email at. In your inbox, open the email and review it.

  12. Click Set to active.

  13. Click Turn on automation.

iPhone
  1. From the Shopify app, tap the button.

  2. Tap Settings > Marketing.

  3. Tap Automations.

  4. Next to the marketing flow that you want to edit, tap > Turn off.

  5. In the dialog, tap Turn off.

  6. Tap the marketing flow.

  7. Next to the marketing email, tap > Edit.

  8. In the Editing this email will revert it to draft dialog, tap Continue.

  9. Add a subject to the Subject line, and then make any additional text or sections to your template.

  10. Optional: To review your email, tap Send test and enter the email address that you want receive the email at. In your inbox, open the email and review it.

  11. Tap Set to active.

  12. Tap > Turn on automation.

Android
  1. From the Shopify app, tap the button.

  2. Tap Settings > Marketing.

  3. Tap Automations.

  4. Next to the marketing flow that you want to edit, tap > Turn off.

  5. In the dialog, tap Turn off.

  6. Tap the marketing flow.

  7. Next to the marketing email, tap > Edit.

  8. In the Editing this email will revert it to draft dialog, tap Continue.

  9. Add a subject to the Subject line, and then make any additional text or sections to your template.

  10. Optional: To review your email, tap Send test and enter the email address that you want receive the email at. In your inbox, open the email and review it.

  11. Tap Set to active.

  12. Tap > Turn on automation.

Update Abandoned Cart or Abandoned checkout emails from the marketing automation summary page

If you set up abandoned checkout automations, then you can update your abandoned checkout email to display grouped views of product bundles by editing the Abandoned cart or Abandoned checkout section.

Steps:

Desktop
  1. From your Shopify admin, go to Marketing > Automations.

  2. Click on the marketing flow that you want to edit.

  3. In the Activity name section, click the thumbnail of the template that you want to edit.

  4. Click Edit.

  5. In the Editing this email will revert it to draft dialog, click Continue.

  6. Click the trash icon next to the Abandoned checkout or Abandoned cart section of the template.

  7. Click + Add section.

  8. Click either the Abandoned cart or Abandoned checkout section.

  9. Optional: To review your email, tap Send test and enter the email address that you want receive the email at. In your inbox, open the email and review it.

  10. Click Set to active.

iPhone
  1. From the Shopify app, tap the button.

  2. Tap Settings > Marketing.

  3. Tap Automations.

  4. Next to the marketing flow that you want to edit, tap > Turn off.

  5. Tap the marketing flow.

  6. Tap the thumbnail of the template that you want to edit.

  7. Tap Edit.

  8. In the Editing this email will revert it to draft dialog, tap Continue.

  9. Swipe up to edit the template.

  10. Long press on the Abandoned checkout or Abandoned cart section, and then tap the trash can icon.

  11. Tap the + button and then tap either Abandoned cart or Abandoned checkout section.

  12. Optional: To review your email, tap Send test and enter the email address that you want receive the email at. In your inbox, open the email and review it.

  13. Tap Set to active.

Android
  1. From the Shopify app, tap the button.

  2. Tap Settings > Marketing.

  3. Tap Automations.

  4. Next to the marketing flow that you want to edit, tap > Turn off.

  5. Tap the marketing flow.

  6. Tap the thumbnail of the template that you want to edit.

  7. Tap Edit.

  8. In the Editing this email will revert it to draft dialog, tap Continue.

  9. Swipe up to edit the template.

  10. Long press on the Abandoned checkout or Abandoned cart section, and then tap the trash can icon.

  11. Tap the + button and then tap either Abandoned cart or Abandoned checkout section.

  12. Optional: To review your email, tap Send test and enter the email address that you want receive the email at. In your inbox, open the email and review it.

  13. Tap Set to active.

Can’t find the answers you’re looking for? We’re here to help.