W3cubDocs

/JavaScript

Template literals

Template literals are string literals allowing embedded expressions. You can use multi-line strings and string interpolation features with them. They were called "template strings" in prior editions of the ES2015 specification.

Syntax

`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag `string text ${expression} string text`

Description

Template literals are enclosed by the back-tick (` `) (grave accent) character instead of double or single quotes. Template literals can contain placeholders. These are indicated by the dollar sign and curly braces (${expression}). The expressions in the placeholders and the text between them get passed to a function. The default function just concatenates the parts into a single string. If there is an expression preceding the template literal (tag here), the template string is called "tagged template literal". In that case, the tag expression (usually a function) gets called with the processed template literal, which you can then manipulate before outputting. To escape a back-tick in a template literal, put a backslash \ before the back-tick.

`\`` === '`' // --> true

Multi-line strings

Any newline characters inserted in the source are part of the template literal. Using normal strings, you would have to use the following syntax in order to get multi-line strings:

console.log('string text line 1\n' +
'string text line 2');
// "string text line 1
// string text line 2"

To get the same effect using template literals, you can now write:

console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"

Expression interpolation

In order to embed expressions within normal strings, you would use the following syntax:

var a = 5;
var b = 10;
console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
// "Fifteen is 15 and
// not 20."

Now, with template literals, you are able to make use of the syntactic sugar making substitutions like this more readable:

var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."

Nesting templates

In certain times, nesting a template is the easiest and perhaps more readable way to have configurable strings. Within a backticked template it is simple to allow inner backticks simply by using them inside a placeholder ${ } within the template. For instance, if condition a is true: then return this templated literal.

In ES5:

var classes = 'header'
classes += (isLargeScreen() ?
   '' : item.isCollapsed ?
     ' icon-expander' : ' icon-collapser');

In ES2015 with template literals and without nesting:

const classes = `header ${ isLargeScreen() ? '' :
    (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;

In ES2015 with nested template literals:

const classes = `header ${ isLargeScreen() ? '' :
 `icon-${(item.isCollapsed ? 'expander' : 'collapser')}`}`; //note the parens

Tagged template literals

A more advanced form of template literals are tagged template literals. Tags allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions. In the end, your function can return your manipulated string (or it can return something completely different as described in the next example). The name of the function used for the tag can be named whatever you want.

var person = 'Mike';
var age = 28;

function myTag(strings, personExp, ageExp) {

  var str0 = strings[0]; // "that "
  var str1 = strings[1]; // " is a "

  // There is technically a string after
  // the final expression (in our example),
  // but it is empty (""), so disregard.
  // var str2 = strings[2];

  var ageStr;
  if (ageExp > 99){
    ageStr = 'centenarian';
  } else {
    ageStr = 'youngster';
  }

  return str0 + personExp + str1 + ageStr;

}

var output = myTag`that ${ person } is a ${ age }`;

console.log(output);
// that Mike is a youngster

Tag functions don't need to return a string, as shown in the following example.

function template(strings, ...keys) {
  return (function(...values) {
    var dict = values[values.length - 1] || {};
    var result = [strings[0]];
    keys.forEach(function(key, i) {
      var value = Number.isInteger(key) ? values[key] : dict[key];
      result.push(value, strings[i + 1]);
    });
    return result.join('');
  });
}

var t1Closure = template`${0}${1}${0}!`;
t1Closure('Y', 'A');  // "YAY!"
var t2Closure = template`${0} ${'foo'}!`;
t2Closure('Hello', {foo: 'World'});  // "Hello World!"

Raw strings

The special raw property, available on the first function argument of tagged template literals, allows you to access the raw strings as they were entered, without processing escape sequences.

function tag(strings) {
  console.log(strings.raw[0]);
}

tag`string text line 1 \n string text line 2`;
// logs "string text line 1 \n string text line 2" ,
// including the two characters '\' and 'n'

In addition, the String.raw() method exists to create raw strings just like the default template function and string concatenation would create.

var str = String.raw`Hi\n${2+3}!`;
// "Hi\n5!"

str.length;
// 6

str.split('').join(',');
// "H,i,\,n,5,!"

Tagged template literals and escape sequences

As of ES2016, tagged template literals conform to the rules of the following escape sequences:

  • Unicode escapes started by "\u", for example \u00A9
  • Unicode code point escapes indicated by "\u{}", for example \u{2F804}
  • Hexadecimal escapes started by "\x", for example \xA9
  • Octal literal escapes started by "\" and (a) digit(s), for example \251

This means that a tagged template like the following is problematic, because, per ECMAScript grammar, a parser looks for valid Unicode escape sequences, but finds malformed syntax:

latex`\unicode`
// Throws in older ECMAScript versions (ES2016 and earlier)
// SyntaxError: malformed Unicode character escape sequence

Tagged template literals should allow the embedding of languages (for example DSLs, or LaTeX), where other escapes sequences are common. The ECMAScript proposal Template Literal Revision (stage 4, to be integrated in the ECMAScript 2018 standard) removes the syntax restriction of ECMAScript escape sequences from tagged template literals.

However, illegal escape sequence must still be represented in the "cooked" representation. They will show up as undefined element in the "cooked" array:

function latex(str) { 
 return { "cooked": str[0], "raw": str.raw[0] }
} 

latex`\unicode`

// { cooked: undefined, raw: "\\unicode" }

Note that the escape sequence restriction is only dropped from tagged template literals and not from untagged template literals:

let bad = `bad escape sequence: \unicode`;

Specifications

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Template Literals' in that specification.
Standard Initial definition. Defined in several section of the specification: Template Literals, Tagged Templates
ECMAScript Latest Draft (ECMA-262)
The definition of 'Template Literals' in that specification.
Living Standard Defined in several section of the specification: Template Literals, Tagged Templates
Template Literal Revision Stage 4 draft Drops escape sequence restriction from tagged template literals

Browser compatibility

Feature Chrome Edge Firefox Internet Explorer Opera Safari
Basic support 41 12 34 No 28 9
Escape sequences allowed in tagged template literals No No 53 No No No
Feature Android webview Chrome for Android Edge mobile Firefox for Android IE mobile Opera Android iOS Safari
Basic support 41 41 12 34 No 28 ?
Escape sequences allowed in tagged template literals No No No 53 No No No

See also

© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals