Multiline strings in ES6 JavaScript

The new kid in town is called Template Strings. Template Strings are demarked by a backtick(`) on either end and can contain other backticks if they are escaped by a backslash(ie. let my_string = `some cool \`escaped\` thing`). This new kind of primitive in JavaScript is different from string literals in a few important ways.

New features in Template Strings

Firstly, it can contain newline characters(\r and \n) which means that hitting enter in the middle of a string is now valid! This also means that you can write long-form content or even properly indented HTML without needing to use one of a list of hacks.

The other main difference with Template Strings is that you can interpolate data into them using the `${data}` syntax. This means that instead of concatenating together a list of strings with tons of extra + operators and newlines you can insert data directly into a string. The interpolation operator will evaluate arbitrary content so you're not limited to just already-declared variables. You can insert expressions to calculate a value or even instantiate a new instance of a class and render it to a string. Go wild!

If you'd like to process a template string in your own way, Template Strings also come in a 'tagged' variety. With the name of a function directly connected to a Template String, the string is then processed and fed into the function with the first argument being an array of normal strings(the ones separated by interpolated data) and the following arguments being a list of calculated values from interpolated sections of the Template String. For example:

let number = 33  
let food = 'problem'

function process_string (clean_strings, value1, value2) {  
  let new_string = `${clean_strings[0]}${value1}${clean_strings[1]}${value2}`

  return `${new_string}. Doncha know?`
  // creates a string processed slightly differently.
  // Just completely ignores clean_strings[2].
}

process_string`i have ${ number * 3 } ${ food + 's' }.`  
// "I have 99 problems. Doncha know?"

Multiline string hacks in ES5

Previously there were 3 ways to write multiline strings in JavaScript in a legible way: escaping newlines, concatenating strings, and creating an array of strings.

Escaping Newlines

While this technique keeps all your information in one string, the escapes at the end aren't very pretty and unfamiliar developers might mistake them for part of the string itself. Or just a syntax error. It's also worth noting that these are not real newlines because they're being escaped. Presentationally this technique and the two following don't allow for visible newlines in the string.

var my_string = 'Lorem ipsum dolor sit amet, \  
consectetur adipiscing elit, sed do eiusmod tempor \  
incididunt ut labore et dolore magna aliqua. Ut enim\  
 ad minim veniam'

Concatenating Strings

Probably the ugliest of techniques but the easiest to understand, this method requires a lot of extra markup to get the same string. This method tends to violate syntax linters for having trailing spaces at the beginning or end of lines.

var my_string = 'Lorem ipsum dolor sit amet, ' +  
    'consectetur adipiscing elit, sed do eiusmod tempor ' +
    'incididunt ut labore et dolore magna aliqua. Ut enim' +
    ' ad minim veniam'

Creating an Array of Strings

This is also not super pretty and involves some unnecessary markup. It is, however, the easiest to read and conforms easier to syntax formatting standards. Make sure to include an empty string or another separator in your Array#join method call or it will join your strings with the default separator(,) which can cause problems in many circumstances.

var my_string = [  
  'Lorem ipsum dolor sit amet, ',
  'consectetur adipiscing elit, sed do eiusmod tempor ',
  'incididunt ut labore et dolore magna aliqua. Ut enim',
  ' ad minim veniam'
].join('')

Writing multiline strings in ES6 using Template Strings

Here's an example of real HTML content with interpolated data written in ES5 first and ES6 second:

var kevin = {  
  profile_image: 'http://lorempixel.com/300/300',
  name: 'Kevin',
  title: 'Mover, Shaker, Risk Taker'
}

function get_user_widget_markup (user) {  
  return [
    '<div class="user-profile">',
      '<img src="' + user.profile_image + '" alt="" class="user-image">',
      '<h2 class="user-name">',
        user.name,
      '</h2>',
      '<p class="user-title">',
        user.title,
      '</p>',
    '</div>'
  ].join('')
}

get_user_widget_markup(kevin)  

Wow, that's really unnecessarily verbose! How about ES6?

let kevin = {  
  profile_image: 'http://lorempixel.com/300/300',
  name: 'Kevin',
  title: 'Mover, Shaker, Risk Taker'
}

function get_user_widget_markup (user) {  
  return `<div class="user-profile">
    <img src="${user.profile_image}" alt="" class="user-image">
    <h2 class="user-name">${user.name}</h2>
    <p class="user-title">${user.title}</p>
  </div>`
}

get_user_widget_markup(kevin)  

Much better. That's 6 lines and 78 characters shorter(at least in the way that I would normally write in each syntax. Feel free to drop me a note about your favorite JS syntax styles. I love to talk about code style). As you can see, writing multiline content in ES6 is simpler, more concise, and doesn't require hacks or workarounds. Using Template Strings we're capable of using newlines without having to explicitly write out \n. Interpolation is much easier as well, requiring less verbose markup and keeping the data in the middle of the string where it belongs instead of breaking up the string. Having written many A/B tests recently as well as other JavaScript code that requires HTML markup to be in the JavaScript files, multiline string support might be my favorite feature of ES6.