html template: how to display?

Hello,
I was following another observable post to create a table using html tagged literals, but for a demo, I tried something simpler

tb = `<table><tr><td>1</td><td>2</td></tr></table>`
const tbfinal = html`${tb}`;
display(tbfinal)

Yet this displays the html code (image attached) rather than rendering the table. This also

```html
${tbfinal}

produces the same output.

What am I missing here?
Thanks much in advance

Same answer as in Triggering a computation (SQL calls cells that depend on a select input somewhere else) - #8 by Fil

The html template literal escapes tags, by design; see GitHub - observablehq/htl: A tagged template literal that allows safe interpolation of values into HTML, following the HTML5 spec for explanations.

The proper way to create html tags is to use html`` at every step. If you create strings with `<some>code`, they become inert strings and can’t be (safely) made into html again.

If you really must do it the unsafe way, you can just use innerHTML:

const div = document.createElement("div");
div.innerHTML = `<some>code`

Alternatively html can be called like this:

html({raw: [ "<b>hello world" ]})

Here, on Hypertext Literal / Observable | Observable there is an example

html`<table style="width: 180px;">
  <thead><tr><th>#</th><th>Color</th><th>Swatch</th></tr></thead>
  <tbody>${d3.schemeCategory10.map((color, i) => html.fragment`<tr>
    <td>${i}</td>
    <td>${color}</td>
    <td style=${{background: color}}></td>
  </tr>`)}</tbody>
</table>`

Isn’t this similar to my example and is displayed as expected

Regards
Saptarshi

The difference is that in your example you’re interpolating the markup.

html`${"<div>foo"}`

is not the same as

html`<div>foo`

The tag function receives a list of strings and interpolated values and escapes any interpolated value (unless it’s already a DOM element or node).

Ohhh!, thank you for the clarification!

Thank you
Saptarshi