[{"data":1,"prerenderedAt":170},["ShallowReactive",2],{"qa-\u002Fjavascript\u002Fmodern\u002Ftemplate-literals":3},{"page":4,"siblings":154,"blog":167},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":145,"seo":146,"seoDescription":147,"stem":148,"subtopic":149,"topic":150,"topicSlug":151,"updated":152,"__hash__":153},"qa\u002Fjavascript\u002Fmodern\u002Ftemplate-literals.md","Template Literals",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","JavaScript","javascript",{},true,3,"\u002Fjavascript\u002Fmodern\u002Ftemplate-literals",[23,28,32,36,40,44,48,52,56,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141],{"id":24,"difficulty":25,"q":26,"a":27},"template-literal-basics","easy","What is a template literal?","A **template literal** is a string written with **backticks** (`` ` ``)\nthat supports interpolation and spans multiple lines.\n\n```js\nconst name = 'Ada'\nconst msg = `Hello, ${name}!`   \u002F\u002F \"Hello, Ada!\"\n```\n\nBackticks replace the need for string concatenation and make embedded\nvalues far more readable than `'Hello, ' + name + '!'`.\n",{"id":29,"difficulty":25,"q":30,"a":31},"interpolation","How does ${} interpolation work?","Any expression inside **`${ }`** is evaluated and its result coerced to a\nstring, then spliced into place.\n\n```js\nconst a = 5, b = 3\n`Sum is ${a + b}`         \u002F\u002F \"Sum is 8\"\n`Upper: ${name.toUpperCase()}`  \u002F\u002F method calls allowed\n```\n\nIt's a full expression slot — arithmetic, calls, ternaries, even nested\ntemplate literals all work. It is **not** a statement slot, so `if`\u002F`for`\ncan't go there.\n",{"id":33,"difficulty":25,"q":34,"a":35},"multiline-strings","How do template literals handle multiline strings?","Newlines inside backticks are **preserved literally** — no `\\n` or\nconcatenation needed.\n\n```js\nconst text = `Line 1\nLine 2`         \u002F\u002F contains a real newline\n```\n\nPitfall: indentation inside the literal becomes part of the string. Leading\nspaces on the second line are included, which can surprise you when the\ncode is nested deep in a function.\n",{"id":37,"difficulty":14,"q":38,"a":39},"expression-embedding","What kinds of expressions can you embed?","Any valid JavaScript **expression**: arithmetic, function calls, ternaries,\nproperty access, even another template literal.\n\n```js\n`Status: ${active ? 'on' : 'off'}`\n`Total: ${items.reduce((s, i) => s + i.price, 0)}`   \u002F\u002F\n```\n\nKeep them simple, though — heavy logic inside `${}` hurts readability.\nCompute into a variable first when the expression gets complex.\n",{"id":41,"difficulty":14,"q":42,"a":43},"nested-templates","Can you nest template literals?","Yes — a `${}` slot can contain another backtick string, which is useful for\nconditional fragments.\n\n```js\nconst html = `\u003Cul>${items.map(i => `\u003Cli>${i}\u003C\u002Fli>`).join('')}\u003C\u002Ful>`\n```\n\nIt works, but deeply nested templates become hard to read. For non-trivial\nmarkup, prefer a templating library or break the pieces into named\nvariables.\n",{"id":45,"difficulty":14,"q":46,"a":47},"tagged-template-basics","What is a tagged template?","A **tagged template** calls a function with the literal's parts. The tag\nfunction receives the array of **string segments** first, then each\ninterpolated **value** as subsequent arguments.\n\n```js\nfunction tag(strings, ...values) {\n  return { strings, values }\n}\ntag`Hi ${name}, you are ${age}`\n\u002F\u002F strings: ['Hi ', ', you are ', ''], values: [name, age]\n```\n\nThe tag fully controls the output — it doesn't have to return a string at\nall. This powers libraries like styled-components and graphql-tag.\n",{"id":49,"difficulty":14,"q":50,"a":51},"tagged-template-strings-values","Why does the strings array always have one more element than values?","Because the string segments **surround** the interpolations — there's\nalways a piece before the first `${}` and after the last one (possibly\nempty).\n\n```js\ntag`a${1}b${2}c`\n\u002F\u002F strings: ['a', 'b', 'c']  (3)\n\u002F\u002F values:  [1, 2]           (2)  strings.length === values.length + 1\n```\n\nTag functions rely on this invariant to interleave: zip\n`strings[i]` with `values[i]` and append the final `strings[n]`.\n",{"id":53,"difficulty":14,"q":54,"a":55},"string-raw","What does String.raw do?","**`String.raw`** is a built-in tag that returns the string with escape\nsequences **uninterpreted** — backslashes stay literal.\n\n```js\nString.raw`C:\\new\\test`   \u002F\u002F 'C:\\\\new\\\\test' (backslashes kept)\n`C:\\new\\test`             \u002F\u002F 'C:' + newline + 'ew' + tab + 'est'\n```\n\nGreat for Windows paths, regex source, and LaTeX. The `strings.raw`\nproperty is how any custom tag accesses the un-escaped segments.\n",{"id":57,"difficulty":58,"q":59,"a":60},"raw-property","hard","What is the .raw property on the strings array?","Inside a tag, `strings` also carries a **`raw`** array holding the\nsegments **before** escape processing — so the tag can choose cooked or raw\ntext.\n\n```js\nfunction show(strings) {\n  return strings.raw[0]   \u002F\u002F raw, e.g. '\\\\n' stays as backslash-n\n}\nshow`\\n`   \u002F\u002F '\\\\n'  not an actual newline\n```\n\n`String.raw` is literally implemented by joining `strings.raw` with the\nvalues.\n",{"id":62,"difficulty":14,"q":63,"a":64},"i18n-use-case","How are tagged templates used for internationalization?","A tag can rebuild the message from its parts, looking up a translated\ntemplate by the static `strings` segments and re-inserting the dynamic\nvalues.\n\n```js\nfunction i18n(strings, ...values) {\n  const key = strings.join('{}')          \u002F\u002F stable lookup key\n  const translated = dictionary[key] ?? key\n  return interpolate(translated, values)   \u002F\u002F locale-aware\n}\ni18n`Hello ${name}`\n```\n\nBecause the static parts are constant per call site, they make a reliable\ntranslation key.\n",{"id":66,"difficulty":58,"q":67,"a":68},"html-escaping-tag","How can a tagged template prevent injection?","The tag escapes the **interpolated values** while leaving the static\n`strings` (trusted, author-written) untouched — exactly what raw template\nliterals fail to do.\n\n```js\nfunction safeHtml(strings, ...values) {\n  return strings.reduce((out, s, i) =>\n    out + s + (i \u003C values.length ? escapeHtml(values[i]) : ''), '')\n}\nsafeHtml`\u003Cp>${userInput}\u003C\u002Fp>`   \u002F\u002F userInput is escaped\n```\n\nThis is the secure pattern; plain `` `\u003Cp>${userInput}\u003C\u002Fp>` `` injects raw\nuser input.\n",{"id":70,"difficulty":58,"q":71,"a":72},"injection-risk","What's the security pitfall of plain template literals?","They perform **no escaping** — interpolated values go in verbatim. Building\nHTML or SQL by interpolation invites XSS\u002FSQL injection.\n\n```js\nel.innerHTML = `\u003Cdiv>${userInput}\u003C\u002Fdiv>`   \u002F\u002F XSS if userInput has \u003Cscript>\ndb.query(`SELECT * FROM u WHERE id = ${id}`) \u002F\u002F SQL injection\n```\n\nUse a sanitizing tag for HTML, and **parameterized queries** for SQL —\nnever interpolate untrusted data into markup or queries directly.\n",{"id":74,"difficulty":25,"q":75,"a":76},"concatenation-comparison","Why prefer template literals over string concatenation?","They're more readable, avoid `+` clutter and stray-space bugs, and handle\nmultiline naturally.\n\n```js\n'Hi ' + name + ', you have ' + n + ' items'   \u002F\u002F noisy\n`Hi ${name}, you have ${n} items`             \u002F\u002F clear\n```\n\nConcatenation also silently coerces with `+`, where a misplaced operand can\nproduce `NaN` or \"[object Object]\"; template slots make intent explicit.\n",{"id":78,"difficulty":14,"q":79,"a":80},"coercion-in-template","How are non-string values coerced inside a template?","Each `${}` result is converted with the abstract ToString — objects call\n`toString()`, arrays join with commas, `null`\u002F`undefined` stringify\nliterally.\n\n```js\n`${[1, 2, 3]}`    \u002F\u002F '1,2,3'\n`${ {a: 1} }`     \u002F\u002F '[object Object]'  rarely what you want\n`${null}`         \u002F\u002F 'null'\n```\n\nFor objects you usually want `JSON.stringify(obj)` inside the slot rather\nthan relying on the default `[object Object]`.\n",{"id":82,"difficulty":25,"q":83,"a":84},"escaping-backtick","How do you include a backtick or ${ literally?","Escape them with a backslash.\n\n```js\n`A backtick: \\``        \u002F\u002F \"A backtick: `\"\n`Not a slot: \\${x}`     \u002F\u002F \"Not a slot: ${x}\"  literal\n```\n\nWithout the backslash, `${x}` would be interpreted as interpolation. This\nmatters when generating template-literal source code or documentation.\n",{"id":86,"difficulty":14,"q":87,"a":88},"css-in-js","How do tagged templates enable CSS-in-JS?","Libraries like styled-components expose a tag that turns the literal into a\nstyled component, injecting interpolated values as dynamic style props.\n\n```js\nconst Button = styled.button`\n  color: ${props => props.primary ? 'white' : 'black'};\n`   \u002F\u002F tag processes the CSS + functions\n```\n\nThe tag receives the CSS chunks and the prop-accessor functions, then\ngenerates real stylesheets at render time.\n",{"id":90,"difficulty":14,"q":91,"a":92},"graphql-gql","Why does GraphQL use a gql tagged template?","The `gql` tag parses the query string into an **AST** at definition time,\ncatching syntax errors early and enabling tooling (highlighting, type\ngeneration) on the embedded query.\n\n```js\nconst QUERY = gql`\n  query { user { id name } }\n`   \u002F\u002F parsed, not just a string\n```\n\nIt also lets fragments be interpolated and composed via `${}` while keeping\na single parse step.\n",{"id":94,"difficulty":58,"q":95,"a":96},"performance-static-strings","Are the strings arrays in tagged templates cached?","Yes — for a given tagged-template **call site**, the engine reuses the\n**same frozen `strings` array** across invocations. This lets tags memoize\nby identity.\n\n```js\nfunction tag(strings) { \u002F* strings is the same object each call *\u002F }\nfunction run() { return tag`hello` }\nrun() ; run()   \u002F\u002F both calls receive the identical strings reference\n```\n\nLibraries exploit this to cache parsed templates (e.g. compiled CSS or\nGraphQL) keyed on the `strings` object.\n",{"id":98,"difficulty":14,"q":99,"a":100},"dedent-indentation","How do you handle unwanted indentation in multiline templates?","The literal preserves source indentation, so nested code leaks leading\nspaces. Use a **dedent** tag or post-process with a regex.\n\n```js\nconst sql = `\n  SELECT *\n  FROM users\n`   \u002F\u002F each line has leading spaces\n\nconst clean = sql.replace(\u002F^\\s+\u002Fgm, '')   \u002F\u002F strip leading whitespace\n```\n\nDedent helper tags are common in test fixtures and embedded SQL\u002FGraphQL to\nkeep output clean while keeping source readable.\n",{"id":102,"difficulty":25,"q":103,"a":104},"ternary-in-slot","How do you add conditional content inside a template?","Use a **ternary** or short-circuit expression in the slot — statements\naren't allowed.\n\n```js\n`Cart${count !== 1 ? 's' : ''}`           \u002F\u002F pluralize\n`${error ? `Error: ${error}` : 'OK'}`     \u002F\u002F nested + conditional\n```\n\nFor anything beyond a simple ternary, compute the fragment in a variable\nfirst to keep the literal readable.\n",{"id":106,"difficulty":14,"q":107,"a":108},"arrays-join-in-template","How do you render a list inside a template literal?","Map to strings and **`join`** — relying on default array coercion adds\ncommas you usually don't want.\n\n```js\n`\u003Cul>${items.map(i => `\u003Cli>${i}\u003C\u002Fli>`).join('')}\u003C\u002Ful>`   \u002F\u002F\n`\u003Cul>${items}\u003C\u002Ful>`   \u002F\u002F inserts commas between items\n```\n\nThe explicit `.join('')` (or `.join(', ')`) controls the separator instead\nof getting the implicit comma.\n",{"id":110,"difficulty":14,"q":111,"a":112},"template-vs-format","Do template literals support format specifiers like printf?","No — there's no `%d`\u002F`%s` formatting. You format inside the slot with\nmethods or `Intl`.\n\n```js\n`Price: ${value.toFixed(2)}`                       \u002F\u002F 2 decimals\n`Date: ${new Intl.DateTimeFormat('en').format(d)}` \u002F\u002F locale format\n```\n\nFor padding\u002Fnumber formatting use `padStart`, `toLocaleString`, or `Intl.*`\nrather than expecting printf-style directives.\n",{"id":114,"difficulty":25,"q":115,"a":116},"empty-interpolation","What happens with an empty or whitespace ${} slot?","`${}` with nothing is a **SyntaxError** — a slot must contain an\nexpression. Whitespace alone is also invalid.\n\n```js\n`${}`        \u002F\u002F SyntaxError\n`${ '' }`    \u002F\u002F an empty-string expression is fine\n`${ \u002F* x *\u002F undefined }`  \u002F\u002F valid, inserts 'undefined'\n```\n\nYou need a real expression; if you want nothing, interpolate an empty\nstring `''`.\n",{"id":118,"difficulty":58,"q":119,"a":120},"tagged-non-string-return","Can a tagged template return something other than a string?","Yes — the tag's return value is whatever the function returns. It can be an\nobject, a component, a parsed AST, a function, anything.\n\n```js\nfunction obj(strings, ...values) {\n  return { template: strings, data: values }   \u002F\u002F returns an object\n}\nconst x = obj`a ${1}`   \u002F\u002F x is an object, not a string\n```\n\nThis flexibility is the whole point — tags are a DSL hook, not just string\nformatters.\n",{"id":122,"difficulty":14,"q":123,"a":124},"line-continuation","How do you write a long single-line string without a literal newline?","End a line with a **backslash** to continue without inserting a newline.\n\n```js\nconst s = `This is one long \\\nlogical line`   \u002F\u002F no newline between 'long ' and 'logical'\n```\n\nBe careful: any spaces after the backslash break it. This is occasionally\nhandy, but joining string parts or using normal wrapping is usually\nclearer.\n",{"id":126,"difficulty":14,"q":127,"a":128},"template-with-functions","Can you call a function and use its result in a slot?","Yes — slots are expressions, so calls (including IIFEs) are allowed and\ntheir return value is interpolated.\n\n```js\n`Now: ${getTime()}`\n`Result: ${(() => compute())()}`   \u002F\u002F IIFE result\n```\n\nSide effects run at interpolation time, in left-to-right order with the\nother slots — keep that in mind if a slot mutates state.\n",{"id":130,"difficulty":14,"q":131,"a":132},"comparison-with-sprintf","When might you still want a formatting library instead of templates?","For locale-aware numbers\u002Fdates, complex pluralization (ICU MessageFormat),\nor printf-style alignment, dedicated libraries (`Intl`, `messageformat`) do\nwhat raw templates can't.\n\n```js\n\u002F\u002F pluralization rules vary by language — a template can't express them all\nmessageFormat.format({ count })   \u002F\u002F handles one\u002Ffew\u002Fmany per locale\n```\n\nTemplates excel at simple interpolation and embedded DSLs; reach for\nformatting libs when human-language or numeric formatting gets involved.\n",{"id":134,"difficulty":14,"q":135,"a":136},"jsx-relation","Are template literals related to JSX?","No — JSX is a separate compile-time syntax transformed by Babel\u002FTypeScript,\nnot a runtime template literal. But tagged templates (`html\\`...\\``) are\nthe **JSX-free** alternative used by libraries like lit-html.\n\n```js\n\u002F\u002F lit-html: tagged template, no build step needed\nhtml`\u003Cdiv>${content}\u003C\u002Fdiv>`   \u002F\u002F runtime, parsed by the html tag\n```\n\nSo tagged templates give a \"JSX-like\" templating experience without a\ncompiler.\n",{"id":138,"difficulty":58,"q":139,"a":140},"whitespace-control","How do you control whitespace between interpolations?","Whatever sits between `${}` slots in the source is kept exactly, so you\nmanage spacing by what you type — or strip it in a tag.\n\n```js\n`${a} ${b}`     \u002F\u002F single space between\n`${a}${b}`      \u002F\u002F no space\n`${a}\n${b}`           \u002F\u002F newline preserved between them\n```\n\nFor HTML where whitespace collapses anyway it rarely matters; for\nprecise output (CSV, fixed-width), a normalizing tag gives full control.\n",{"id":142,"difficulty":25,"q":143,"a":144},"best-practices","What are best practices for template literals?","Keep `${}` expressions simple, never interpolate untrusted data into\nHTML\u002FSQL without escaping\u002Fparameters, use `String.raw` for paths\u002Fregex, and\nmind leaked indentation in multiline strings.\n\n```js\nconst label = `${count} ${count === 1 ? 'item' : 'items'}`  \u002F\u002F simple\nel.textContent = `Hello ${name}`   \u002F\u002F textContent, not innerHTML\n```\n\nPrefer `textContent` over `innerHTML`, and a sanitizing tag when raw markup\nis unavoidable.\n",null,{"description":11},"JavaScript template literal interview questions — interpolation, multiline strings, expression embedding, tagged templates, String.raw and security pitfalls around escaping.","javascript\u002Fmodern\u002Ftemplate-literals","Template Literals & Tagged Templates","Modern JavaScript (ES6+)","modern","2026-06-18","omSaAPQVGjJbVBYUSbK9SnLVjjpYF_CcFJGLpbxUZSU",[155,159,162,163],{"subtopic":156,"path":157,"order":158},"Destructuring, Spread & Rest","\u002Fjavascript\u002Fmodern\u002Fdestructuring-spread-rest",1,{"subtopic":160,"path":161,"order":12},"Optional Chaining & Nullish Coalescing","\u002Fjavascript\u002Fmodern\u002Foptional-chaining-nullish",{"subtopic":149,"path":21,"order":20},{"subtopic":164,"path":165,"order":166},"Symbols","\u002Fjavascript\u002Fmodern\u002Fsymbols",4,{"path":168,"title":169},"\u002Fblog\u002Fjavascript-template-literals-tagged-templates","JavaScript Template Literals & Tagged Templates — Interpolation, Multiline and DSLs",1781808676251]