Skip to main content

Command Palette

Search for a command to run...

Template Literals in JavaScript

Template Literals: The String Revolution You Didn't Know You Needed ✨

Updated
11 min read
J

Turning chai into code and ideas into full-stack applications. Sharing lessons from my development journey, one commit at a time.

The Birthday Card Disaster

Last year, I volunteered to code a birthday email generator for my university's student club. Simple enough, right? Send personalized emails to 500 students with their names, ages, and upcoming events.

Here's what I wrote (and deeply regretted):

const name = "Sarah";
const age = 21;
const event = "Welcome Party";
const date = "March 15th";

const message = "Hi " + name + "! Happy " + age + "th birthday! We're excited to invite you to our " + event + " on " + date + ". Hope to see you there!";

console.log(message);

It worked. Technically. But when I had to change the message format three times (committee members, you know), I spent 20 minutes hunting for missing + signs and quotes. One time, I forgot a space and sent emails saying "Hi Sarah!Happy 21th birthday!" 🤦

Then my senior showed me template literals, and it felt like discovering fire.


The Old Way: String Concatenation Hell 🔥

Before ES6 (2015), JavaScript developers had to build strings like this:

// Basic concatenation
const firstName = "John";
const lastName = "Doe";
const fullName = firstName + " " + lastName;

// The nightmare begins with complex strings
const user = "Alice";
const score = 95;
const grade = "A";

const report = "Student: " + user + "\nScore: " + score + "\nGrade: " + grade + "\nStatus: " + (score >= 90 ? "Excellent" : "Good");

Problems with Concatenation:

  1. Missing spaces (the classic "Hi" + name becomes "Hiname")

  2. Quote confusion ("He said "Hello"" breaks everything)

  3. Multi-line strings required weird \n everywhere

  4. Expression evaluation needed extra parentheses

  5. Readability was terrible for complex strings

Real example from my codebase:

// Trying to generate HTML (this is painful to read)
const html = "<div class=\"card\">" +
             "  <h2>" + title + "</h2>" +
             "  <p>" + description + "</p>" +
             "  <span>Posted by: " + author + " on " + date + "</span>" +
             "</div>";

I counted: 13 opportunities to make mistakes in just 5 lines! 😱


Template Literals: The Modern Solution 🚀

In 2015, ES6 gave us template literals (also called template strings), and they changed everything.

Basic Syntax: Backticks (`)

Instead of quotes "" or '', we use backticks ` `:

// Old way
const greeting1 = "Hello, World!";

// New way
const greeting2 = `Hello, World!`;

Looks the same? Wait for the magic...


Feature 1: String Interpolation 🎯

Embedding variables and expressions directly into strings:

const name = "Sarah";
const age = 21;

// Old way: Manual concatenation
const message1 = "Hi " + name + ", you are " + age + " years old.";

// New way: Template literal
const message2 = `Hi \({name}, you are \){age} years old.`;

console.log(message2);
// Output: "Hi Sarah, you are 21 years old."

The ${} Syntax:

  • Put any valid JavaScript expression inside ${}

  • Variables, math, function calls, ternaries—anything!

const price = 100;
const tax = 0.18;

// Expressions work!
const total = `Total: $${price + (price * tax)}`;
console.log(total);
// Output: "Total: $118"

// Function calls work!
const shout = (text) => text.toUpperCase();
const excited = `I'm ${shout('very excited')} about this!`;
console.log(excited);
// Output: "I'm VERY EXCITED about this!"

// Ternary operators work!
const score = 85;
const result = `You ${score >= 90 ? 'passed with honors' : 'passed'}!`;
console.log(result);
// Output: "You passed!"

Feature 2: Multi-line Strings 📝

Remember those ugly \n characters? Gone.

// Old way: Escape characters everywhere
const oldPoem = "Roses are red,\nViolets are blue,\nJavaScript is awesome,\nAnd so are you!";

// New way: Just write naturally
const newPoem = `Roses are red,
Violets are blue,
JavaScript is awesome,
And so are you!`;

console.log(newPoem);
/*
Output:
Roses are red,
Violets are blue,
JavaScript is awesome,
And so are you!
*/

Real-World Example: HTML Templates

const title = "My Blog Post";
const content = "This is amazing content!";
const author = "Jane Doe";

const htmlTemplate = `
<!DOCTYPE html>
<html>
  <head>
    <title>${title}</title>
  </head>
  <body>
    <article>
      <h1>${title}</h1>
      <p>${content}</p>
      <footer>Written by ${author}</footer>
    </article>
  </body>
</html>
`;

Before template literals, this would require:

  • 15+ concatenation operators

  • Manual \n insertion

  • Escaped quotes nightmare

  • High probability of syntax errors

With template literals: Just write it naturally! ✨


Feature 3: Expression Embedding 🧮

You can embed complex JavaScript directly:

const items = ['Apple', 'Banana', 'Orange'];

const list = `
Shopping List:
\({items.map((item, index) => `\){index + 1}. ${item}`).join('\n')}
`;

console.log(list);
/*
Output:
Shopping List:
1. Apple
2. Banana
3. Orange
*/

Date Formatting Example:

const now = new Date();

const formatted = `
Current Date: ${now.toLocaleDateString()}
Current Time: ${now.toLocaleTimeString()}
Timestamp: ${now.getTime()}
`;

console.log(formatted);
/*
Output:
Current Date: 4/12/2026
Current Time: 2:30:45 PM
Timestamp: 1744652445000
*/

Before vs After: Side-by-Side Comparison 📊

Example 1: User Greeting

const user = { name: "Alex", points: 1250, level: 15 };

// OLD WAY (Concatenation)
const oldGreeting = 
  "Welcome back, " + user.name + "! " +
  "You have " + user.points + " points " +
  "and you're at level " + user.level + ".";

// NEW WAY (Template Literal)
const newGreeting = 
  `Welcome back, \({user.name}! You have \){user.points} points and you're at level ${user.level}.`;

Lines of code: Same
Readability: 10x better
Error-prone: 70% less


Example 2: SQL Query

const table = "users";
const minAge = 18;
const country = "USA";

// OLD WAY
const oldQuery = 
  "SELECT * FROM " + table + 
  " WHERE age >= " + minAge + 
  " AND country = '" + country + "'";

// NEW WAY
const newQuery = 
  `SELECT * FROM ${table} 
   WHERE age >= ${minAge} 
   AND country = '${country}'`;

Example 3: API URL Building

const baseURL = "https://api.example.com";
const endpoint = "users";
const userId = 42;
const includeDetails = true;

// OLD WAY
const oldURL = 
  baseURL + "/" + endpoint + "/" + userId + 
  "?details=" + (includeDetails ? "true" : "false");

// NEW WAY
const newURL = 
  `\({baseURL}/\){endpoint}/\({userId}?details=\){includeDetails}`;

console.log(newURL);
// Output: "https://api.example.com/users/42?details=true"

Advanced Use Cases 🔥

1. Tagged Templates (Advanced)

You can process template literals with a function:

function highlight(strings, ...values) {
  return strings.reduce((result, str, i) => {
    return result + str + (values[i] ? `<mark>${values[i]}</mark>` : '');
  }, '');
}

const name = "JavaScript";
const year = 2015;

const message = highlight`\({name} template literals were introduced in \){year}!`;

console.log(message);
// Output: "<mark>JavaScript</mark> template literals were introduced in <mark>2015</mark>!"

Real-world use: Styled-components, i18n libraries, SQL builders!


2. Conditional Content

const user = { 
  name: "Sarah", 
  isPremium: true,
  credits: 50 
};

const dashboard = `
Welcome, ${user.name}!

${user.isPremium ? `
  ⭐ Premium Member Benefits:
  - Unlimited downloads
  - Priority support
  - Ad-free experience
` : `
  Upgrade to Premium for exclusive benefits!
`}

Credits remaining: ${user.credits}
`;

console.log(dashboard);

3. Dynamic Email Templates

function sendEmail(recipient, orderDetails) {
  const { name, items, total, orderNumber } = orderDetails;
  
  const emailBody = `
Hi ${name},

Thank you for your order (#${orderNumber})!

Order Summary:
\({items.map(item => `- \){item.name}: $${item.price}`).join('\n')}

Total: $${total}

We'll send you tracking information soon.

Best regards,
The Team
  `;
  
  return emailBody;
}

const order = {
  name: "Alex",
  orderNumber: "ORD-12345",
  items: [
    { name: "Laptop", price: 999 },
    { name: "Mouse", price: 25 }
  ],
  total: 1024
};

console.log(sendEmail("alex@example.com", order));

Common Gotchas & Solutions 🚨

Gotcha 1: Backticks in Strings

// Problem: Need to include a backtick in the string
const code = `Use backticks like this: \`template\``;
console.log(code);
// Output: Use backticks like this: `template`

Solution: Escape with backslash ```


Gotcha 2: Whitespace Preservation

const poem = `
  Roses are red
  Violets are blue
`;

console.log(poem);
/*
Output:

  Roses are red
  Violets are blue

*/
// Notice: Leading/trailing newlines are preserved!

Solution: Use .trim() if needed:

const cleanPoem = poem.trim();

Gotcha 3: Complex Expressions Get Messy

// Hard to read
const message = `The answer is ${someArray.filter(x => x > 10).map(x => x * 2).reduce((a, b) => a + b, 0)}`;

// Better: Extract to a variable
const result = someArray
  .filter(x => x > 10)
  .map(x => x * 2)
  .reduce((a, b) => a + b, 0);

const message = `The answer is ${result}`;

When to Use Template Literals 🎯

Always Use Template Literals For:

  1. Any string with variables

    const msg = `Hello, ${name}!`;
    
  2. Multi-line strings

    const html = `
      <div>
        <h1>Title</h1>
      </div>
    `;
    
  3. String building with expressions

    const price = `Total: $${basePrice * (1 + taxRate)}`;
    
  4. Dynamic content

    const status = `User is ${isActive ? 'online' : 'offline'}`;
    

⚠️ Use Regular Strings When:

  1. Simple static strings

    const hello = "Hello";  // No need for template literal
    
  2. Performance is ultra-critical (minimal difference, but concatenation is marginally faster in some engines)


Real-World Impact: My Refactoring Story 📈

Remember that birthday email generator? Here's the before and after:

// BEFORE: 45 lines, 3 bugs found in production
function generateEmail(student) {
  let email = "Hi " + student.name + "!\\n\\n";
  email += "Happy " + student.age;
  email += student.age === 21 ? "st" : student.age === 22 ? "nd" : "th";
  email += " birthday!\\n\\n";
  email += "Event: " + student.event + "\\n";
  email += "Date: " + student.date + "\\n\\n";
  email += "Best regards,\\nThe Team";
  return email;
}

// AFTER: 15 lines, 0 bugs, infinitely more readable
function generateEmail(student) {
  const { name, age, event, date } = student;
  const suffix = age === 21 ? 'st' : age === 22 ? 'nd' : 'th';
  
  return `Hi ${name}!

Happy \({age}\){suffix} birthday!

Event: ${event}
Date: ${date}

Best regards,
The Team`;
}

Result:

  • 66% less code

  • 100% fewer production bugs

  • Committee requested 5 more changes—took 2 minutes instead of 20


Interview Tips 💼

Common Question: "What are the advantages of template literals?"

Strong Answer:

  1. Readability: No concatenation operators cluttering the code

  2. Multi-line support: Native support without \n escapes

  3. Expression embedding: Any JavaScript expression works inside ${}

  4. Tagged templates: Advanced text processing capabilities

  5. Reduced errors: Fewer quotes and operators mean fewer mistakes

Bonus points: Mention that template literals are part of ES6 and have excellent browser support (IE11 doesn't support them, but edge cases).


Practice Challenge 🏋️

Refactor this ugly code using template literals:

function createProductCard(product) {
  let html = "<div class=\"product\">";
  html += "<img src=\"" + product.image + "\" alt=\"" + product.name + "\">";
  html += "<h3>" + product.name + "</h3>";
  html += "<p class=\"price\">$" + product.price + "</p>";
  html += "<p class=\"stock\">" + (product.inStock ? "In Stock" : "Out of Stock") + "</p>";
  html += "</div>";
  return html;
}

Solution:

function createProductCard(product) {
  const { image, name, price, inStock } = product;
  
  return `
<div class="product">
  <img src="\({image}" alt="\){name}">
  <h3>${name}</h3>
  <p class="price">$${price}</p>
  <p class="stock">${inStock ? 'In Stock' : 'Out of Stock'}</p>
</div>
  `.trim();
}

The Final Word 💭

Template literals aren't just a syntax upgrade—they're a mindset shift. They taught me that good code isn't about being clever; it's about being clear.

Every time I write a template literal, I remember those birthday emails and smile. The best code is the code that future-you (and your teammates) can read without wanting to scream.

So ditch the plus signs. Embrace the backticks. Your future self will thank you. 🙏


Your Turn! 🚀

What's the ugliest string concatenation you've ever written? Share in the comments—let's laugh (and cry) together!!