You could use PHP's json_encode:
<script type="application/javascript">
  const str = <?=json_encode($str)?>;
</script>
This will return a JSON representation of your String, meaning that:
- it will be wrapped with double quotes
- escape double quotes which might be in the String itself
- escape Unicode characters
With this code alone (const str = ...), there is absolutely zero risk of XSS. The String is safe by itself, and can be manipulated by JS.
However, it can become an XSS hazard if you use that String like this:
- eval(str);for obvious reasons
- elem.innerHTML = str;for example if- str === '<button onclick="sendCookiesToEvilServer()">Click me</button>', or- '<style>body { display: none; }</style>'
- ... that list is not exhaustive
If you want to display that String to the user, prefer .innerText to .innerHTML, or maybe look at strip_tags.
If you do need to use innerHTML because the string is allowed to contain some HTML, you need to properly sanitize it against XSS. And it's a little harder, because then, you need a parser to allow/remove only some HTML tags and/or attributes. strip_tags will allow you to do so to a certain extent (i.e. you could only allow <b> for example, but that won't prevent that <b> from having an attribute onclick="...").