Welcome back! ๐ In the previous lesson, you learned all about string methods. Now let's explore one of the most beloved ES6 features โ Template Literals!
Before ES6, building dynamic strings in JavaScript was clunky and error-prone โ full of + operators, escaped quotes, and broken multi-line strings. Template literals changed everything. They give you a clean, powerful, and readable way to work with strings.
You'll use template literals in every single JavaScript project you ever write. Let's master them completely!
What are Template Literals?
Template literals are strings wrapped in backticks (`) instead of single or double quotes. They allow you to:
- Embed variables and expressions directly inside strings
- Write multi-line strings naturally
- Build complex dynamic strings without messy concatenation
// Old way โ messy
let name = "Mihir";
let greeting = "Hello, " + name + "! Welcome back.";
// Template literal โ clean โ
let greeting = `Hello, ${name}! Welcome back.`;
console.log(greeting); // Hello, Mihir! Welcome back.Syntax
`string text ${expression} string text`- Backticks
`โ wrap the entire string (not quotes) ${}โ the interpolation slot โ anything inside is evaluated as JavaScript- Everything outside
${}is treated as plain text
1. String Interpolation
Embedding variables or expressions directly into a string using ${}.
Variables
let name = "Mihir";
let role = "Developer";
let city = "Mumbai";
console.log(`Name: ${name}`);
console.log(`${name} is a ${role} from ${city}.`);
// Output: Mihir is a Developer from Mumbai.Expressions
Any valid JavaScript expression works inside ${} โ math, comparisons, function calls, ternary operators โ anything.
let a = 10;
let b = 5;
console.log(`Sum: ${a + b}`); // 15
console.log(`Product: ${a * b}`); // 50
console.log(`Power: ${a ** b}`); // 100000
console.log(`Is even: ${a % 2 === 0}`); // trueFunction Calls
function getDiscount(price, percent) {
return price - (price * percent / 100);
}
let price = 5000;
console.log(`Original: โน${price}`);
console.log(`After 20% off: โน${getDiscount(price, 20)}`);
// Output:
// Original: โน5000
// After 20% off: โน4000Ternary Operator Inside ${}
let marks = 78;
console.log(`Result: ${marks >= 40 ? "Pass โ
" : "Fail โ"}`);
// Output: Result: Pass โ
let stock = 0;
console.log(`Status: ${stock > 0 ? `${stock} in stock ๐ข` : "Out of stock ๐ด"}`);
// Output: Status: Out of stock ๐ดObject Properties
let user = { name: "Priya", age: 26, role: "Editor" };
console.log(`User: ${user.name} (${user.role}), Age: ${user.age}`);
// Output: User: Priya (Editor), Age: 26Array Values
let scores = [92, 85, 78];
console.log(`Scores: ${scores[0]}, ${scores[1]}, ${scores[2]}`);
console.log(`Total: ${scores.reduce((s, n) => s + n, 0)}`);
// Output:
// Scores: 92, 85, 78
// Total: 2552. Multi-line Strings
Before template literals, writing multi-line strings required \n escape characters. Now you just press Enter.
Old Way โ Painful โ
let message = "Dear Mihir,\n\nThank you for signing up.\nWelcome to our platform!\n\nRegards,\nThe Team";
console.log(message);Template Literal Way โ Clean โ
let name = "Mihir";
let message = `Dear ${name},
Thank you for signing up.
Welcome to our platform!
Regards,
The Team`;
console.log(message);
// Output:
// Dear Mihir,
//
// Thank you for signing up.
// Welcome to our platform!
//
// Regards,
// The TeamBuilding HTML Strings
let product = {
name: "Wireless Headphones",
price: 4999,
rating: 4.5,
};
let card = `
<div class="product-card">
<h2>${product.name}</h2>
<p class="price">โน${product.price.toLocaleString()}</p>
<p class="rating">โญ ${product.rating}/5</p>
<button>Add to Cart</button>
</div>
`;
console.log(card);Building Email Templates
function createWelcomeEmail(user) {
return `
Subject: Welcome to LearnJS, ${user.name}!
Hi ${user.name},
Welcome aboard! ๐ Your account has been created successfully.
Here are your details:
- Name: ${user.name}
- Email: ${user.email}
- Plan: ${user.plan}
Start learning at: https://learnjs.com/dashboard
Happy coding!
The LearnJS Team
`.trim();
}
let newUser = { name: "Mihir", email: "mihir@example.com", plan: "Pro" };
console.log(createWelcomeEmail(newUser));3. Nested Template Literals
You can put a template literal inside another template literal's ${}.
let isAdmin = true;
let username = "Mihir";
let header = `Welcome, ${username}! ${isAdmin ? `You have <strong>Admin</strong> access ๐` : `You are logged in as a User ๐ค`}`;
console.log(header);
// Output: Welcome, Mihir! You have <strong>Admin</strong> access ๐let cartItems = 3;
let cartMessage = `๐ Cart: ${cartItems > 0
? `${cartItems} item${cartItems > 1 ? "s" : ""} โ ready to checkout!`
: "Your cart is empty"}`;
console.log(cartMessage);
// Output: ๐ Cart: 3 items โ ready to checkout!4. Expressions and Logic Inside ${}
Since ${} evaluates any JavaScript expression, you can put quite a lot of logic right inside.
Math Operations
let radius = 7;
console.log(`Area of circle: ${(Math.PI * radius ** 2).toFixed(2)}`);
// Output: Area of circle: 153.94Method Calls
let name = " mihir shah ";
console.log(`Hello, ${name.trim().split(" ").map(w => w[0].toUpperCase() + w.slice(1)).join(" ")}!`);
// Output: Hello, Mihir Shah!Logical Operators
let user = { name: "Priya", nickname: "" };
console.log(`Hello, ${user.nickname || user.name}!`);
// Output: Hello, Priya! (nickname is empty, falls back to name)let config = null;
console.log(`Theme: ${config?.theme ?? "dark"}`);
// Output: Theme: dark5. Tagged Template Literals
A more advanced feature โ tagged templates let you process a template literal with a function. The function receives the string parts and interpolated values separately, giving you full control over how the output is built.
Syntax
tagFunction`string ${value} string`Basic Tagged Template
function tag(strings, ...values) {
console.log("Strings:", strings); // Array of string parts
console.log("Values:", values); // Array of interpolated values
}
let name = "Mihir";
let role = "Developer";
tag`Hello, ${name}! You are a ${role}.`;
// Strings: ['Hello, ', '! You are a ', '.']
// Values: ['Mihir', 'Developer']Real-World Use โ Highlight Interpolated Values
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
let value = values[i - 1];
return result + (value ? `**${value}**` : "") + str;
});
}
let name = "Mihir";
let score = 95;
let grade = "A+";
console.log(highlight`Student ${name} scored ${score} and earned grade ${grade}.`);
// Output: Student **Mihir** scored **95** and earned grade **A+**.Real-World Use โ Safe HTML (Escape User Input)
function safeHTML(strings, ...values) {
let result = strings[0];
values.forEach((value, i) => {
let safe = String(value)
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
result += safe + strings[i + 1];
});
return result;
}
let userInput = '<script>alert("hacked!")</script>';
let username = "Mihir";
console.log(safeHTML`<p>Hello, ${username}! Your message: ${userInput}</p>`);
// Output: <p>Hello, Mihir! Your message: <script>alert("hacked!")</script></p>Template Literals vs String Concatenation
let name = "Mihir";
let age = 25;
let city = "Mumbai";
let score = 92;
// โ Old concatenation โ hard to read
let msg1 = "Hello, " + name + "! You are " + age + " years old from " + city + " with a score of " + score + ".";
// โ
Template literal โ clean and readable
let msg2 = `Hello, ${name}! You are ${age} years old from ${city} with a score of ${score}.`;
console.log(msg1); // Same output
console.log(msg2); // Same output โ but so much cleaner!| Feature | Concatenation + | Template Literal |
|---|---|---|
| Readability | Hard with many variables | Clean and clear |
| Multi-line | Requires \n | Press Enter naturally |
| Expressions | Awkward | Direct inside ${} |
| HTML building | Very messy | Natural indentation |
| Method calls | Clunky | Inline in ${} |
Real-World Examples
Example 1: Generate a Product Card (HTML)
function renderProductCard(product) {
let discountBadge = product.discount
? `<span class="badge">-${product.discount}% OFF</span>`
: "";
return `
<div class="card">
${discountBadge}
<img src="${product.image}" alt="${product.name}" />
<h3>${product.name}</h3>
<p class="price">
โน${product.price.toLocaleString()}
${product.originalPrice ? `<del>โน${product.originalPrice.toLocaleString()}</del>` : ""}
</p>
<p class="rating">โญ ${product.rating} (${product.reviews} reviews)</p>
<button class="${product.inStock ? "btn-primary" : "btn-disabled"}">
${product.inStock ? "Add to Cart ๐" : "Out of Stock"}
</button>
</div>`.trim();
}
let product = {
name: "Wireless Headphones",
price: 3999,
originalPrice: 4999,
discount: 20,
rating: 4.5,
reviews: 1240,
inStock: true,
image: "/images/headphones.jpg",
};
console.log(renderProductCard(product));Example 2: Build a Report Table
let students = [
{ name: "Mihir", marks: 92, grade: "A" },
{ name: "Priya", marks: 85, grade: "B" },
{ name: "Rahul", marks: 60, grade: "C" },
{ name: "Sara", marks: 45, grade: "D" },
];
let rows = students
.map(s => ` ${s.name.padEnd(10)} | ${String(s.marks).padStart(5)} | ${s.grade}`)
.join("\n");
let report = `
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STUDENT REPORT โ
โ โโโโโโโโโโโโโฆโโโโโโโโฆโโโโโโฃ
โ Name โ Marks โ G โ
โ โโโโโโโโโโโโโฌโโโโโโโโฌโโโโโโฃ
${rows}
โโโโโโโโโโโโโโฉโโโโโโโโฉโโโโโโ
Total Students: ${students.length}
Average Marks: ${(students.reduce((s, st) => s + st.marks, 0) / students.length).toFixed(1)}
`.trim();
console.log(report);Example 3: Dynamic SQL-style Query Builder
function buildQuery({ table, fields = "*", where = null, limit = null }) {
let query = `SELECT ${fields} FROM ${table}`;
if (where) query += `\nWHERE ${where}`;
if (limit) query += `\nLIMIT ${limit}`;
return query + ";";
}
console.log(buildQuery({ table: "users" }));
// SELECT * FROM users;
console.log(buildQuery({
table: "products",
fields: "name, price",
where: "price < 1000 AND inStock = true",
limit: 10,
}));
// SELECT name, price FROM products
// WHERE price < 1000 AND inStock = true
// LIMIT 10;Example 4: Notification Message Builder
function buildNotification(type, data) {
const messages = {
like: `โค๏ธ ${data.from} liked your post "${data.post}"`,
comment: `๐ฌ ${data.from} commented: "${data.text}"`,
follow: `๐ค ${data.from} started following you`,
mention: `๐ ${data.from} mentioned you in "${data.post}"`,
};
return messages[type] ?? `๐ New notification from ${data.from}`;
}
console.log(buildNotification("like", { from: "Priya", post: "My JS Journey" }));
console.log(buildNotification("comment", { from: "Rahul", text: "Great post!" }));
console.log(buildNotification("follow", { from: "Sara" }));
console.log(buildNotification("share", { from: "Arjun", post: "Arrow Functions" }));
// Output:
// โค๏ธ Priya liked your post "My JS Journey"
// ๐ฌ Rahul commented: "Great post!"
// ๐ค Sara started following you
// ๐ New notification from ArjunCommon Mistakes
Mistake 1: Using Quotes Instead of Backticks
let name = "Mihir";
// โ Using quotes โ ${name} is treated as plain text
let msg = "Hello, ${name}!";
console.log(msg); // Hello, ${name}! โ Not interpolated!
// โ
Use backticks for interpolation
let msg = `Hello, ${name}!`;
console.log(msg); // Hello, Mihir! โ
Mistake 2: Unnecessary String Conversion
let count = 5;
// โ Redundant .toString() โ template literals handle it
let msg = `You have ${count.toString()} messages`;
// โ
Just use the value directly
let msg = `You have ${count} messages`;
// Output: You have 5 messages โ
Mistake 3: Complex Logic Inside ${} โ Hurts Readability
let users = [{ name: "Mihir" }, { name: "Priya" }];
// โ Too much logic crammed inside โ hard to read
let msg = `Users: ${users.filter(u => u.name.length > 4).map(u => u.name.toUpperCase()).join(", ")}`;
// โ
Compute first, then embed
let longNames = users.filter(u => u.name.length > 4).map(u => u.name.toUpperCase()).join(", ");
let msg = `Users: ${longNames}`;
console.log(msg); // Users: MIHIR โ
Mistake 4: Forgetting to Trim Multi-line Templates
function getGreeting(name) {
// โ Leading newline from the template indent
return `
Hello, ${name}!`;
}
console.log(getGreeting("Mihir"));
// (empty line)
// Hello, Mihir! โ extra indent
// โ
Use .trim() to clean up
function getGreeting(name) {
return `
Hello, ${name}!`.trim();
}
console.log(getGreeting("Mihir")); // Hello, Mihir! โ
Practical Exercise
Create a file called template-literals.js:
// ๐ฏ Template Literals Practice
// 1. User profile card
function renderProfile(user) {
let statusIcon = user.online ? "๐ข Online" : "๐ด Offline";
let premiumBadge = user.premium ? " ๐ Premium" : "";
return `
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ค ${user.name.padEnd(24)}โ
โ ๐ง ${user.email.padEnd(24)}โ
โ ๐๏ธ ${user.city.padEnd(23)}โ
โ ${statusIcon.padEnd(27)}โ
โ Plan: ${(user.plan + premiumBadge).padEnd(22)}โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ`.trim();
}
console.log("=== ๐ค User Profiles ===\n");
console.log(renderProfile({
name: "Mihir Shah", email: "mihir@example.com",
city: "Mumbai", online: true, plan: "Pro", premium: true,
}));
console.log();
console.log(renderProfile({
name: "Priya Nair", email: "priya@example.com",
city: "Pune", online: false, plan: "Free", premium: false,
}));
// 2. Invoice generator
function generateInvoice(order) {
let itemRows = order.items
.map(item => ` ${item.name.padEnd(20)} โน${String(item.price).padStart(6)} x${item.qty} = โน${item.price * item.qty}`)
.join("\n");
let subtotal = order.items.reduce((s, i) => s + i.price * i.qty, 0);
let tax = Math.round(subtotal * 0.18);
let total = subtotal + tax;
return `
${"=".repeat(45)}
INVOICE #${order.id}
${"=".repeat(45)}
Customer : ${order.customer}
Date : ${order.date}
${"โ".repeat(45)}
ITEMS:
${itemRows}
${"โ".repeat(45)}
Subtotal : โน${subtotal.toLocaleString()}
GST 18% : โน${tax.toLocaleString()}
TOTAL : โน${total.toLocaleString()}
${"=".repeat(45)}
Thank you for your order! ๐
${"=".repeat(45)}`.trim();
}
console.log("\n=== ๐งพ Invoice ===\n");
console.log(generateInvoice({
id: "INV-2024-001",
customer: "Mihir Shah",
date: "13 Feb 2024",
items: [
{ name: "JavaScript Course", price: 1999, qty: 1 },
{ name: "React Course", price: 2499, qty: 1 },
{ name: "Node.js Course", price: 1799, qty: 1 },
],
}));Run it:
node template-literals.jsExpected Output:
=== ๐ค User Profiles ===
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ค Mihir Shah โ
โ ๐ง mihir@example.com โ
โ ๐๏ธ Mumbai โ
โ ๐ข Online โ
โ Plan: Pro ๐ Premium โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
=== ๐งพ Invoice ===
=============================================
INVOICE #INV-2024-001
=============================================
Customer : Mihir Shah
Date : 13 Feb 2024
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
ITEMS:
JavaScript Course โน 1999 x1 = โน1999
React Course โน 2499 x1 = โน2499
Node.js Course โน 1799 x1 = โน1799
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Subtotal : โน6,297
GST 18% : โน1,133
TOTAL : โน7,430
=============================================
Thank you for your order! ๐
=============================================Key Takeaways
Congratulations! ๐ You now fully understand template literals in JavaScript.
โ
Template literals use backticks ` โ not quotes.
โ
String interpolation โ ${} embeds any expression directly into the string.
โ
Multi-line strings โ just press Enter โ no \n needed.
โ
Inside ${} you can use variables, math, method calls, ternary operators, function calls โ any valid JS expression.
โ
Nested template literals โ a template literal inside another template's ${} is perfectly valid.
โ Tagged templates โ process template literals with a function for advanced use cases like safe HTML and highlighting.
โ
Always .trim() multi-line template literal returns to remove leading/trailing newlines.
Best Practices
- โ
Always use template literals instead of
+concatenation โ cleaner and more readable - โ
Keep
${}expressions simple โ complex logic should be computed before embedding - โ
Use
.trim()on multi-line templates returned from functions - โ Use template literals for HTML strings โ natural indentation and readability
- โ
Use template literals for multi-line strings โ never
\nconcatenation - โ Use nested templates sparingly โ one level is fine, more gets unreadable
- โ Use tagged templates for security-sensitive output like user-generated HTML
- โ
Don't call
.toString()inside${}โ template literals convert values automatically
What's Next?
Excellent work! ๐ Template literals will make every string you write from here on cleaner and more expressive.
Next up, let's dive into one of the most important data structures in JavaScript:
Arrays and Array Methods โ โ ordered lists, powerful built-in methods, and everything you need to work with collections of data like a pro!
Let's keep going! ๐ช