Custom Email Template HTML Minification and Empty Lines Bug

We are using custom email templates with programmable emails, where the body of the template is defined in an imported module.

We are doing this because are emails are rather large as a digest of our website content, and Hubspot was bloating our email significantly, causing it to get truncated in gmail very quickly.

We noticed one of our emails was still getting truncated earlier than expected, so I looked at the rendered HTML to see if there was any opportunity to further optimize it. What I discovered was two issues:

  1. Hubspot is not removing empty lines or applying any non-descructive minification
    1. There seems to be no minification happening and I can’t seem to find any way to adjust how hubspot handles our HTML.
    2. I’m also not sure of a reasonable workflow where we can manually minify the programmable email and keep the templates where we can easily edit them.
  2. Loops generate new lines even if there is no output text
    1. This doesn’t seem to be consistent with the example in the docs where they are updating a property in a loop, then outputing the value. There is not an empty line for each iteration of the loop

Email Code Examples:

I broke out the key components of our email for testing, so will share the key snippets below:

Custom Email Template (only added my module to the default template)

<!--
 templateType: email
 isAvailableForNewContent: true
 isEnabledForEmailV3Rendering: true
-->
<!doctype html>
<html>
 <head>
 <title>{% if content.html_title and content.html_title != '' %}{{ content.html_title }}{% else %}{{ content.body.subject }}{% endif %}</title>
 {% if content.meta_description %}<meta name="description" content="{{ content.meta_description }}"/>{% endif %}
 <style type="text/css" id="hs-inline-css">
 /*<![CDATA[*/
 /* everything in this style tag will be inlined onto matching elements */
 .sample-rule {
 }
 /*]]>*/
 </style>
 </head>
 <body>
 <!-- Preview text (text which appears right after subject in certain email clients) -->
 <div id="preview_text" style="display:none!important">{% text "preview_text" label="Preview Text <span class=help-text>This will be used as the preview text that displays in some email clients</span>", value="", no_wrapper=True %}</div>
 <!-- View as webpage link -->
 {% if content.create_page %}
 <div>
 Not rendering correctly? <a class="hubspot-mergetag" data-viewaswebpage="true" href="{{ view_as_page_url }}">View this email as a web page</a>.
 </div>
 {% endif %}

 {% module "nick_testing_module" path='/Testing/nick_testing_module', label="nicks module" %}

 <!-- Office location information and unsubscribe links -->
 <p id="footer">
 {{ site_settings.company_name }} 
 {{ site_settings.company_street_address_1 }} 
 {{ site_settings.company_street_address_2 }} 
 {{ site_settings.company_city }} 
 {{ site_settings.company_state }} 
 {{ site_settings.company_zip }} 
 {{ site_settings.company_country }} 
 <br/>
 You received this email because you are subscribed to {{ subscription_name }} from {{ site_settings.company_name }}.
 <br/>
 <a class="hubspot-mergetag" data-unsubscribe="true" href="{{ unsubscribe_link }}">Update your email preferences</a> to choose the types of emails you receive.
 <br/>
 <a class="hubspot-mergetag" data-unsubscribe="true" href="{{ unsubscribe_link_all }}">Unsubscribe from all future emails.</a>
 </p>
 </body>
</html>

Module with Loop

{# Define the offers we want to get by the custom id property offer_id, plus the fields to request each offer #}
{% set offer_ids = '21492984,21492637,21492671,21492983,21492631,21492916,21492940,21492640,21492681,21492689,21492974,21492652,21492654,21492591,21492577,21492982,21492636,21492978,21492955,21492649,21490191,21492558,21492612,21492976,21492946' %}

{% set offer_fields = 'offer_id,offer_title,headline,image_url,universal_url,value_statement,click_url,promoted' %}

{# Get offers by comma separated list of offer_ids #}
{% set unsorted_offers = crm_objects('offers', 'offer_id__in=' ~ offer_ids ~ '&limit=100', offer_fields) %}
{% set unsorted_offers = unsorted_offers.results %} 

{# Hubspot doesn't return the offers in the order we requested, so create new sorted list 

 THIS IS WHERE THE EXTRA LINES ARE ADDED

 If you put the entire for-loop on one line, the issue goes away, but hurts code readability

#}
{% set offers = [] %}
{% for offer_id in offer_ids|split(',') %}
 {% for offer in unsorted_offers %}
 {% if (offer.offer_id|int) == offer_id|int %}
 {% do offers.append(offer) %}
 {% endif %}
 {% endfor %}
{% endfor %} 

{{ offer_ids }}
{{ unsorted_offers|join(',', 'offer_id') }}
{{ offers|join(',', 'offer_id') }}

Rendered Output HTML

Here, you’ll see the basic start of the template, then 1000+ emply lines, then the output of:

  • The offer ids we requested from crm_objects
  • The offer ids in the order that they were returned from crm_objects (can’t simply sort the list because we have it in a specific order)
  • The offer ids after performing the loop-based sort
<!doctype html><html><head>
 <title></title>

 <style type="text/css" id="hs-inline-css">
 /*<![CDATA[*/
 /* everything in this style tag will be inlined onto matching elements */
 .sample-rule {
 }
 /*]]>*/
 </style>
 <base href="https://21305817.hubspotpreview-na1.com" target="_blank"><meta name="generator" content="HubSpot"><meta name="viewport" content="width=device-width, initial-scale=1"><meta property="og:url" content="https://info.dealnews.com/7dea362b-3fac-3e00-956a-4952a3d4f474"><meta name="x-apple-disable-message-reformatting"><meta name="robots" content="noindex,follow"></head>
 <body>
 <!-- Preview text (text which appears right after subject in certain email clients) -->

 <!-- View as webpage link -->

 <div>
 Not rendering correctly? <a class="hubspot-mergetag" data-viewaswebpage="true" href="https://info.dealnews.com/7dea362b-3fac-3e00-956a-4952a3d4f474" data-hs-link-id="0" target="_blank">View this email as a web page</a>.
 </div>

 <div id="hs_cos_wrapper_nick_testing_module" class="hs_cos_wrapper hs_cos_wrapper_widget hs_cos_wrapper_type_module" style="color: inherit; font-size: inherit; line-height: inherit;" data-hs-cos-general-type="widget" data-hs-cos-type="module">

21492984,21492637,21492671,21492983,21492631,21492916,21492940,21492640,21492681,21492689,21492974,21492652,21492654,21492591,21492577,21492982,21492636,21492978,21492955,21492649,21490191,21492558,21492612,21492976,21492946
21490191,21492558,21492577,21492591,21492612,21492637,21492631,21492636,21492640,21492649,21492654,21492652,21492681,21492671,21492689,21492916,21492940,21492955,21492976,21492983,21492946,21492974,21492978,21492982,21492984
21492984,21492637,21492671,21492983,21492631,21492916,21492940,21492640,21492681,21492689,21492974,21492652,21492654,21492591,21492577,21492982,21492636,21492978,21492955,21492649,21490191,21492558,21492612,21492976,21492946</div>
 <!-- Office location information and unsubscribe links -->
 <p id="footer" style="margin-bottom: 1em; ">
 DealNews 
 501 Madison Street SE 
  
 Huntsville 
 AL 
 35801 
  
 <br>
 You received this email because you are subscribed to emails from DealNews.
 <br>
 <a class="hubspot-mergetag" data-unsubscribe="true" href="https://info.dealnews.com/hs/preferences-center/en/page?data=W2nXS-N30h-GnW4tCG3m251GplW1X7dG92-svxxW3NCqxL1QzpnvW308vn63VLDBQW3_FW9G47xhVBW2FDqSQ3XWDwHW1QfdtX3R16QmW3D-PPC2THr6RW1Zd5qY1NprhKW2RQJt_47s_j7W2CGn752PSw-rW2FMWK43LDTJ0W1ZfMPM1V0ny4W235FjB3drTt7W4tCgTL2Kn8-XW4r6FvB2zw_XHW2KRj824ftbvJW2WL5w-2Rg8cmW4m9B814klSSsW2FM7fp38xqSDW3Hc1SB4rBCggW2zXKmB49LMJgW2MT-Xd1_l5r8W3ST6fd3H622QW2569W52RwqNcW3Q_2fy2YD5h_W1NdKnP1--XJ4W2WJmNG2ztYJ7W3R6w_s4r7sWSW1QB9x64fJJbbW3QDtdh3QCZHtW2r4Trh41tWdqW4fNpVT1S4hZqW3LRdmg2YmhkG0" data-hs-link-id="0" target="_blank">Update your email preferences</a> to choose the types of emails you receive.
 <br>
 <a class="hubspot-mergetag" data-unsubscribe="true" href="https://info.dealnews.com/hs/preferences-center/en/direct?data=W2nXS-N30h-MdW4px7by2Mk0d6W3T0XK33813zCW3dyPnk3_Z8-xW2xNx0J2HB-9kW329xGh22WqbTW3ZW2Tf2Kx4xYW1Nmgs34fr2xNW2HCNL44csZJJW4t6trZ4pCb2ZW4tl65z4cHFvtW2C-NB53NMkhZW2RLSMM3bvbR9W1VrJyR3XZBtrW4fyl_S2xZt_fW3yQDcN41ZMcPW4mtLDM1Xmlb9W1VgWPj1Vs5fMW3S-N242xZ8CXW2PyM3c2MmXsNW2qG6qj2t0sv6W3M7k_-1Sjt4rW3_sW-634DXBxW49wDNr1ShxNNW4rnrzm3bdsyrW4cw0YQ2FFM8hW2YtxsB1QyZd_W4frwbF3ST8xjW2RjBby386VNYW1_3tGH1Xvp0SW47wPXy2nSLJ7W2HJR7g20VQM4W43VpxX32t03zW1ShzDw2HT9_YW3QS7Bc212sJh0" data-hs-link-id="0" target="_blank">Unsubscribe from all future emails.</a>
 </p>

</body></html>

Hey, @rothnic, happy Thursday!

I would recommend connecting with HubSpot Technical Support, as Support is included in your subscription, and they will be able to provide real-time assistance for this matter, including hopping on a screen share if necessary.

Kindly,

Pam

Have you tried adding a minus sign to your expressions and comments? It’s an indicator to remove white space at the start and end of a block.

{%- expression -%}
{#- comment -#}