Here is an example of using GAS to replace the contents of the HTML body. Although I am using a spreadsheet as my basis, I believe it should work with a Web App. I add a <div> to the body so as not to disturb the <script> section.
Code.gs
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function showTest() {
let html = HtmlService.createTemplateFromFile("HTML_Body");
SpreadsheetApp.getUi().showModalDialog(html.evaluate(),"Test");
}
function getHtml(id) {
let fileName = id === "buttonA" ? "HTML_B" : "HTML_A";
let html = HtmlService.createHtmlOutputFromFile(fileName);
return html.getContent();
}
HTML_Body.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div id="htmlBody">
<?!= include("HTML_A"); ?>
</div>
<?!= include("JS_ButtonOnClick"); ?>
</body>
</html>
HTML_A.html
<p>This is A</p>
<input id="buttonA" type="button" value="Click Me" onclick="buttonOnClick(this)">
HTML_B.html
<p>This is B</p>
<input id="buttonB" type="button" value="Click Me" onclick="buttonOnClick(this)">
JS_ButtonOnClick
<script>
function buttonOnClick(button) {
try {
google.script.run.withSuccessHandler(
function(html) {
document.getElementById("htmlBody").innerHTML = html;
}
).getHtml(button.id);
}
catch(err) {
alert(err);
}
}
</script>
References
function include(filename) { return HtmlService.createHtmlOutputFromFile(filename).getContent(); }and then inside of the HTML code you slap in<?!= include('B'); ?>forB.htmlto simply have all the html files loaded up even when separated. Then just use css to hide elements and display them when the interaction is made to display them. That's how I did a menu for one of my scripts. 16 HTML files split between JS code, css and just plain webpage code