You can pass HTML directly to your [[base/Google Apps Script/Google Apps Script|Google Apps Script]] [[web app]] by using `<?! = myHTMLvar?>` which will pass the HTML string and return it without "escaping" it. If you exclude the exclamation point, the string will be returned exactly as written, tags and all. This is because without the exclamation mark the browser escapes the HTML, making it not HTML anymore, just plain text. This is especially important if your user is providing input that is then passed to the script. If you do not escape the user input, you are allowing your user to run any HTML code they want on your server. Bad idea. However, you can pass unescaped HTML after you have escaped any user input.
Instead of passing the list as an array and then handle the rendering in the HTML, it might be cleaner to convert the data directly to HTML and passing that to the template.
In `Code.gs` use the map function to wrap the data in html tags and then join to collapse from an array to a string. Note you must use the `createTemplateFromFile` method to access these variables.
```JavaScript title="Code.gs"
function doGet(e){
var ss = SpreadsheetApp.openById(id);
var ws = ss.getSheetByName('data');
var list = ws.getDataRange().getValues();
var htmlListArray = list.map(function(r){ return '<li>' + r[0] + '</li>'; }).join('');
var tmp = HtmlService.createTemplateFromFile("index");
tmp.title = "Hello Bootstrap";
tmp.list = htmlListArray;
return tmp.evaluate();
}
```
In` index.html`, return the unescaped HTML.
```HTML title="index.html"
<body>
<h1>
<?= title; ?>
</h1>
<ul>
<?!= list ?>
</ul>
</body>
```
Note that this only works if everything will be loaded on initial load. You can't dynamically load content later since the template has already been executed.