Suggest an editImprove this articleRefine the answer for “Tagged template literals”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A tagged template is a template literal preceded by a function name: JavaScript does not build the string itself, it calls that function and passes it the array of text parts separately from all the injected values.** That lets the tag control how the values reach the result: they can be escaped, formatted, highlighted, or turned into a completely different type. The call `` tag`Hello, ${name}!` `` becomes `tag(['Hello, ', '!'], name)`. ```javascript function tag(strings, ...values) { console.log(strings); // [ 'Hello, ', '!' ] console.log(values); // [ 'Alex' ] } const name = 'Alex'; tag`Hello, ${name}!`; ``` **Key point:** the tag receives `strings` and `values` and decides for itself what the final string will be.Shown above the full answer for quick recall.Answer (EN)Image**A tagged template literal is a template literal with a function name written in front of it; instead of joining the pieces automatically, JavaScript calls that function and hands it the string parts and the injected values separately.** The tag decides what to do with the values, which is why this construct is used for escaping, formatting and custom mini-languages such as CSS-in-JS. ## Theory ### TL;DR - A plain template just inserts values, a tagged one hands control to a function. - The tag function receives two sets of data: the array of text parts and the list of injected values. - `` tag`Hello, ${name}!` `` runs as `tag(['Hello, ', '!'], name)`. - A tag may return anything, not necessarily a string. - Main uses: safe HTML, CSS-in-JS, GraphQL queries, formatting, i18n. ### Quick example ```javascript function tag(strings, ...values) { console.log(strings); // [ 'Hello, ', '!' ] console.log(values); // [ 'Alex' ] } const name = 'Alex'; tag`Hello, ${name}!`; ``` What happens under the hood: ```javascript // The interpreter does roughly this: tag(['Hello, ', '!'], 'Alex'); ``` ### How it looks and what the tag receives A plain template literal simply substitutes variables: ```javascript const name = 'Alex'; console.log(`Hello, ${name}!`); // Hello, Alex! ``` But if you put a function name in front of the template literal, JavaScript calls that function and passes it: 1. The array of string parts (the text between substitutions). 2. All the injected values from `${...}`. ```javascript tag`Hello, ${name}!` ``` That is a tagged template. So: - `strings` is the array of all the text chunks between insertions; - `values` is the array of all injected values, collected by the rest parameter. There is always one more text part than there are values, because a template starts and ends with text, possibly empty. ### Processing the content: your own templating A tag function can be used to build your own template languages or to format strings. ```javascript function highlight(strings, ...values) { return strings.reduce( (result, str, i) => result + str + (values[i] ? `<b>${values[i]}</b>` : ''), '' ); } const name = 'Alex'; const lang = 'JavaScript'; const message = highlight`Hello, ${name}! You love ${lang}.`; console.log(message); // Hello, <b>Alex</b>! You love <b>JavaScript</b>. ``` Here we caught every `${...}` insertion and wrapped it in `<b>...</b>`. A formatter is just as easy: ```javascript function format(strings, ...values) { return strings.reduce( (res, str, i) => res + str + (values[i] !== undefined ? `[${values[i]}]` : ''), '' ); } const a = 10, b = 20; console.log(format`Sum of ${a} and ${b} is ${a + b}`); // Sum of [10] and [20] is [30] ``` ### XSS protection: safe HTML The most useful scenario: the tag escapes everything that came from outside, so the markup stays safe. ```javascript function safeHTML(strings, ...values) { const escape = str => String(str) .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>'); return strings.reduce( (res, str, i) => res + str + (values[i] ? escape(values[i]) : ''), '' ); } const userInput = '<script>alert("Hacked!")</script>'; const html = safeHTML`<div>User says: ${userInput}</div>`; console.log(html); // <div>User says: <script>alert("Hacked!")</script></div> ``` Thanks to the tag the HTML stays safe, with no foreign script execution. Crucially, only the values are escaped; the static template text written by the developer is left untouched. ### Real world uses 1. **Styled Components (React)** ```javascript const Button = styled.button` background: ${props => props.primary ? 'blue' : 'gray'}; color: white; `; ``` Here `styled.button` is a tag function that receives the template and builds CSS from it. 2. **GraphQL queries** ```javascript const query = gql` query GetUser { user(id: 1) { name } } `; ``` The `gql` tag parses the query text into an AST before it is ever sent to the server. 3. **Internationalisation (i18n)** ```javascript translate`Welcome, ${userName}!`; ``` The tag looks the translation up by the static part and injects the values into it. ### Comparison with a plain template literal | Feature | Plain template literal | Tagged template literal | | --- | --- | --- | | Syntax | `` `Hello, ${name}` `` | `` tag`Hello, ${name}` `` | | Substitutions | Inserted automatically | Handled manually inside the tag | | Flexibility | Interpolation only | Can filter, format, escape | | Result | Always a string | Whatever the tag returns | | Used for | Simple strings | Templating, security, CSS-in-JS, SQL, i18n | Summary: | Question | Answer | | --- | --- | | What it is | A template literal preceded by a tag function that receives the string parts and the values | | Why it exists | To control how the `${}` insertions are joined and interpreted | | Where it is used | Safe HTML, CSS-in-JS, formatting, internationalisation | | Key parameters | `strings` (template parts), `values` (injected values) | ### Common mistakes 1. **Adding parentheses after the tag.** `tag(`Hello ${name}`)` is an ordinary call with an already joined string; a tagged template is written without parentheses, straight after the function name. 2. **Expecting the tag to receive a finished string.** The first argument is the array of parts and the rest arrive through rest parameters; joining them is the function's job. 3. **Getting the counts wrong.** `strings` always has one element more than `values`, so a naive loop over `values` drops the final chunk of text. 4. **Escaping the wrong thing.** Escape the values, not the whole result: running the static template HTML through the escaper turns the markup into plain text. 5. **Forgetting `strings.raw`.** The normal array holds processed escape sequences, while `strings.raw` gives the raw text; that is exactly what `String.raw` is built on. 6. **Assuming a tag must return a string.** A tag can return an object, a function or an AST, which is what `gql` and CSS-in-JS libraries do.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.