"Lit-html" first time: unsafeHTML vs. templateContent vs. eval

āđāļĄāļ·āđāļāļŠāļāļāļ§āļąāļāļāđāļāļāđāļāļīāđāļāđāļāđāļāļđāļĢāļēāļĒāļĨāļ°āđāļāļĩāļĒāļ Lit āļāļķāđāļāđāļāđāļāđāļāļĢāđāļāļāļāđāļāļĩāđāļāļģāđāļŠāļāļāđāļāļ§āļāļēāļāļāļąāļāļāļē Web Components āļāļķāđāļāļāļđāđāļĨāđāļ§āļāđāļēāļĒāļāļ§āđāļē polymer āļāļĩāđāļŦāļĒāļļāļāļāļąāļāļāļēāđāļĨāđāļ§āđāļĨāļ°āđāļāļ°āļāļģāđāļŦāđāļĒāđāļēāļĒāļĄāļēāđāļāđ Lit (āļāļąāđāļāļāļđāđāđāļāđāļāđāļāļĢāđāļāļāļāđāļāļāļ Google) āđāļĄāđāļĢāļđāđāļ§āđāļēāļāļĄāđāļāļāļĒāļđāđāđāļŦāļāļāļķāļāđāļĄāđāđāļāđāļāļēāļĄāļāđāļēāļ§āļāļĢāļēāļ§āđāļĨāļĒ āļāļāļāļāļāļāļĩāđāļāļāļ version 3 āļĄāļēāđāļĨāđāļ§
āļāļ§āļēāļĄāļāļĢāļ°āļāļąāļāđāļāđāļĢāļ āļāļĢāļąāļāļāļēāļāļ§āļēāļĄāđāļĢāļĩāļĒāļāļāđāļēāļĒ āļĨāļ°āļāļīāđāļāļāļīāļāļĩāļāļĢāļĢāļĄāļāļĩāđāļāđāļāļāļāļķāđāļāđāļāļĢāđāļāļāļāđāļāđāļ§āļĒāļāļēāļĢāļāļīāļāļāļąāđāļ build tools āļĄāļēāļāļĄāļēāļĒāļāļēāļĄāļĒāļļāļāļŠāļĄāļąāļĒ āļŠāļēāļĄāļēāļĢāļāđāļĢāļīāđāļĄāļāļāļĨāļāļāđāļāļĩāļĒāļāđāļāđāļāļāđāļ§āļĒāļāļēāļĢāļŠāļĢāđāļēāļāđāļāļĨāđ HTML āđāļāļĨāđāđāļāļĩāļĒāļ§ āđāļāļīāļāļāļđāļāļēāļ browser āđāļĄāđāļāđāļāļāļĄāļĩāđāļĄāđāļāļĢāļ°āļāļąāđāļ Live Server
āđāļāđāļāļĢāļąāļ! āđāļĢāļīāđāļĄāļāđāļāļāđāļēāļĒāđāļāđāļāļĩāđāđāļāļ āđāļŦāļĄāļ·āļāļāļāļĢāļąāđāļāļŦāļāļķāđāļāļāļĩāđāđāļĢāļēāđāļāđāđāļāđ notepad āļāđāļĨāļāļāđāļāļĩāļĒāļāđāļ§āđāļāđāļāđ
āļŦāļĨāļąāļāļāļēāļāļāļĩāđāļŠāļģāļĢāļ§āļāļāđāļāļĄāļđāļĨāļāļĢāđāļēāļ§ āđ āļāļāļ§āđāļē āđāļāđāļāļŠāļģāļāļąāļāļāļāļ lit āļāļĒāļđāđāļāļĩāđāļāļēāļĢāđāļāđāļāļĢāļ°āđāļĒāļāļāđāļāļēāļāļĄāļēāļāļĢāļāļēāļ JavaScript ES6 (2015) Template Literal āđāļāļīāđāļĄ htmlāđāļāđāļēāļĄāļēāļāļģāđāļŦāđāļāļēāļĢāđāļāļĩāļĒāļāđāļāđāļāļāļĩāđāļĄāļĩ HTML syntax āļŠāļēāļĄāļēāļĢāļāļāļģāđāļāđāļ āļēāļĒāđāļāđāļāļĨāđ .js āđāļāļĒāđāļĄāđāļāđāļāļ compile āļŦāļĢāļ·āļāđāļāđ build tools
const content = html`<h1>Hello ${name || "World"}</h1>`;
āļāļĩāđāļŠāļģāļāļąāļāļāļ§āđāļēāļāļąāđāļ html template āļŠāļēāļĄāļēāļĢāļāļāļģāļĄāļēāđāļāđāļāļąāļāđāļāđāļāļāļąāđāļ§āđāļ āđāļāļĒāđāļĄāđāļāļģāđāļāđāļāļāđāļāļāļāļđāļāļāļĒāļđāđāđāļ LitElement āđāļāđāļēāļāļąāđāļ āļĄāļĩ monorepo lit-html āđāļĒāļāļāļāļāļĄāļēāđāļāđāļ standalone package
āļāļĢāļ°āđāļāđāļāļāļĩāđāļāļĄāļŠāļāđāļāđāļĨāļ°āļāļĒāļēāļĒāļēāļĄāļŦāļēāļĄāļēāļāļĨāļāļāļāļ·āļ āļāļ§āļēāļĄāļŠāļēāļĄāļēāļĢāļ embedded HTML āđāļāļĒāđāļĄāđāļāđāļāļ compile āđāļŦāļĄāđ āļāļķāđāļāļāļģāđāļŦāđāļŠāļēāļĄāļēāļĢāļāđāļĒāļāļāļēāļāļĢāļ°āļŦāļ§āđāļēāļ developer āļāļĩāđāļāļđāđāļĨāđāļāđāļāđāļāļĢāđāļāļĢāļĄ āļāļąāļ implementer āļāļĩāđ customize āļāļēāļāđāļŦāđāļāļąāļāđāļāļāđāļāđāļēāļ āđ āļāļĩāđāļāļđāđāļĨ
Single HTML with CDN
āđāļĢāļīāđāļĄāļāđāļāļāļēāļāļāļāļŠāļāļāđāļāļĩāļĒāļ HTML āđāļāļĨāđāđāļāļĩāļĒāļ§ āđāļĨāđāļ§āđāļāļīāļāđāļ browser āđāļāļĒāđāļĄāđāļāđāļāļāļĄāļĩ server āļŠāļēāļĄāļēāļĢāļ import package lit-html āļāļēāļ CDN āļĄāļĩāđāļŦāđāđāļĨāļ·āļāļāđāļāđ unpkg āļāļąāļ jsdelivr (minified)
āđāļāđ text editor āļŠāļĢāđāļēāļāđāļāļĨāđāđāļŦāļĄāđāļāļ·āđāļ lit-html.html
copy&paste āđāļāđāļāļāđāļēāļāļĨāđāļēāļ
save āđāļĨāđāļ§āđāļāļē path āļāļāļāđāļāļĨāđāđāļāđāļāļīāļāļāđāļ§āļĒ browser
<script type="module">
import {html, render} from 'https://unpkg.com/lit-html@3.1.2/lit-html.js';
render(html`<h1>Hello World</h1>`, document.body)
</script>
āļāļģāļŠāļąāđāļ html āđāļāđāļāļąāļ template literal āļāļąāļāļāļĩāđāļāļĨāđāļēāļ§āļĄāļēāđāļĨāđāļ§
āļŠāđāļ§āļāļāļģāļŠāļąāđāļ render āđāļāđāļŠāļģāļŦāļĢāļąāļāđāļāļēāļāļĨāļĨāļąāļāļāđāļāļēāļ html template āļāļąāđāļāđāļāđāļŠāđāđāļ HTML element <body> āđāļāļ·āđāļāđāļŠāļāļāļāļĨāđāļ browser

āļāđāļāđāļāļāļĄāļāļāļŠāļāļ render āđāļāļĒāļāļēāļĢāļŠāđāļāļāđāļāļāļ§āļēāļĄāļāļĩāđāđāļāđāļ text āļāļąāļāļāđāļāļāļ§āļēāļĄāļāļĩāđāļāđāļēāļ html template
āļĨāļāļāļŠāļąāļāđāļāļāļāļĨāļĨāļąāļāļāđāļāļĩāđāđāļāđ āļāļ°āđāļŦāđāļāļ§āđāļēāļāđāļāļāļ§āļēāļĄ text āđāļĄāđāļāļđāļāđāļāļĨāļāđāļāđāļ element
<!doctype html>
<html>
<!---->
<body>
<div id="text"></div>
<div id="html"></div>
</body>
<!---->
<script type="module">
import {html, render} from 'https://unpkg.com/lit-html@3.1.2/lit-html.js';
render(`<h1>Hello World</h1>`, document.querySelector('div#text'))
render(html`<h1>Hello World</h1>`, document.querySelector('div#html'))
</script>
</html>
unsafeHTML( text )
āļāļąāļ§ lit-html āđāļāļāļĄāļĩ built-in directive unsafeHTML āļŠāļēāļĄāļēāļĢāļāđāļāļĢāļ external HTML āđāļāđāļēāđāļāđāļāđ
āļŠāļĄāļĄāļāļīāļ§āđāļēāļĄāļĩ userdata āļāļķāđāļāļāļĢāļ°āļāļāļāļāđāļ§āļĒāļāļīāļĨāļāđ name, fullname āđāļĨāļ° profileHTML āļāļĩāđāđāļāđāļ embedded HTML āđāļāļ·āđāļāđāļāđāļāļāļŠāļāļ
āđāļāļīāđāļĄ import package unsafe-html
āđāļāļīāđāļĄ <div id="profile"></div>
āđāļāļīāđāļĄ render profileHTML

āļāļĨāļĨāļąāļāļāđāļāļēāļāđāļāđāļāļāļąāļ§āļāļĒāđāļēāļāļāđāļēāļāļĨāđāļēāļ āļāļ°āđāļŦāđāļāļ§āđāļē unsafeHTML āļĢāļāļāļĢāļąāļāđāļāļāļēāļ°āđāļāļĨāļ HTML text āđāļāđāļ element āđāļĄāđāļŠāļēāļĄāļēāļĢāļāđāļāđāļāļēāļ nested template āđāļāđ āđāļĄāđāļŠāļēāļĄāļēāļĢāļāđāļāļāļāļĩāđāļāđāļēāļāļĩāđāļāļĒāļđāđāđāļ ${}
<!doctype html>
<html>
<!---->
<body>
<div id="greet"></div>
<hr/>
<div id="profile" style="border:solid thin; padding:8px;"></div>
</body>
<!---->
<script type="module">
import {html, render} from 'https://unpkg.com/lit-html@3.1.2/lit-html.js';
import {unsafeHTML} from 'https://unpkg.com/lit-html@3.1.2/directives/unsafe-html.js';
const userdata = {
name: 'John',
fullname: 'John Doe',
profileHtml: [
'<p>',
' <b>Name:</b> ${userdata.name}<br/>',
' <b>Full Name:</b> ${userdata.fullname}<br/>',
'</p>',
].join('')
}
const greetHTML = _data => (html`
<h1>Hello ${_data?.name || 'World'}</h1>
`)
render(greetHTML(userdata), document.querySelector('div#greet'))
// profile
const profileHTML = _data => (html`
<h3>Profile</h3>
<div>${unsafeHTML(_data?.profileHtml)}</div>
`)
render(profileHTML(userdata), document.querySelector('div#profile'))
</script>
</html>
templateContent(elem)
āđāļāđ built-in directive templateContent āđāļāļāļāļĩāđāļāļ° embedded āđāļ§āđāđāļ text āđāļāļĨāļĩāđāļĒāļāđāļāđāļāđāļāļēāđāļ§āđāđāļ HTML element <template>..</template>āļāļĨāđāļēāļĒāļāļąāļāļāļĢāļāļĩāļāļāļ unsafeHTML āļāđāļāļāļŦāļāđāļēāļāļĩāđ
<template id="profile">
<p>
<b>Name:</b> ${userdata.name}<br/>
<b>Full Name:</b> ${userdata.fullname}<br/>
</p>
</template>
āļāļāđāļāļĩāļĒāļ template āļāđāļ§āļĒāđāļāļĢāļāļŠāļĢāđāļēāļ HTML āđāļāļāļāļĩāđ āļāļĄāļāļāļāļ°āļāļķāļāļāļķāļāļāļēāļāđāļĨāļ·āļāļāļāļĩāđāļāļēāļāđāļāđāđāļāļāļēāļĢāļāļąāļāļāļēāđāļāđāļĄāļēāļāļāļķāđāļ āđāļāđāļāđāļēāđāļŠāļĩāļĒāļāļēāļĒāļāļĨāļĨāļąāļāļāđāļāļĩāđāđāļāđāļāđāđāļĄāđāļāđāļēāļāļāļąāļ āļŠāļēāļĄāļēāļĢāļāđāļāļē element āļāļĩāđāļŠāļĢāđāļēāļāđāļ§āđāđāļ <template> āļĄāļēāđāļāđāđāļāđ āđāļāđāđāļĄāđāļŠāļēāļĄāļēāļĢāļāļāļĢāļ°āļĄāļ§āļĨāļāļĨāđāļāļāļāđāļē ${..}

<!doctype html>
<html>
<!---->
<body>
<div id="greet"></div>
<hr/>
<div id="profile" style="border:solid thin; padding:8px;"></div>
<template id="profile">
<p>
<b>Name:</b> ${userdata.name}<br/>
<b>Full Name:</b> ${userdata.fullname}<br/>
</p>
</template>
</body>
<!---->
<script type="module">
import {html, render} from 'https://unpkg.com/lit-html@3.1.2/lit-html.js';
import {templateContent} from 'https://unpkg.com/lit-html@3.1.2/directives/template-content.js';
const userdata = {
name: 'John',
fullname: 'John Doe',
}
const greetHTML = _data => (html`
<h1>Hello ${_data?.name || 'World'}</h1>
`)
render(greetHTML(userdata), document.querySelector('div#greet'))
// profile
const profileHTML = _data => (html`
<h3>Profile</h3>
<div>${templateContent(document.querySelector('template#profile'))}</div>
`)
render(profileHTML(userdata), document.querySelector('div#profile'))
</script>
</html>
eval( html`" + + `" )
āļĄāļĩāļāļģāļāļēāļĄāđāļ StackOverflow āđāļāļĩāđāļĒāļ§āļāļąāļāļāļēāļĢāđāļāđ external text āļāļąāļ Lit āđāļĨāļ°āļāļģāļāļāļāļŦāļāļķāđāļāļāļāļāļ§āđāļē āļŠāļēāļĄāļēāļĢāļāđāļāđ eval() āđāļāđ
// profile
const profileHTML = _data => (html`
<h3>Profile</h3>
<div>${eval("html`" + (_data?.profileHtml) + "`")}</div>
`)
āļāļēāļāļāļĩāđāļāđāļēāļāļĄāļēāļāļāļāļāļĄ āļĄāļĩāļāļēāļĢāđāļāđāļāļĢāļ°āđāļĒāļāļāđāļāļēāļ eval āļŦāļĨāļēāļĒāļāļĒāđāļēāļ āđāļāđāļ āļāļēāļĢāļāļāļāđāļāļāļāļāđāļāļĢāļ·āđāļāļāļāļīāļāđāļĨāļ āđāļĄāļ·āđāļāļāļđāđāđāļāđāļāļĩāļĒāđāļāļąāļ§āđāļĨāļ 10+2+3 āļāđāļŠāļēāļĄāļēāļĢāļāđāļĢāļĩāļĒāļāđāļāđ eval("10+2+3") āļāļģāļāļ§āļāļāļģāļāļāļāđāļāļĒāđāļĄāđāļāđāļāļāļāļģāļāļ°āđāļĢāļāļąāļāļāđāļāļ
āļāļĢāļāļĩāļāļāļ lit-html āļāđāļēāđāļāđ eval āđāļāđāļāđāļēāļāļ°āđāļāļīāļāđāļāļāļēāļŠāļāļāļāļāļ§āļēāļĄāđāļāđāļāđāļāđāļāđāļāļĩāļāļĄāļēāļāļĄāļēāļĒ

<!doctype html>
<html>
<!---->
<body>
<div id="greet"></div>
<hr/>
<div id="profile" style="border:solid thin; padding:8px;"></div>
</body>
<!---->
<script type="module">
import {html, render} from 'https://unpkg.com/lit-html@3.1.2/lit-html.js';
const userdata = {
name: 'John',
fullname: 'John Doe',
profileHtml: [
'<p>',
' <b>Name:</b> ${userdata.name}<br/>',
' <b>Full Name:</b> ${userdata.fullname}<br/>',
'</p>',
].join('')
}
const greetHTML = _data => (html`
<h1>Hello ${_data?.name || 'World'}</h1>
`)
render(greetHTML(userdata), document.querySelector('div#greet'))
// profile
const profileHTML = _data => (html`
<h3>Profile</h3>
<div>${eval("html`" + (_data?.profileHtml) + "`")}</div>
`)
render(profileHTML(userdata), document.querySelector('div#profile'))
</script>
</html>
innerHTML
āđāļĢāļēāļŠāļēāļĄāļēāļĢāļāđāļāđ eval āđāļāļĒāđāļāļē innerHTML āļāļāļ elem āļāļĩāđāļāļģāđāļ§āđāđāļ <template> āļĄāļēāđāļāđāđāļāđāđāļāđāļāļāļąāļ
// profile
const profileHTML = _data => (html`
<h3>Profile</h3>
<div>${eval("html`" + document.querySelector('template#profile').innerHTML + "`")}</div>
`)

<!doctype html>
<html>
<!---->
<body>
<div id="greet"></div>
<hr/>
<div id="profile" style="border:solid thin; padding:8px;"></div>
<template id="profile">
<p>
<b>Name:</b> ${userdata.name}<br/>
<b>Full Name:</b> ${userdata.fullname}<br/>
</p>
</template>
</body>
<!---->
<script type="module">
import {html, render} from 'https://unpkg.com/lit-html@3.1.2/lit-html.js';
const userdata = {
name: 'John',
fullname: 'John Doe',
}
const greetHTML = _data => (html`
<h1>Hello ${_data?.name || 'World'}</h1>
`)
render(greetHTML(userdata), document.querySelector('div#greet'))
// profile
const profileHTML = _data => (html`
<h3>Profile</h3>
<div>${eval("html`" + document.querySelector('template#profile').innerHTML + "`")}</div>
`)
render(profileHTML(userdata), document.querySelector('div#profile'))
</script>
</html>
Attention!
āļāļķāļāđāļĄāđāļ§āđāļē eval āļāļ°āđāļāđāļāļĢāļ°āđāļĒāļāļāđāđāļāđāđāļāļāļĢāļāļĩāļāļĩāđ āđāļāđāļāđāļāļ§āļĢāļĢāļ°āļ§āļąāļāļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒāļŦāļēāļāđāļĄāđāļŠāļēāļĄāļēāļĢāļāļāļ§āļāļāļļāļĄāļāļđāđāđāļāđāļēāļāļķāļāļŠāđāļ§āļ embedded code āđāļāļĢāļēāļ°āļŠāļēāļĄāļēāļĢāļāđāļāļĩāļĒāļāđāļāđāļāđāļŦāđāļāļ°āļĨāļļāļāđāļēāļ script āđāļ eval() āļĄāļēāđāļāđ āļāļēāļĄāļāļąāļ§āļāļĒāđāļēāļāļāđāļēāļāļāđāļ āļŠāļēāļĄāļēāļĢāļāđāļāđāļēāļāļķāļāļāļąāļ§āđāļāļĢ userdata āļāļĩāđāļāļĒāļđāđāđāļ global āđāļĨāļ° module scope āļĄāļēāđāļāđāļāļĢāļ āđ āļŦāļĄāļēāļĒāļāļ§āļēāļĄāļ§āđāļēāđāļĢāļēāļāļēāļāđāļāđāļēāđāļāđāļāļĨāļĩāđāļĒāļāļāđāļēāđāļāļāļąāđāļāđāļāđāđāļāđāļāļāļąāļ āļŦāļēāļāļāļģāđāļāđāļāļāđāļāļāđāļāđāļāļēāļāđāļ production āļāļĢāļīāļ āļāļēāļāļāļīāļāļēāļĢāļāļēāļāļāļāđāļāļāđāļŦāđāļĢāļąāļāļāļļāļĄāļāļ§āđāļēāļāļĩāđ āđāļāđāļ āđāļāđ scopedEval
āļāđāļēāļāļāļīāļ
Lit https://lit.dev/
Polymer https://polymer-library.polymer-project.org/
JavaScript ES6 (2015) Template Literal https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
lit-html standalone https://lit.dev/docs/libraries/standalone-templates/
Lit-ElementââHow to render template from an external text? https://stackoverflow.com/a/76290324
eval https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
scoped-eval https://github.com/3cp/scoped-eval


