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: PassExpressions 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.00Function 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: 92Multi-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 threeReal 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. KeyboardThe 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.0Tagged 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, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
return result + escaped + str;
});
}
const userInput = '<script>alert("hacked!")</script>';
const safe = escapeHTML`<p>User said: ${userInput}</p>`;
console.log(safe);
// <p>User said: <script>alert("hacked!")</script></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 | |
|---|---|---|
| Readability | Hard with many variables | Clean and natural |
| Multi-line | Needs \n | Natural line breaks |
| Expressions | Need to break out of string | Inline with ${} |
| Modern JavaScript | Old 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 TeamSummary
- Template literals use backticks
``instead of quotes - Embed any JavaScript expression with
${expression} - Support multi-line strings naturally — no
\nneeded - 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
+