DocsHub
Strings

Template Literals

Learn how to write cleaner, more powerful strings using template literals in JavaScript.

Template Literals

Before ES6, building strings with dynamic values meant concatenating pieces together with +:

const name = "Ali";
const age = 22;
const city = "Lahore";

const message = "My name is " + name + ", I am " + age + " years old and I live in " + city + ".";

It works — but it is messy, hard to read, and easy to get wrong. One missing space or extra + and the output is wrong.

Template literals solve this completely. They let you embed expressions directly inside a string — no concatenation needed.

const message = `My name is ${name}, I am ${age} years old and I live in ${city}.`;

Same result. Much cleaner. Template literals use backticks `` instead of quotes, and ${} to embed any expression.


Basic Syntax

const result = `text ${expression} more text`;

Anything inside ${} is evaluated as JavaScript — variables, operations, function calls, ternary operators — the result is converted to a string and inserted.

const name = "Ali";
const score = 88;

console.log(`Hello, ${name}!`);                    // Hello, Ali!
console.log(`Your score is ${score}/100.`);        // Your score is 88/100.
console.log(`Double your score: ${score * 2}`);   // Double your score: 176
console.log(`Pass or fail: ${score >= 50 ? "Pass" : "Fail"}`); // Pass or fail: Pass

Expressions Inside ${}

You are not limited to just variables. Any valid JavaScript expression works inside ${}.

Math

const price = 1200;
const quantity = 3;
const tax = 0.17;

console.log(`Subtotal: Rs. ${price * quantity}`);
// Subtotal: Rs. 3600

console.log(`Tax: Rs. ${(price * quantity * tax).toFixed(2)}`);
// Tax: Rs. 612.00

console.log(`Total: Rs. ${(price * quantity * (1 + tax)).toFixed(2)}`);
// Total: Rs. 4212.00

Function calls

function capitalize(str) {
  return str[0].toUpperCase() + str.slice(1);
}

const name = "ali";
console.log(`Welcome, ${capitalize(name)}!`); // Welcome, Ali!

Ternary operator

const hour = 14;
const greeting = `Good ${hour < 12 ? "morning" : hour < 17 ? "afternoon" : "evening"}!`;
console.log(greeting); // Good afternoon!

Array and object access

const user = { name: "Ali", scores: [88, 92, 76] };

console.log(`Name: ${user.name}`);
// Name: Ali

console.log(`Top score: ${Math.max(...user.scores)}`);
// Top score: 92

Multi-line Strings

Template literals preserve line breaks naturally. No need for \n or concatenation.

// Old way — ugly
const old = "Line one\n" +
            "Line two\n" +
            "Line three";

// Template literal — clean
const modern = `Line one
Line two
Line three`;

console.log(modern);
// Line one
// Line two
// Line three

Real use — building HTML strings:

const user = { name: "Ali", role: "Admin", city: "Lahore" };

const card = `
  <div class="user-card">
    <h2>${user.name}</h2>
    <p>Role: ${user.role}</p>
    <p>City: ${user.city}</p>
  </div>
`;

console.log(card);

Multi-line template literals are perfect for HTML snippets, SQL queries, email bodies, or any block of text that spans multiple lines.


Nesting Template Literals

You can nest template literals inside ${} when needed.

const items = ["Laptop", "Mouse", "Keyboard"];

const list = `
  Items:
  ${items.map((item, i) => `  ${i + 1}. ${item}`).join("\n")}
`;

console.log(list);
//   Items:
//   1. Laptop
//   2. Mouse
//   3. Keyboard

The inner template literal inside map() builds each list item. The outer one wraps everything together. Powerful but keep it readable — if nesting gets too deep, extract the inner part into a variable or function.


Building Dynamic Content

Template literals shine when building content from data.

const students = [
  { name: "Ali",  score: 88, passed: true },
  { name: "Sara", score: 45, passed: false },
  { name: "Zara", score: 92, passed: true },
];

const report = `
Student Report
==============
${students.map(s => `${s.name.padEnd(10)} ${s.score}/100  ${s.passed ? "✓ Pass" : "✗ Fail"}`).join("\n")}
==============
Total students : ${students.length}
Passing        : ${students.filter(s => s.passed).length}
Average score  : ${(students.reduce((sum, s) => sum + s.score, 0) / students.length).toFixed(1)}
`;

console.log(report);

// Student Report
// ==============
// Ali        88/100  ✓ Pass
// Sara       45/100  ✗ Fail
// Zara       92/100  ✓ Pass
// ==============
// Total students : 3
// Passing        : 2
// Average score  : 75.0

Tagged Template Literals

This is an advanced feature — template literals can be processed by a function called a tag. You place the function name directly before the backtick.

function tag(strings, ...values) {
  console.log(strings); // array of string parts
  console.log(values);  // array of expression values
}

const name = "Ali";
const score = 88;

tag`Hello ${name}, your score is ${score}.`;
// strings: ["Hello ", ", your score is ", "."]
// values:  ["Ali", 88]

The tag function receives the static string parts and the dynamic values separately — giving you full control over how the final string is built.

Real use — safe HTML escaping

function escapeHTML(strings, ...values) {
  return strings.reduce((result, str, i) => {
    const value = values[i - 1];
    const escaped = String(value)
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;");
    return result + escaped + str;
  });
}

const userInput = '<script>alert("hacked!")</script>';
const safe = escapeHTML`<p>User said: ${userInput}</p>`;

console.log(safe);
// <p>User said: &lt;script&gt;alert(&quot;hacked!&quot;)&lt;/script&gt;</p>

The dangerous characters are escaped before being inserted into the string. This is how libraries like lit-html and styled-components work under the hood.

Tagged template literals are an advanced feature used mainly in libraries. You will not write them often yourself — but knowing they exist helps you understand how popular tools like styled-components, graphql-tag, and sql libraries work.


Template Literals vs String Concatenation

const name = "Ali";
const age = 22;
const city = "Lahore";

// Concatenation — hard to read, error-prone
const msg1 = "Hi, I am " + name + ". I am " + age + " years old. I live in " + city + ".";

// Template literal — clean and readable
const msg2 = `Hi, I am ${name}. I am ${age} years old. I live in ${city}.`;
Concatenation +Template Literals
ReadabilityHard with many variablesClean and natural
Multi-lineNeeds \nNatural line breaks
ExpressionsNeed to break out of stringInline with ${}
Modern JavaScriptOld pattern✅ Use this

Always use template literals in modern JavaScript. Concatenation with + is only in old code.


A Real Example — Email Generator

function generateWelcomeEmail({ name, username, plan = "Free" }) {
  return `
Subject: Welcome to DocsHub, ${name}!

Hi ${name},

Your account has been created successfully.

  Username : ${username}
  Plan     : ${plan}
  Joined   : ${new Date().toDateString()}

${plan === "Free"
  ? `You are on the Free plan. Upgrade anytime to unlock all features.`
  : `You are on the ${plan} plan. Enjoy full access to all content.`
}

If you have any questions, reply to this email.

The DocsHub Team
  `.trim();
}

console.log(generateWelcomeEmail({
  name: "Ali Hassan",
  username: "ali_dev",
  plan: "Pro"
}));

// Subject: Welcome to DocsHub, Ali Hassan!
//
// Hi Ali Hassan,
//
// Your account has been created successfully.
//
//   Username : ali_dev
//   Plan     : Pro
//   Joined   : Mon Mar 18 2024
//
// You are on the Pro plan. Enjoy full access to all content.
//
// If you have any questions, reply to this email.
//
// The DocsHub Team

Summary

  • Template literals use backticks `` instead of quotes
  • Embed any JavaScript expression with ${expression}
  • Support multi-line strings naturally — no \n needed
  • Expressions inside ${} can be variables, math, function calls, ternary operators — anything that returns a value
  • Tagged template literals let a function process the string — used in libraries for safe HTML, CSS-in-JS, and SQL
  • Always prefer template literals over string concatenation with +

On this page