JavaScript Template Literals: Complete String Guide
What You'll Learn:
- ✅ Template literal syntax and basics
- ✅ String interpolation with expressions
- ✅ Multi-line strings
- ✅ Nesting and complex expressions
- ✅ Tagged templates for advanced processing
- ✅ Performance considerations
- ✅ Common pitfalls and best practices
What are Template Literals?
Template literals are a modern way to work with strings in JavaScript, using backticks (`) instead of quotes. They provide string interpolation, allowing you to embed expressions directly in strings, and they support multi-line strings natively. Introduced in ES6 (2015), they've become the preferred way to work with strings in modern JavaScript.
Basic Syntax
Template Literal Basics
// Template literal uses backticks
const greeting = `Hello, World!`;
console.log(greeting); // "Hello, World!"
// Equivalent to traditional strings:
const old = "Hello, World!";
const modern = `Hello, World!`;
console.log(old === modern); // true
// Can contain single and double quotes without escaping:
const quote1 = `She said "Hello"`;
const quote2 = `It's beautiful`;
const quote3 = `"It's going to be great," he said`;
console.log(quote1); // She said "Hello"
console.log(quote2); // It's beautiful
console.log(quote3); // "It's going to be great," he said
Template literals use backticks and support both single and double quotes without escaping.
String Interpolation - The Power
String interpolation lets you embed variables and expressions directly in strings using ${ and } syntax. This eliminates tedious string concatenation.
String Interpolation
// Variables in template literals
const name = "Alice";
const age = 25;
// Old way (concatenation)
const oldWay = "My name is " + name + " and I'm " + age + " years old";
// Modern way (interpolation)
const modern = `My name is ${name} and I'm ${age} years old`;
console.log(modern); // My name is Alice and I'm 25 years old
// Any expression works inside ${}
const x = 10;
const y = 20;
console.log(`${x} plus ${y} equals ${x + y}`); // 10 plus 20 equals 30
// Function calls
function getGreeting(time) {
return time < 12 ? "Good morning" : "Good afternoon";
}
const hour = new Date().getHours();
console.log(`Status: ${getGreeting(hour)}`);
// Ternary operators
const score = 85;
console.log(`Grade: ${score >= 90 ? "A" : score >= 80 ? "B" : "C"}`);
// Method calls
const text = "javascript";
console.log(`Language: ${text.toUpperCase()}`); // Language: JAVASCRIPT
Interpolation with \${...} lets you embed any expression directly in strings, replacing tedious concatenation.
Multi-line Strings
Template literals preserve newlines and whitespace, making multi-line strings simple and readable.
Multi-line Strings
// Traditional multi-line (awkward)
const oldWay = "Line 1\n" +
"Line 2\n" +
"Line 3";
// Template literal (clean)
const modern = `Line 1
Line 2
Line 3`;
console.log(modern);
// Output:
// Line 1
// Line 2
// Line 3
// HTML template (very common use case)
const htmlTemplate = `
<div class="container">
<h1>Welcome</h1>
<p>This is a paragraph</p>
</div>
`;
// SQL queries
const userId = 123;
const sqlQuery = `
SELECT * FROM users
WHERE id = ${userId}
AND status = 'active'
`;
// JSON-like structures
const config = `
{
"name": "MyApp",
"version": "1.0.0",
"debug": true
}
`;
// Warning: Whitespace is preserved!
const indented = `
Indented text
More indented
`; // Includes leading spaces and newlines
Template literals preserve newlines and whitespace, enabling clean multi-line strings.
Nested and Complex Expressions
Advanced Interpolation
// Nested template literals
const user = { name: "Bob", premium: true };
const message = `
User: ${user.name}
Status: ${user.premium ? "Premium" : "Free"}
`;
// Objects and arrays
const person = { name: "Carol", age: 30, hobbies: ["reading", "coding"] };
console.log(`
Name: ${person.name}
Age: ${person.age}
Hobbies: ${person.hobbies.join(", ")}
`);
// Nested template literals
const outer = `
Outer: ${`Inner template with ${123}`}
`;
console.log(outer); // Outer: Inner template with 123
// Conditional logic
const items = [1, 2, 3];
const list = `
Items count: ${items.length}
${items.length > 0 ? `First item: ${items[0]}` : "No items"}
`;
// Loop inside template
const numbers = [1, 2, 3];
const result = `
Numbers: ${numbers.map(n => n * 2).join(", ")}
`;
console.log(result); // Numbers: 2, 4, 6
Template literals support nested templates, objects, arrays, and complex expressions.
Tagged Templates (Advanced)
Tagged templates allow you to process template literals with a function. The function receives the string parts and interpolated values separately, enabling custom processing.
Tagged Templates
// Tag function receives (strings, ...values)
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
return result + str + (values[i] ? `<mark>${values[i]}</mark>` : "");
}, "");
}
const name = "Alice";
const age = 25;
const result = highlight`My name is ${name} and I'm ${age}`;
console.log(result);
// My name is <mark>Alice</mark> and I'm <mark>25</mark>
// Practical example: HTML escaping
function escape(strings, ...values) {
const escapeHtml = (str) => {
const map = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'"
};
return str.replace(/[&<>"']/g, m => map[m]);
};
return strings.reduce((result, str, i) => {
return result + str + (values[i] ? escapeHtml(values[i]) : "");
}, "");
}
const userInput = "<script>alert('xss')</script>";
const safe = escape`User input: ${userInput}`;
console.log(safe);
// User input: <script>alert('xss')</script>
// Real libraries use this: styled-components, graphql template tags, etc.
Tagged templates let you create functions that process template literals, enabling custom formatting and security features.
Best Practices
- ✅Use template literals over concatenation: More readable, fewer errors
- ✅Keep interpolations simple: Move complex logic to variables first
- ✅Watch whitespace in multi-line: Often included unintentionally
- ✅Use for HTML/SQL templates:**Really clean and readable
- ✅Consider tagged templates for complex processing: Like HTML escaping
Common Pitfalls
Things to Watch Out For
// PITFALL 1: Forgetting $ in interpolation
const name = "Bob";
const wrong = `Hello {name}`; // "Hello {name}" (literal braces!)
const right = `Hello ${name}`; // "Hello Bob"
// PITFALL 2: Backticks vs quotes
const text = "This won't work as template literal"; // Just a string
const template = `This works as ${variable}`; // Template literal
// PITFALL 3: Unwanted whitespace
const html = `
<div>
Content
</div>
`; // Has leading/trailing whitespace and indentation
// Better:
const htmlClean = [
"<div>",
" Content",
"</div>"
].join("\n");
// Or use trim():
const htmlTrimmed = `
<div>
Content
</div>
`.trim();
// PITFALL 4: XSS vulnerability with user input
const userInput = "<script>alert('xss')</script>";
const unsafe = `<div>${userInput}</div>`; // DANGEROUS!
// Always escape or use a template library
const safeHtml = escapeHtml(`<div>${userInput}</div>`);
Common mistakes with template literals include forgetting $, confusion with backticks, whitespace issues, and security vulnerabilities.
Performance Notes
Performance Comparison
// Performance is similar for simple cases
// But string concatenation in loops can be slow
// SLOW - concatenation in loop
let slow = "";
for (let i = 0; i < 1000; i++) {
slow += `Item ${i},`;
}
// FAST - join array
const items = [];
for (let i = 0; i < 1000; i++) {
items.push(`Item ${i}`);
}
const fast = items.join(",");
// Template literals don't automatically optimize loops
// Use array + join for large string building
Template literals have similar performance to concatenation for simple cases, but use array.join() for building large strings.
Interview Q&A
Q: What's the difference between template literals and regular strings?
A: Template literals use backticks, support \$ interpolation, preserve newlines, and allow direct expression embedding. Regular strings don't support interpolation and require concatenation or escape sequences for newlines.
Q: How do tagged templates work?
A: Tagged templates call a function with the template. The function receives an array of string parts and the interpolated values as separate arguments, allowing custom processing like HTML escaping or SQL injection prevention.
Summary
- 🎯 Template literals use backticks and support \$ interpolation
- 🎯 They're cleaner than concatenation for complex strings
- 🎯 Multi-line strings are supported natively
- 🎯 Tagged templates enable custom string processing
- 🎯 Always escape user input in templates for security
- 🎯 Use array.join() for building very large strings
- 🎯 They're the modern standard for string handling in JavaScript