Suggest an editImprove this articleRefine the answer for “Template literals in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Template literals** are strings in JavaScript enclosed in backticks (`` ` ``) that support embedded expressions with `${}`, multi-line strings, and tagged templates. Introduced in ES6. ```javascript const name = "Alice"; const greeting = `Hello, ${name}!`; // "Hello, Alice!" ``` **Key point:** Use them whenever a string contains variables or spans multiple lines.Shown above the full answer for quick recall.Answer (EN)Image**Template literals** are strings wrapped in backticks (`` ` ``) that let you embed expressions with `${}` syntax, write multi-line strings without escape sequences, and use tagged templates for advanced processing. Introduced in ES6. ## Theory ### TL;DR - Template literals work like mail merge: one template, inject data where needed - Main difference: backticks + `${}` vs concatenation with `+` - Use them whenever a string has variables, multi-line content, or dynamic values - Static strings with no variables? Regular quotes are clearer there - Inside `${}` you can use any expression: math, function calls, ternary operators ### Quick example ```javascript const name = "Alice"; const age = 28; // Old way - concatenation const old = "Hello, " + name + "! You are " + age + " years old."; // Template literal const modern = `Hello, ${name}! You are ${age} years old.`; // "Hello, Alice! You are 28 years old." // Multi-line - no \n needed const message = `Welcome, ${name}! Your account is active. Age: ${age}`; ``` The backtick syntax removes the chain of `+` operators between every variable and string piece. ### Key difference Template literals evaluate expressions inside `${}` at runtime and convert results to strings automatically. With concatenation, you chain pieces with `+` and need `\n` for line breaks. Template literals handle both. They also unlock tagged templates, where a function receives the string parts and expression values separately before anything is concatenated. Regular strings cannot do that. ### When to use - Any string that mixes text with variables - Multi-line content: HTML snippets, SQL queries, error messages - Complex expressions: `${user.isAdmin ? 'admin' : 'user'}` - Dynamic attributes and class names in components - Avoid for plain static strings with no dynamic parts - regular quotes read more clearly there In practice, once you switch to template literals for dynamic strings, concatenation feels clunky even for simple two-part cases. ### How it works internally When the JS engine hits a template literal, it parses the backtick-delimited string and locates each `${}` block. Each expression gets evaluated in the current scope, converted via `.toString()`, and inserted at that position. For tagged templates, the engine splits the static string parts and evaluated expression values into separate arguments, then passes them to the tag function before any string building happens. Structure is resolved at parse time; expression evaluation happens at runtime. ### Common mistakes **Forgetting the `$` in `${}`** ```javascript const name = "Alice"; // ❌ Prints literal curly braces const greeting = `Hello, {name}!`; console.log(greeting); // "Hello, {name}!" - not what you wanted // ✅ Correct const greeting2 = `Hello, ${name}!`; console.log(greeting2); // "Hello, Alice!" ``` **Template literals as object keys** ```javascript const key = "user"; // ❌ The key becomes the literal string "${key}_name" const bad = { [`${key}_name`]: "Alice" }; // needs square brackets // Without brackets: { '${key}_name': 'Alice' } - wrong // ✅ Computed property syntax with square brackets const obj = { [`${key}_name`]: "Alice" }; console.log(obj); // { user_name: 'Alice' } ``` **Unescaped user input (XSS)** ```javascript const userInput = "<img src=x onerror='alert(1)'>"; // ❌ The script executes when rendered const html = `<div>${userInput}</div>`; // ✅ Escape before injecting function escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return text.replace(/[&<>"']/g, m => map[m]); } const safeHtml = `<div>${escapeHtml(userInput)}</div>`; // <div><img src=x onerror='alert(1)'></div> - safe ``` **Unexpected whitespace in multi-line templates** ```javascript // ❌ Includes a leading newline and indentation spaces const html = ` <div> <p>Content</p> </div> `; // ✅ Use .trim() or skip the leading newline const html2 = `<div> <p>Content</p> </div>`.trim(); ``` ### Real-world usage - React: dynamic `className` strings and `aria-label` attributes - Express/Node.js: SQL query strings, log messages, error responses - Apollo Client: GraphQL queries via the `gql` tagged template - styled-components: CSS-in-JS with tagged template syntax - Jest: test descriptions and snapshot strings ### Follow-up questions **Q:** What happens if you put an object inside `${}`? **A:** It calls `.toString()` on the value, which gives `[object Object]`. Use `JSON.stringify(obj)` explicitly if you need the actual content. **Q:** Can you use template literals as object property names? **A:** Not directly. Without square brackets the backtick string is treated as a literal key. You need computed property syntax: `{ [\`key_${x}\`]: value }`. **Q:** How do tagged templates actually work? **A:** The tag is a function that receives the static string parts as an array and the evaluated expression values as separate arguments: `(strings, ...values)`. The function decides how to combine them. That is how SQL tag functions escape query parameters and how styled-components processes CSS strings. **Q:** Are template literals slower than concatenation? **A:** No. Modern engines like V8 and SpiderMonkey optimize both. The performance difference is negligible. The reason to prefer template literals is readability. **Q:** (Senior) How do you build a tagged template that automatically prevents XSS? **A:** Write a tag function that maps over the `values` array and escapes each one before insertion. It receives `(strings, ...values)` - escape each value and interleave with the `strings` parts to build the final string. This is exactly how `lit-html` and `htm` handle user-provided content. ## Examples ### Basic interpolation and multi-line string ```javascript const user = { name: "Alice", email: "alice@example.com" }; const isActive = true; const card = ` Name: ${user.name} Email: ${user.email} Status: ${isActive ? "active" : "inactive"} Joined: ${new Date().toLocaleDateString()} `.trim(); console.log(card); // Name: Alice // Email: alice@example.com // Status: active // Joined: 1/15/2025 ``` Ternary operators, method calls, and property access all work inside `${}`. The `.trim()` removes the leading and trailing newlines that come from the backtick wrapping. ### Tagged template for SQL query safety ```javascript function sql(strings, ...values) { const escaped = values.map(v => typeof v === "string" ? `'${v.replace(/'/g, "''")}'` : v ); let result = strings[0]; for (let i = 0; i < escaped.length; i++) { result += escaped[i] + strings[i + 1]; } return result; } const userId = 42; const userName = "O'Brien"; // contains an apostrophe const query = sql`SELECT * FROM users WHERE id = ${userId} AND name = ${userName}`; console.log(query); // SELECT * FROM users WHERE id = 42 AND name = 'O''Brien' // The apostrophe is escaped - SQL injection blocked ``` The tag function runs before the string is built. It receives the static parts in `strings` and the evaluated expressions in `values`. This is the same pattern Apollo Client uses for GraphQL queries with the `gql` tag.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.