"Unterminated template literal" syntax error when literal contains script tag

31,022

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.

Share:
31,022
Michael
Author by

Michael

Being an engineer with a vision is a curse. You see the world as it should be, and you have just enough skill and ability to delude yourself into thinking you can fix things, make them better, and bring about a better order. Problem is, nobody cares about doing things right. You'll never have fast and reliable because people are cheap. As a result I waste my spare time wrestling with problems that should not be hard. I spend an entire weekend trying to get code to work that's more important than anything I could ever achieve at my job during the week. I'm not an engineer because I enjoy or even find fulfillment in solving problems. I want to set things right, but my private struggle is that succeeding in solving a difficult problem is an embarrassment, a shame for all the time wasted fighting things not directly relevant to the task at hand. I'm an engineer because my mind commands me, drives me to fight against the subtle evil in the world, and I must either obey or give up my mind. What is subtle evil? Things like the fact that one cannot simply develop once and have code that will run equally well on a desktop computer or a mobile platform. That mobile platforms are second class citizens in the computing world when in fact they are just as Turing Complete. Steve Jobs once said - to paraphrase - that it was more important to start with what makes life easier for the user and work backwards. I disagree. Start with what makes life easier for the developer by virtue of the fundamentals sitting right, and let everything flow from that. You can't build a skyscraper starting with the penthouse.

Updated on March 23, 2020

Comments

  • Michael
    Michael about 4 years

    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?

  • Michael
    Michael about 8 years
    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!
  • Eric Hepperle - CodeSlayer2010
    Eric Hepperle - CodeSlayer2010 over 5 years
    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.
  • adelriosantiago
    adelriosantiago over 4 years
    Oh. I was thinking I found a major bug in ES6 template literals...
  • xgqfrms
    xgqfrms over 2 years
    you can fix that by using a self close tag js const url = 'https://file.js'; document.body.insertAdjacentHTML('beforeend', `<script src="${url}" />`);