21
votes

If I create a simple HTML web app in Google Apps Script, like this:

function doGet() {
    return HtmlService.createHtmlOutputFromFile("index.html");
}

and index.html looks like this:

<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<div>Test</div>

is it possible to add JS and CSS files as part of the project and include them using script and link tags, or do they have to be inline/hosted elsewhere?

5
Not exactly what you were asking for, but a possible workaround: the google.script API - developers.google.com/apps-script/html_service#GoogleScriptAPITomTasche
I ran across this issue recently. Good find hereqodeninja

5 Answers

54
votes

Here is a workaround I have found useful:

  1. Add this function to your server-side Javascript:

    function getContent(filename) {
        return HtmlService.createTemplateFromFile(filename).getRawContent();
    }
    
  2. Add a second 'html' file to your project that contains only the JS or CSS surrounded by <script> or <style> tags as appropriate.

    <!-- myscript.js.html -->
    <script>
        alert("Script included!");
    </script>
    
  3. Now you can include the script in your main HTML template like this:

    <?!= getContent("myscript.js") ?>
    

This way, you can have your JS and CSS split into as many files as you like and keep them all accessible from within the Apps Script project.

7
votes

Google provides a similar solution here.

Basically, they suggest you add this function to your .gs file:

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .getContent();
}

and add one or both of these to your .html file:

<?!= include('Stylesheet'); ?>
<?!= include('JavaScript'); ?>

the names in quotes of course referring to separate .html files containing your JS or CSS code with <script> or <style> tags.

3
votes

For now, it is not doable to have your CSS and JS script to be part of your Google Apps Script project. You will have to host it somewhere else and point the URL in your template.

3
votes

You can't have simple js or css files in the project so what you do instead is create html files that contain it, and preferably you place the < script>< /script> or < style> inside those files.

So you might have a file a file named myscript.js.html with the following content:

<script>
  alert ("Hello World!");
</script>

Now you put this line in the html where you want the asset to be included

Put this in the html where you want to include the asset:

<?= HtmlService.createHtmlOutputFromFile('myscript.js').getContent() ?>

Notice that the ".html" in the filename is omitted.

If you're going to include a number of assets it might be a good idea to make a helper-function. You can put the following function in your code (gs-file)

function include(filename) {
    return HtmlService.createTemplateFromFile(filename).getRawContent();
}

Then the line above can be changed to:

<?!= include('myscript.js') ?>

Finally, you also need to call the evaluate()-method of the HTMLTemplate or else the code inside <?!= ?> in the html file wont be evaluated. So if you're serving the html file like this for instance:

var html=HtmlService.createTemplateFromFile('repeatDialog');
SpreadsheetApp.getUi().showModalDialog(html, 'foo');

You simply need to change it to:

var html=HtmlService.createTemplateFromFile('repeatDialog').evaluate();
SpreadsheetApp.getUi().showModalDialog(html, 'foo');

If you were using createHtmlOutputFromFile and not createTemplateFromFile before then you should know that evaluate() returns htmlOutput so if you're wondering where to put things like .setWidth() then it's after the evaluate() call.

2
votes

You can directly render a file inside a scriptlet tag.

<?!= HtmlService.createTemplateFromFile("example.js").getRawContent() ?>

Create the example.js.html file in your apps script project. While rendering in the scriptlet tag do not mention the extension ".html"