Template literals are introduced in ES6 and provide a modern way to work with strings in JavaScript. You can use multi-line strings, tagged templates, and variable interpolation features with them.

Before ES6, we used to use single quotes (') or double quotes (") to wrap a string.

In contrast, template literals are enclosed by the backtick (`) character, as shown in the following example:

let str = `JavaScript Basics`

The backticks wrapping provides us several advantages over a regular string built with quotes.

  1. A template literal can span over multiple lines. This allows us to create multi-line strings.
  2. We can use variables and expressions to dynamically substitute parts of the string with the values of variables. This feature is also known as string interpolation.
  3. A template literal can contain HTML tags without escaping. You can even use single and double quotes in a template literal.
  4. The syntax is simple and clean as compared to strings.

Basic syntax

To declare a string with template literal, use backticks (`) instead of single or double quotes:

let str = `JavaScript Strings`

console.log(str)        // JavaScript Strings
console.log(str.length) // 18
console.log(typeof str) // string

You can also use single and double quotes in a template literal without escaping:

let str = `What's up?`

To escape a backtick in a template literal, use a backslash (\) before the backtick:

let str = `A backtick (\`) can appear in a template literal`

Multi-line strings

Before ES6, if we wanted to create a multi-line string, we had to use the \n or newline character:

let str = 'This is an example \n\
of multi-line string.'

console.log(str)
// This is an example
// of multi-line string.

Template literals make it easier to declare a multi-line string. All you need to do is press enter to insert a new line character whenever you want:

let str = `This is a
an example
of multi-line string.`

console.log(str)
// This is a
// an example
// of multi-line string.

Any newline character inserted in the text is considered part of the template literal. This also applies to whitespace characters.

Therefore, you can make sure that the text is formatted with proper indentation. For example, the following template literal:

let str = `First part
            Second part`

will produce a string like the below:

First part
            Second part

Expression interpolation

The most significant benefit of template literals over a regular string is the ability to embed variables and expressions to substitute parts of a string.

The JavaScript engine will automatically replace all variables and expressions with their respective values. This is also known as string interpolation.

You use the ${...} syntax to embed variables and expressions in a template literal:

const name = `Atta`

console.log(`Hey! I'm ${name}!`)
// Hey! I'm Atta!

You can put any expressions inside the ${...}:

const price = 22.99
const discount = 4.55

let total = `The total price is $${(price - discount).toFixed(2)}`

console.log(total)
// The total price is $18.44

Here is another example that demonstrates how you can use template literal expressions in an object method:

const person = {
  firstName: `John`,
  lastName: `Doe`,
  fullName: function () {
    return `${this.firstName} ${this.lastName}`
  }
}

person.fullName() // John Doe

HTML templates

With the ability to create multi-line strings and dynamically substitute parts of a string with variables and expressions, template literals make it easy to use HTML templates in JavaScript.

Let us say that we get some data from an API that looks like the below:

const person = {
  id: 1,
  firstName: 'John',
  lastName: 'Doe',
  email: 'john.doe@example.com'
}

The following example code returns an HTML template for the above person object:

const createPersonMarkup = data => {
  return `
      <div class="card" id="${data.id}">
          <div class="card-body">
              <h3 class="card-title">${data.firstName} ${data.lastName}</h3>
              <p class="text-muted">${data.email}</p>
          </div>
      </div>
  `
}

The above function will return the following HTML markup for the person object we declared before:

<div class="card" id="1">
    <div class="card-body">
        <h3 class="card-title">John Doe</h3>
        <p class="text-muted">john.doe@example.com</p>
    </div>
</div>

Nesting templates

Within a backticked template, it is allowed to have inner backticks by using them inside a placeholder ${}:

const classes = `navbar ${isMenu() ? `navbar-${data.isDark() ? `dark` : `light`}` : ``}`

Tagged templates

Tagged templates are an advanced form of template literals frequently used by modern JavaScript libraries and frameworks.

A template tag allows you to parse template literals with a function and returns the result string.

To create a template tag, you have to place the tag at the start of the template before the backtick (`) character as follows:

const msg = greeting`Hey`

In the above example, greeting is the template tag that applies to the Hey template literal. Here is what the greeting function looks like:

const greeting = (literals, ...expressions) => {
  console.log({ literals, expressions })
}

const msg = greeting`Hey`
// { literals: [ 'Hey' ], expressions: [] }

In the greeting function:

  • The literals parameter is an array that contains the literal string values.
  • The expressions parameter contains the subsequent arguments related to each expression.

Inside the tag function, you can carry whatever transformation you want on these arguments and return the manipulated string:

const product = `Milk`
const price = 2.99
const quantity = 5

const format = (literals, ...expressions) => {
  let message = ''

  for (let i = 0; i < expressions.length; i++) {
    message += literals[i]
    message += expressions[i]
  }

  message += literals[literals.length - 1]
  return message
}

const msg = format`${quantity} ltr ${product} costs $${(quantity * price).toFixed(2)}.`

console.log(msg)
// 5 ltr Milk costs $14.95.

Raw strings

The tag function also provides a special raw property that returns the raw strings as they were entered.

It is available on the literals parameter:

const format = (literals, ...expressions) => {
  console.log(literals.raw)
  // [ '', ' ltr ', ' costs $', '.' ]
}

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.