Categories
heredoc javascript multiline string

Creating multiline strings in JavaScript

3222

I have the following code in Ruby. I want to convert this code into JavaScript. What is the equivalent code in JS?

text = <<"HERE"
This
Is
A
Multiline
String
HERE

0

    4199

    Update:

    ECMAScript 6 (ES6) introduces a new type of literal, namely template literals. They have many features, variable interpolation among others, but most importantly for this question, they can be multiline.

    A template literal is delimited by backticks:

    var html = `
      <div>
        <span>Some HTML here</span>
      </div>
    `;
    

    (Note: I’m not advocating to use HTML in strings)

    Browser support is OK, but you can use transpilers to be more compatible.


    Original ES5 answer:

    Javascript doesn’t have a here-document syntax. You can escape the literal newline, however, which comes close:

    "foo \
    bar"
    

    24

    • 271

      Be warned: some browsers will insert newlines at the continuance, some will not.

      – staticsan

      Apr 30, 2009 at 2:22

    • 43

      Visual Studio 2010 seems to be confused by this syntax as well.

      – jcollum

      Apr 17, 2011 at 21:58

    • 57

      @Nate It is specified in ECMA-262 5th Edition section 7.8.4 and called LineContinuation : “A line terminator character cannot appear in a string literal, except as part of a LineContinuation to produce the empty character sequence. The correct way to cause a line terminator character to be part of the String value of a string literal is to use an escape sequence such as \n or \u000A.”

      – some

      Sep 25, 2012 at 2:28

    • 22

      I don’t see why you’d do this when browsers treat it inconsistently. “line1\n” + “line2” across multiple lines is readable enough and you’re guaranteed consistent behavior.

      Mar 20, 2013 at 20:14

    • 20

      “Browser support is OK”… not supported by IE11 – not OK

      May 25, 2017 at 5:18

    1493

    ES6 Update:

    As the first answer mentions, with ES6/Babel, you can now create multi-line strings simply by using backticks:

    const htmlString = `Say hello to 
    multi-line
    strings!`;
    

    Interpolating variables is a popular new feature that comes with back-tick delimited strings:

    const htmlString = `${user.name} liked your post about strings`;
    

    This just transpiles down to concatenation:

    user.name + ' liked your post about strings'
    

    Original ES5 answer:

    Google’s JavaScript style guide recommends to use string concatenation instead of escaping newlines:

    Do not do this:

    var myString = 'A rather long string of English text, an error message \
                    actually that just keeps going and going -- an error \
                    message to make the Energizer bunny blush (right through \
                    those Schwarzenegger shades)! Where was I? Oh yes, \
                    you\'ve got an error and all the extraneous whitespace is \
                    just gravy.  Have a nice day.';
    

    The whitespace at the beginning of each line can’t be safely stripped at compile time; whitespace after the slash will result in tricky errors; and while most script engines support this, it is not part of ECMAScript.

    Use string concatenation instead:

    var myString = 'A rather long string of English text, an error message ' +
                   'actually that just keeps going and going -- an error ' +
                   'message to make the Energizer bunny blush (right through ' +
                   'those Schwarzenegger shades)! Where was I? Oh yes, ' +
                   'you\'ve got an error and all the extraneous whitespace is ' +
                   'just gravy.  Have a nice day.';
    

    11

    • 25

      I don’t understand Google’s recommendation. All browsers except extremely old ones support the backslash followed by newline approach, and will continue to do so in the future for backward compatibility. The only time you’d need to avoid it is if you needed to be sure that one and only one newline (or no newline) was added at the end of each line (see also my comment on the accepted answer).

      Feb 26, 2013 at 18:40

    • 8

      Note that template strings aren’t supported in IE11, Firefox 31, Chrome 35, or Safari 7. See kangax.github.io/compat-table/es6

      – EricP

      May 24, 2014 at 2:41

    • 43

      @MattBrowne Google’s recommendation is already documented by them, in order of importance of reasons: (1) The whitespace at the beginning of each line [in the example, you don’t want that whitespace in your string but it looks nicer in the code] (2) whitespace after the slash will result in tricky errors [if you end a line with \ instead of `\` it’s hard to notice] and (3) while most script engines support this, it is not part of ECMAScript [i.e. why use nonstandard features?] Remember it’s a style guide, which is about making code easy to read+maintain+debug: not just “it works” correct.

      Jul 31, 2016 at 20:29


    • 2

      amazing that after all these years string concatenation is still the best/safest/most compliant way to go with this. template literals (above answer) don’t work in IE and escaping lines is just a mess that you’re soon going to regret

      Nov 11, 2016 at 12:31

    • 2

      Found out the hard way that older versions of Android do not support the backticks so if you have an Android app using the webView your backticks cause your app to not run!

      Jun 26, 2019 at 19:45

    729

    the pattern text = <<"HERE" This Is A Multiline String HERE is not available in js (I remember using it much in my good old Perl days).

    To keep oversight with complex or long multiline strings I sometimes use an array pattern:

    var myString = 
       ['<div id="someId">',
        'some content<br />',
        '<a href="#someRef">someRefTxt</a>',
        '</div>'
       ].join('\n');
    

    or the pattern anonymous already showed (escape newline), which can be an ugly block in your code:

        var myString = 
           '<div id="someId"> \
    some content<br /> \
    <a href="#someRef">someRefTxt</a> \
    </div>';
    

    Here’s another weird but working ‘trick’1:

    var myString = (function () {/*
       <div id="someId">
         some content<br />
         <a href="#someRef">someRefTxt</a>
        </div>        
    */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];
    

    external edit: jsfiddle

    ES20xx supports spanning strings over multiple lines using template strings:

    let str = `This is a text
        with multiple lines.
        Escapes are interpreted,
        \n is a newline.`;
    let str = String.raw`This is a text
        with multiple lines.
        Escapes are not interpreted,
        \n is not a newline.`;
    

    1 Note: this will be lost after minifying/obfuscating your code

    33

    • 38

      Please don’t use the array pattern. It will be slower than plain-old string concatenation in most cases.

      – BMiner

      Jul 17, 2011 at 12:39

    • 86

      The array pattern is more readable and the performance loss for an application is often negligible. As that perf test shows, even IE7 can do tens of thousands of operations per second.

      Aug 20, 2011 at 8:16

    • 23

      +1 for an elegant alternative that not only works the same way in all browsers, but is also future-proof.

      – Pavel

      May 21, 2012 at 6:06

    • 28

      @KooiInc Your tests start with the array already created, that skews the results. If you add the initialization of the array, straight concatenation is faster jsperf.com/string-concat-without-sringbuilder/7 See stackoverflow.com/questions/51185/… As a trick for newlines, it may be OK, but it’s definitely doing more work than it should

      Aug 4, 2013 at 8:02


    • 12

      @BMiner: 1) “Premature optimization is the root of all evil” – Donald Knuth, and 2) ‘readability’ is in the eye of the beholder

      – user2418182

      Mar 25, 2014 at 15:27