Skip to the content.

Template Literal Sanitization with Named or Tagged Template Literals

This article describes the high level goals and usage of an custom function ‘html’ that sanitizes JavaScript template literals.

Goals

The ‘html’ and ‘createElement’ functions are a strong foundation for working with custom elements with minimal amount of helper code. This article discusses my ‘html’ tagged template literal function.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

Breakdown of the ‘html’ in templateLit()

  export class myComponent extends HTMLElement {
    
    connectedCallback(){
      const frag = this.templateLit()
      const submit = frag.queryselector('button')
      submit.addeventListener('click', submitEventHandler)
      this.append(frag); // append to the DOM after you have event handlers and other work complete.
    }
    
    templateLit(){
      retrun html`<div>${user_input}`
     }
    
  }

Because of various reporting reasons I’m not going to post my html function, but if you follow the link to MDN and do the following things you can build your own.

Main Features of my html function

Before you return you can do extra work like:

How to create a document fragment

Known issue

Table related elements are different, instead of using a div to add the sanitized string, I use the ‘table’ element.

For tables I export a slightly different function ‘htmlTable’ vs ‘html’. Everything is the same, except a table element is created vs. a div.

Character clean up

I’ve done both the regex way to clean up data and I have used createTextNode. CreateTextNode is a bit more code, and does the same thing.

Disadvantage of this approach

Cannot nest html via html<div>${childHtmlString}</div>.

This hasn’t been an issue for me. I have several work arounds. Either a separate component, or a separate template in the same component.

Workaround As separate component

html`<div><child-component></child-component></div>

Workaround as separate template literal and append where needed before painting to the DOM

  const frag = this.templateLit()
  const childLocation = frag.querySelectort('something')
  // treat is just like the parent and append it where it is needed.
  childLocation.append(this.templateLitSomeChildHTML());