cf.completefrontendCode editorOpen lab
THE JAVASCRIPT FIELD GUIDE

Template literals & tagged templates

Build strings with expressions, preserve line breaks, process templates with tag functions, and keep backslashes with String.raw.

By the end you can
  • 01
    Fill strings with expressionsUse ${} for values, math, function calls, ternaries, and nested templates.
  • 02
    Control text shapePredict when newlines, indentation, escapes, and raw backslashes are preserved.
  • 03
    Write simple tagsReceive template pieces and values separately, then format or escape the values.

Strings that can think before they print

A template literal is a string written with backtick characters instead of quote characters. Backticks unlock three powers: blanks you can fill with expressions, real multi-line text, and a way to send the template through a function before the final string exists.

You already know the basics from the Strings lesson: a backtick string can contain a blank like ${name}. This lesson turns that feature into a reliable tool. We will predict exactly what values become strings, where whitespace comes from, how tags receive their arguments, and why String.raw keeps backslashes untouched.

Real-life analogyA template literal is a fill-in-the-blank form

Imagine a form that says “Hello, ____.” The printed part stays the same; the blank changes for each person. Template literals work the same way, except each blank is real JavaScript that runs before the final string is assembled.

In real life: The printed words on the form
In JavaScript: The literal text between backticks
In real life: Each blank on the form
In JavaScript: One expression inside a placeholder
In real life: The filled-in final document
In JavaScript: The string value JavaScript produces

Where the analogy stops: A paper form usually accepts simple handwriting. A JavaScript placeholder can run any expression: math, function calls, ternaries, or another template.

The tiny definition

A template literal is a backtick-delimited string. A placeholder evaluates the expression inside ${...}, converts the result to a string, and inserts it at that spot.

Backticks clash with this site’s inline-code marker, so longer examples appear in code blocks. When you copy them, copy the backtick characters from the code block exactly.

Interpolation: each blank is an expression

STEP THROUGH

Interpolation means “put a value into a larger piece of text.” In a template literal, JavaScript runs each expression inside ${...} from left to right. The expression can be as small as a variable or as rich as a ternary decision.

Fill the blanks with real expressions
Step 0 of 6Ready
Your turn: follow the blue line

Choose a preset, predict the final sentence, then step through how each ${} blank is evaluated.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
const items = ["tea","cake"];const paid = true;const line = `${name} ordered ${items.length} ${items.length === 1 ? "item" : "items"}: ${items.join(", ")}`;const status = `${line} — ${paid ? "paid" : "needs payment"}`;console.log(status);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
Choose the data for lines 1–3

Changing the data starts a fresh run. Predict line 6 before stepping.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Notice that line 4 does not merely paste variables. It counts an array, chooses singular or plural, and calls join. Template literals are readable because the code sits where the result belongs. That makes them perfect for receipts, labels, logs, and messages.

Objects and arrays are converted tooPop out in the code editor (opens in a new tab)JavaScript
const obj = { name: "Ada" };const custom = { toString() { return "custom object"; } };console.log(`${obj}`);console.log(`${custom}`);console.log(`${["a", "b", "c"]}`);

The placeholder conversion uses the same “string” hint you met in the Object to primitive conversion lesson. A plain object becomes [object Object] unless it customizes toString. An array becomes a comma-joined list. If you want a better result, call the method you mean, such as items.join(", ") or JSON.stringify(data).

Fun fact: templates can nest

A placeholder can contain another template literal. Keep nesting shallow, though. If a string starts looking like a puzzle, build a named variable first and interpolate that name.

Multi-line strings preserve the page shape

STEP THROUGH

Quote-delimited strings can include a newline by writing \n. Template literals can include the real newline itself. That is wonderful for messages, SQL-like text, small snippets, and test fixtures. It also means accidental indentation is real output.

Step through preserved line breaks
Step 0 of 5Ready
Your turn: follow the blue line

Step through a multi-line string and watch why indentation appears in the output.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
  Ship date: Friday    Bring snacks`;const cleaned = messy  .split("\n")  .map((line) => line.trim())  .join("\n");console.log(messy);console.log("---");console.log(cleaned);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

The trim-and-join fix in the experiment is intentionally simple: it removes spaces from both ends of every line. In production you may want a small dedent helper that removes only the shared indentation, so intentional spaces inside the message survive.

Normal strings and template literals both make strings, but whitespace is easier to see in templates.
FeatureNormal quoted stringTemplate literal
DelimiterSingle or double quotesBackticks
InterpolationNo; placeholders print literallyYes, placeholders evaluate expressions
Line breaksUse an escape like newlineReal source newlines are allowed
IndentationOnly what you type in escapes or concatenated piecesEvery space between the backticks is preserved

Tagged templates: send the form through a clerk

INTERACTIVE

A tagged template puts a function name before the template. JavaScript does not build the final string first. Instead it calls the tag function with two kinds of information: the literal string pieces and the evaluated placeholder values.

Real-life analogyA tagged template is a form checked by a clerk

The form is not final until the clerk reviews it. The clerk can mark important values, format money, translate text, or escape risky user input before handing back a result.

In real life: The clerk sees the printed form
In JavaScript: The strings array
In real life: The clerk sees the filled-in blanks
In JavaScript: The rest values
In real life: The clerk stamps or rewrites the document
In JavaScript: The tag returns any value it wants

Where the analogy stops: A real clerk usually returns a document. A tag can return any JavaScript value, although strings are the common case.

A tag is a normal function call with special argumentsPop out in the code editor (opens in a new tab)JavaScript
function highlight(strings, ...values) {  console.log(strings.length);  console.log(values.length);  console.log(strings.raw[0]);  return strings.reduce((text, part, index) => text + part + (index < values.length ? "[" + values[index] + "]" : ""), "");}const price = 12;const qty = 3;console.log(highlight`Total: ${price} for ${qty} items`);
What a tag receives
Step 0 of 7Ready
Your turn: follow the blue line

A tag is just a function call with special arguments. Step through the call shape.

Running in
  1. script
Next: line 9
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
function highlight(strings, ...values) {  console.log(strings.length);  console.log(values.length);  console.log(strings.raw[0]);  return strings.reduce((text, part, index) => text + part + (index < values.length ? "[" + values[index] + "]" : ""), "");}const price = 12;const qty = 3;
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

The important rule is precise: for n placeholders, the tag receives n + 1 string pieces. There is a piece before the first placeholder, between each pair, and after the last one. Empty pieces still count.

Tagged template clerk
Tag functionsPop out in the code editor (opens in a new tab)JavaScript
function highlight(strings, ...values) {  return strings.reduce((text, part, index) =>    text + part + (index < values.length ? "[" + values[index] + "]" : ""), "");}function currency(strings, ...values) {  return strings.reduce((text, part, index) => {    const value = values[index];    const money = typeof value === "number" ? "₹" + value.toFixed(2) : String(value ?? "");    return text + part + (index < values.length ? money : "");  }, "");}function safeHtml(strings, ...values) {  return strings.reduce((text, part, index) =>    text + part + (index < values.length ? escapeHtmlValue(values[index]) : ""), "");}
What the clerk receivesHighlight values
strings["Total: "," for "," items"]
values[12,3]
strings.length3
values.length2
returned stringRun the tag
Try it yourself

Pick a tag, read the code, then run it. The previews show what the tag receives before it joins anything.

The simple HTML escaping example escapes values only. The deeper security lesson later is XSS & safe DOM updates.

The HTML-escaping example is deliberately small: it escapes only interpolated values, replacing &, <, >, double quotes, and apostrophes. The fixed string pieces are code you wrote. User input belongs in values. The deeper lesson XSS & safe DOM updates will cover the security model in more detail.

String.raw: keep every backslash as typed

STEP THROUGH

Template strings are normally cooked: escape sequences like \n and \t become a newline and a tab. String.raw is a built-in tag that reads the raw template pieces instead. Think of it as a photocopy that preserves every backslash.

Cooked escapes vs raw backslashes
Step 0 of 5Ready
Your turn: follow the blue line

Compare a normal template with String.raw. The source looks similar, but the string values are different.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
const raw = String.raw`C:\new\table`;console.log(normal);console.log(raw);console.log(String.raw`\d+\sitems`);
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Use String.raw when the source text itself contains many backslashes: Windows paths, regular-expression sources, and examples where you want learners to see the exact escape sequence. One caveat: a JavaScript template literal cannot end with a single unescaped backslash before the closing backtick, because that backslash would try to escape the backtick.

Raw does not mean unsafe or unprocessed forever

String.raw only affects how escape sequences in the literal pieces are read. Placeholder values are still evaluated and converted normally.

Where you’ll use this

PRACTICAL

Template literals show up anywhere a program has to explain itself to a person: UI labels, analytics logs, errors, receipts, generated file paths, and test data. Tags are less common, but powerful when a team wants one consistent rule for a whole family of strings.

Practical patternsPop out in the code editor (opens in a new tab)JavaScript
const user = "Ada";const unread = 4;const label = `${user} has ${unread} unread messages`; const lines = ["first", "second"];const report = `Report:${lines.join("\n")}`; const folder = "invoices";const filename = "april.csv";const path = String.raw`C:\exports\${folder}\${filename}`; const unsafeName = "<Ada>";const html = safeHtml`<strong>${unsafeName}</strong>`;
Normal string or template tool?
  • `Hello ${name}`
  • "Hello ${name}"
  • highlight`Total: ${price}`
  • String.raw`C:\new\table`
  • `first line second line`
  • 'Total: ${price}'
  • html`<p>${comment}</p>`
  • String.raw`\d+\sitems`
Try it yourself
0 of 8 correct

Sort each card by the kind of string feature it uses.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Common mistakes

WATCH FOR
  • “Quotes interpolate too.” They do not. The string "Hello ${name}" prints the dollar sign, braces, and name literally.
  • “The braces are optional.” The dollar sign and both braces make the placeholder. $name is just text.
  • “Objects print like the console preview.” String conversion is not inspection. Plain objects become [object Object] unless customized.
  • “Tags receive one finished string.” Tags receive the literal pieces and values separately. That separation is their power.
  • “String.raw makes everything raw.” It preserves raw literal pieces, but placeholder expressions still run normally.
Three mistakes to spotPop out in the code editor (opens in a new tab)JavaScript
const name = "Ada";console.log("Hello ${name}"); const item = { title: "Tea" };console.log(`Item: ${item}`); const folder = "new";console.log(`C:${folder}	able`);

Practice exercises

5 EXERCISES
Exercise 1 · Warm-upBuild a receipt line

Predict the exact line printed by this receipt program.

Starter codePop out in the code editor (opens in a new tab)JavaScript
const item = "Notebook";
const qty = 3;
const price = 4;
console.log(`${qty} × ${item}: ₹${qty * price}`);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · Warm-upFix the quoted greeting

    Change the greeting so it prints the person’s actual name.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    const name = "Mina";
    console.log("Hello ${name}");

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeUppercase only the interpolated values

      Write or read a tag that uppercases the values but keeps the string pieces unchanged.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      function upperValues(strings, ...values) {
        return strings.reduce((text, part, index) => text + part + (index < values.length ? String(values[index]).toUpperCase() : ""), "");
      }
      console.log(upperValues`Hello ${"ada"}, status: ${"ready"}`);

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · ChallengeEscape a user comment

        Use a tag to protect a simple HTML string from a dangerous value.

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        function escapeValue(value) {
          return String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
        }
        function html(strings, ...values) {
          return strings.reduce((text, part, index) => text + part + (index < values.length ? escapeValue(values[index]) : ""), "");
        }
        const comment = "<img src=x onerror='alert(1)'>";
        console.log(html`<p>${comment}</p>`);

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · PracticeKeep a Windows path raw

          Print the file path without turning parts of it into a newline or tab.

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          console.log(String.raw`C:\new\table\report.txt`);

          Answer, then press Check. Spacing and letter case don’t matter.

            Check your understanding

            7 QUESTIONS
            Template literals quiz · 7 questionsScore: first tries count
            1. Question 1 of 7What does a backtick greeting print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const name = "Ada";
              console.log(`Hello ${name}`);

              Choose an answer to see the explanation.

            2. Question 2 of 7What does a quoted greeting print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log("Hello ${name}");

              Choose an answer to see the explanation.

            3. Question 3 of 7What does an interpolated plain object print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const item = { name: "Tea" };
              console.log(`${item}`);

              Choose an answer to see the explanation.

            4. Question 4 of 7How many string pieces does the tag receive?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              function tag(strings, ...values) {
                console.log(strings.length);
                console.log(values.length);
              }
              tag`A ${1} B ${2} C`;

              Choose an answer to see the explanation.

            5. Question 5 of 7What does this print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log(String.raw`C:\new\table`);

              Choose an answer to see the explanation.

            6. Question 6 of 7Which value should a safe HTML tag escape?

              Choose an answer to see the explanation.

            7. Question 7 of 7What is preserved by a multi-line template literal?

              Choose an answer to see the explanation.

            Key takeaways

            • Backticks create template literals; quotes create normal strings.
            • Each placeholder evaluates a real expression, then string conversion inserts the result.
            • Real newlines and indentation inside template literals are part of the string.
            • Tagged templates call a function with string pieces and values before joining.
            • String.raw keeps escape backslashes in literal pieces.

            A template literal is a string form whose blanks can run JavaScript before the final text is produced.

            Up next: Unicode & string internals.

            CompleteFrontend Clear concepts. Working examples.