42

I'm using ES6 template literals to construct some HTML in strings, and so far it has been working fine. However, as soon as I try to put the literal text </script> in my string the browser throws up and throws the syntax error:

SyntaxError: Unterminated template literal

Here is a simple JavaScript sample which throws the error:

var str=`
<script>
</script>
`
var pre = document.createElement('pre')
pre.textContent = str
document.body.appendChild(pre)

See the above code in JS Fiddle.

It appears that what is happening is that it gives up looking for the end literal quote and instead starts treating everything at point as literal HTML, so all the JavaScript after that point is incorrectly treated as HTML, which it is not!

If I replace script by any other legal HTML tag (and even invalid tags like scripty) then it works just fine, so I can't see how this can possibly be a syntax error or a weird case where I think I have typed one character (e.g. the backtick) but instead have typed another that looks almost like it.

I am literally creating a string (to my understand, at compile time), the browser should not be attempting to treat it as HTML or in any way parse it. So what gives?

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
Michael
  • 9,060
  • 14
  • 61
  • 123

1 Answers1

90

If you insert </script> inside a script tag, no matter if it's a string in quotes, apostrophes, or even a template literal, it will always close the script tag. You have to escape it, for example like that:

var str=`
<script>
<\/script>
`
var pre = document.createElement('pre')
pre.textContent = str
document.body.appendChild(pre)

However, if you use external script <script src="url"></script>, it should work fine without escaping.

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
  • 1
    Ah.... for some reason (such as the fact that I can freely put other kinds of quotes inside template quotes) I was thinking that anything inside the template quotes was isolated from the rest of the document. That indeed fixes it! – Michael Apr 13 '16 at 19:37
  • Thank you so much! I didn't know this was what was causing my error, but when I came across your post I was able to get my HTML ES6 template literal to print properly by escaping every close tag. – Eric Hepperle - CodeSlayer2010 Dec 06 '18 at 18:37
  • Oh. I was thinking I found a major bug in ES6 template literals... – adelriosantiago Dec 21 '19 at 23:37
  • you can fix that by using a self close tag ```js const url = 'https://file.js'; document.body.insertAdjacentHTML('beforeend', ``); ``` – xgqfrms Nov 22 '21 at 08:16