Unwanted <br> tag getting added above HTML table in email notification

Somujit1
Tera Contributor

Hello Experts,

 

I have a HTML type variable for a catalog item, which contains a table as below.

Somujit1_0-1743464468737.png

 

The source code does not have any <br> tags.

However, when a email notification is triggered, there are many unwanted spacing/<br> tags getting above this table as below 

Somujit1_2-1743464970374.png 

Somujit1_3-1743465297535.png

 

Not sure why these unwanted spacing is showing in the email. Can you advise and help me with a solution to remove this unwanted spacing.

 

Thanks,

Somujit

 

4 REPLIES 4

Shivalika
Mega Sage

Hello @Somujit1 

 

In email body - it fetches the body as EMAIL BODY as PLAIN HTML - so wherever there will be variations - it will definitely put BR .

 

 

  • The notification body in ServiceNow uses a WYSIWYG editor (What You See Is What You Get) or a source code editor that supports HTML and Jelly scripting.

  • It allows dynamic content using variables (${current.variable_name}), scripts, and email templates.

  • It may include ServiceNow-specific syntax, such as gs.getProperty() or gs.template.print(), which won’t work in raw HTML.

2. Plain HTML Email Body (Standalone)

  • If you extract the email’s HTML source code from an email client, it may contain:

    • Inline CSS

    • Absolute URLs

    • Email-specific formatting (like <style> inside <head>)

 

Kindly mark my answer as helpful and accept solution if it helped you in anyway. This will help me be recognized for the efforts and also move this questions from unsolved to solved bucket. 

 

Regards,

 

Shivalika 

 

My LinkedIn - https://www.linkedin.com/in/shivalika-gupta-540346194

 

My youtube - https://youtube.com/playlist?list=PLsHuNzTdkE5Cn4PyS7HdV0Vg8JsfdgQlA&si=0WynLcOwNeEISQCY*

 

Ankur Bawiskar
Tera Patron
Tera Patron

@Somujit1 

how are you sending the email? via script using eventQueue or directly based on notification?

share the complete details

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

Hi @Ankur Bawiskar ,

The email trigger is based on notification on record insert and has the below email script

 

(function runMailScript(current, template, email, email_action, event) {
   
    var variablesDisplayed = ''; // as the variable set occurs on multiple items, only show a variable once at the beginning

    var emailContent = '<table style="border:none;">';

    var gr = current; // Current record is RITM

    emailContent += '<tr>';
    emailContent += '<td style="border-bottom: 1px solid #999;background-color:#eee;padding:0px;margin:0px;min-width: 120px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">Ref: ' + gr.number  + '</td>';
    emailContent += '<td style="border-bottom: 1px solid #999;background-color:#eee;padding:0px;margin:0px;min-width: 150px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">' + gr.cat_item.getDisplayValue() +  '</td>';
    emailContent += '<td style="border-bottom: 1px solid #999;;background-color:#eee;padding:0px;margin:0px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">' + (gr.price==0 ? '': ' (with an internal cost of $'+ gr.price + ' x ' + gr.quantity + ')') +'</td>';
    emailContent += '</tr>';

    var variables = new GlideRecord('sc_item_option_mtom');
    variables.orderBy('sc_item_option.item_option_new.order');
    variables.query('request_item',gr.sys_id);
    while (variables.next()){
        var variableLabel = variables.sc_item_option.item_option_new.question_text;
        if (variables.sc_item_option.item_option_new == 'd6ad213b1b8974107632fe231d4bcbe1')
            variableLabel= '';//ack label
        if (variables.sc_item_option.item_option_new == '8bd523fd1b887050bb62c91d0d4bcbdc' && variables.sc_item_option.value ==false)
            variableLabel= '';
        if (variables.sc_item_option.item_option_new == '75db556bdb48f8504870be37f49619f5' && variables.sc_item_option.value ==false)
            variableLabel= '';
        var variableValue = gr.variables[variables.sc_item_option.item_option_new.name].getDisplayValue();
        // Check for HTML variable
        var isHtmlType = gr.variables[variables.sc_item_option.item_option_new.type].toString() == '23';
        //labels and formatters don't have a display value and so should be ignored
        variableValue = (variableValue=='undefined' ? '': variableValue.toString());
        //variableValue = variableValue.replace(/(<([^>]+)>)/ig, ''); //Get rid of HTML tags within HTML field type -- new
        //variableValue = variableValue.replace(/<\/?[^>]+(>|$)/g, ''); //Get rid of HTML tags within HTML field type -- new
        variableValue = variableValue.replace(/<br>/g,''); //---------------
        variableValue  = variableValue.replace(/<style>(?:.|\n)*?<\/style>/gm, ' : ');//Get rid of ALL styles
        variableValue  = variableValue.replace(/<!--(?:.|\n)*?-->/gm, ' : ');         //Get rid of ALL comments
        variableValue  = variableValue.replace(/<!(?:.|\n)*?>/gm, ' : ');             //Get rid of ALL special microsoft comments

        variableValue  = variableValue.replace(/(<\/th>\n|<\/th>\r\n|<\/th>\r)(?:.)*?>/gm, ' : ');//switch table info into key : value
        //variableValue  = variableValue.replace(/<(?:.|\n)*?>/gm, '');           //Remove any HTML formatting
        //variableValue  = variableValue.replace(/<(.|\n)*?>/gm, '');             //Remove any HTML formatting
        variableValue  = variableValue.replace(/\w\\:\*(?:.|\n)*?}/gm, '');     //Remove v\:* {behavior:url(#default#VML);}
        variableValue  = variableValue.replace(/\.(?:.|\n)*?}/gm, '');          //Remove .shape {behavior:url(#default#VML);}  
        variableValue  = variableValue.replace(/<!(?:.|\n)*?>/gm, '');          //Remove any special Microsoft HTML comments <!
        variableValue  = variableValue.replace(/&nbsp;/gm, '');                 //Remove any non-blank spaces
        variableValue  = variableValue.replace(/\sbody,table(?:.|\n)*?}/gm, '');//Remove any special Microsoft HTML junk
        variableValue  = variableValue.replace(/\h1,(?:.|\n)*?}/gm, '');        //Remove any special Microsoft HTML junk
        variableValue  = variableValue.replace(/\.container(?:.|\n)*?}/gm, ''); //Remove any special Microsoft HTML junk
        variableValue  = variableValue.replace(/\*{64}/gm, '');                 //Remove ******** from the footer of an email
        variableValue  = variableValue.replace(/Please\sthink([^]*)/gm, '');    //Remove generic disclaimer
        variableValue  = variableValue.replace(/^\r\n|^\r|^\n{1,}$/gm, '');     //Remove double lines
        variableValue  = variableValue.replace(/body,table\str,table td,a,\sspan,table/gm, '');//Remove styles
        variableValue  = variableValue.replace(/<!--(?:.|\n)*?-->/gm, '');      //Remove any Microsoft HTML comments
        if (!isHtmlType) {
            variableValue  = variableValue.replace(/(?:\r\n|\r|\n)/g, '<br />');    //replace line breaks with HTML breaks  
        }
          // only show variable set first time (ignore super branch as used to determine cost center & not relevant to approvers
        if(variablesDisplayed.indexOf(variableLabel +'~' + variableValue)==-1 && variableValue != '' && variableLabel !='Super Branch' && variableValue !='undefined' && variableLabel !=''){
            emailContent += '<tr>';
            emailContent += '<td style="border-bottom: 1px solid #999;padding:0px;margin:0px;font-family: arial, helvetica, sans-serif; font-size: 10pt;"></div>';
            emailContent += '<td style="border-bottom: 1px solid #999;padding:0px;margin:0px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">'    + variableLabel + '</div>';
            emailContent += '<td style="border-bottom: 1px solid #999;padding:0px;margin:0px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">' + variableValue   + '</div>';
            emailContent += '</tr>';
        }
            variablesDisplayed += variableLabel +'~' + variableValue;//don't display duplicates
    }
 
    emailContent += '</table>';
    template.print(emailContent);
   
})(current, template, email, email_action, event);  

@Somujit1 

try to apply this style to that HTML

<style>
    body, table, td {
        margin: 0;
        padding: 0;
        border: 0;
        font-size: 100%;
        font: inherit;
        vertical-align: baseline;
    }
</style>

Inline styles for tag

<td style="border-bottom: 1px solid #999; background-color: #eee; padding: 0px; margin: 0px; min-width: 120px; font-family: arial, helvetica, sans-serif; font-size: 10pt;">

try this script

(function runMailScript(current, template, email, email_action, event) {
    var variablesDisplayed = ''; // as the variable set occurs on multiple items, only show a variable once at the beginning
    var emailContent = '<table style="border:none;">';
    var gr = current; // Current record is RITM

    emailContent += '<tr>';
    emailContent += '<td style="border-bottom: 1px solid #999;background-color:#eee;padding:0px;margin:0px;min-width: 120px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">Ref: ' + gr.number  + '</td>';
    emailContent += '<td style="border-bottom: 1px solid #999;background-color:#eee;padding:0px;margin:0px;min-width: 150px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">' + gr.cat_item.getDisplayValue() +  '</td>';
    emailContent += '<td style="border-bottom: 1px solid #999;;background-color:#eee;padding:0px;margin:0px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">' + (gr.price==0 ? '': ' (with an internal cost of $'+ gr.price + ' x ' + gr.quantity + ')') +'</td>';
    emailContent += '</tr>';

    var variables = new GlideRecord('sc_item_option_mtom');
    variables.orderBy('sc_item_option.item_option_new.order');
    variables.query('request_item',gr.sys_id);
    while (variables.next()){
        var variableLabel = variables.sc_item_option.item_option_new.question_text;
        if (variables.sc_item_option.item_option_new == 'd6ad213b1b8974107632fe231d4bcbe1')
            variableLabel= '';//ack label
        if (variables.sc_item_option.item_option_new == '8bd523fd1b887050bb62c91d0d4bcbdc' && variables.sc_item_option.value ==false)
            variableLabel= '';
        if (variables.sc_item_option.item_option_new == '75db556bdb48f8504870be37f49619f5' && variables.sc_item_option.value ==false)
            variableLabel= '';
        var variableValue = gr.variables[variables.sc_item_option.item_option_new.name].getDisplayValue();
        // Check for HTML variable
        var isHtmlType = gr.variables[variables.sc_item_option.item_option_new.type].toString() == '23';
        //labels and formatters don't have a display value and so should be ignored
        variableValue = (variableValue=='undefined' ? '': variableValue.toString());
        variableValue = variableValue.replace(/<br>/g,''); // Remove <br> tags
        variableValue  = variableValue.replace(/<style>(?:.|\n)*?<\/style>/gm, ' : ');//Get rid of ALL styles
        variableValue  = variableValue.replace(/<!--(?:.|\n)*?-->/gm, ' : ');         //Get rid of ALL comments
        variableValue  = variableValue.replace(/<!(?:.|\n)*?>/gm, ' : ');             //Get rid of ALL special microsoft comments
        variableValue  = variableValue.replace(/(<\/th>\n|<\/th>\r\n|<\/th>\r)(?:.)*?>/gm, ' : ');//switch table info into key : value
        variableValue  = variableValue.replace(/\w\\:\*(?:.|\n)*?}/gm, '');     //Remove v\:* {behavior:url(#default#VML);}
        variableValue  = variableValue.replace(/\.(?:.|\n)*?}/gm, '');          //Remove .shape {behavior:url(#default#VML);}  
        variableValue  = variableValue.replace(/<!(?:.|\n)*?>/gm, '');          //Remove any special Microsoft HTML comments <!
        variableValue  = variableValue.replace(/&nbsp;/gm, '');                 //Remove any non-blank spaces
        variableValue  = variableValue.replace(/\sbody,table(?:.|\n)*?}/gm, '');//Remove any special Microsoft HTML junk
        variableValue  = variableValue.replace(/\h1,(?:.|\n)*?}/gm, '');        //Remove any special Microsoft HTML junk
        variableValue  = variableValue.replace(/\.container(?:.|\n)*?}/gm, ''); //Remove any special Microsoft HTML junk
        variableValue  = variableValue.replace(/\*{64}/gm, '');                 //Remove ******** from the footer of an email
        variableValue  = variableValue.replace(/Please\sthink([^]*)/gm, '');    //Remove generic disclaimer
        variableValue  = variableValue.replace(/^\r\n|^\r|^\n{1,}$/gm, '');     //Remove double lines
        variableValue  = variableValue.replace(/body,table\str,table td,a,\sspan,table/gm, '');//Remove styles
        variableValue  = variableValue.replace(/<!--(?:.|\n)*?-->/gm, '');      //Remove any Microsoft HTML comments
        if (!isHtmlType) {
            variableValue  = variableValue.replace(/(?:\r\n|\r|\n)/g, '<br />');    //replace line breaks with HTML breaks  
        }
        // only show variable set first time (ignore super branch as used to determine cost center & not relevant to approvers
        if(variablesDisplayed.indexOf(variableLabel +'~' + variableValue)==-1 && variableValue != '' && variableLabel !='Super Branch' && variableValue !='undefined' && variableLabel !=''){
            emailContent += '<tr>';
            emailContent += '<td style="border-bottom: 1px solid #999;padding:0px;margin:0px;font-family: arial, helvetica, sans-serif; font-size: 10pt;"></div>';
            emailContent += '<td style="border-bottom: 1px solid #999;padding:0px;margin:0px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">'    + variableLabel + '</div>';
            emailContent += '<td style="border-bottom: 1px solid #999;padding:0px;margin:0px;font-family: arial, helvetica, sans-serif; font-size: 10pt;">' + variableValue   + '</div>';
            emailContent += '</tr>';
        }
        variablesDisplayed += variableLabel +'~' + variableValue;//don't display duplicates
    }
    emailContent += '</table>';
    template.print(emailContent);
})(current, template, email, email_action, event);

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader