Interfaces HTML personnalisées
Introduction
La classe Ui permet d’afficher des dialogues simples, mais elle reste limitée. Pour créer de véritables interfaces dynamiques, Apps Script propose HtmlService. Ce service permet d’intégrer des pages complètes en HTML, CSS et JavaScript dans Google Workspace ou sous forme d’application web autonome.
Grâce à lui, il devient possible d’afficher des données issues de Sheets, de construire des formulaires interactifs avec validation, ou encore d’utiliser des bibliothèques externes pour enrichir l’expérience. HtmlService transforme ainsi un script en une petite application web intégrée à l’écosystème Google.
Découverte du service HTML
Ce service se distingue des autres services d’Apps Script par la liberté qu’il offre. Là où la classe Ui se limite à des dialogues simples, et où CardService sert à construire des interfaces d’extensions Google Workspace sous forme de cartes avec des composants et une structure prédéfinis, le service HTML permet de créer une interface comme sur n’importe quel site web, avec HTML, CSS et JavaScript.
Un projet peut contenir plusieurs fichiers HTML, ensuite affichés dans une sidebar, une boîte de dialogue ou diffusés en tant qu’application web accessible par URL.
1. Créer un fichier HTML dans Apps Script
La première étape consiste à ajouter un fichier HTML dans le projet.
Reprenez l’exemple du générateur de factures et ajoutez un fichier HTML en cliquant sur « + » puis en sélectionnant « HTML ».

Ce fichier peut inclure du code HTML, du CSS et du JavaScript côté client, comme pour une page web classique. Il est rendu en HTML5, mais certaines fonctionnalités avancées de la norme ne sont pas prises en charge en raison des restrictions de l’environnement Apps Script.
En effet, l’interface est exécutée dans un sandbox en mode IFRAME, ce qui limite certaines interactions avec le contexte de navigation du navigateur et impose quelques contraintes sur le code côté client.

Une fois créé, le fichier HTML peut être rendu visible de différentes manières selon le besoin. Dans un projet lié à Google Sheets (ou à Docs, Slides et Forms), il peut être affiché dans une sidebar, pratique pour conserver une interface persistante sur le côté, ou bien dans une boîte de dialogue modale qui bloque l’interaction avec le document tant qu’elle reste ouverte.
Il existe aussi les dialogues modeless, qui restent flottants au-dessus du document sans en bloquer l’usage.
Ces différents modes d’affichage permettent d’adapter l’expérience utilisateur : une sidebar convient à des outils ou formulaires à utiliser en parallèle du document, alors qu’une boîte de dialogue modale est mieux adaptée...
Côté serveur et côté client
Lorsqu’une page HTML est diffusée avec HtmlService, deux environnements distincts cohabitent :
-
Le côté serveur, qui correspond au code Apps Script exécuté dans le cloud, avec accès aux services Google (Sheets, Drive, Gmail, etc.).
-
Le côté client, qui correspond au code JavaScript inclus dans la page HTML, et qui est exécuté directement dans le navigateur de l’utilisateur.
On pourrait comparer cela au front et au back d’une application web. Il est important de garder cette notion en tête lorsque l’on développe des applications web ou toute autre interface en HTML.
Nous allons voir dans ce chapitre comment ces deux mondes communiquent.
1. Interaction client/serveur avec google.script.run
Dans l’exemple du générateur de factures, on peut imaginer une modale contenant un simple bouton. Au clic, celui-ci déclenche une fonction côté serveur qui compte le nombre de factures déjà créées, puis renvoie le résultat pour l’afficher directement dans la modale.
Pour cela, ajoutez deux fonctions au Code.gs. Une pour compter le nombre de feuilles dont le nom commence par « Invoice » et une autre qui affiche la boîte de dialogue.
function getInvoiceCount() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheets = ss.getSheets();
const invoiceSheets = sheets.filter(sheet => sheet.getName().startsWith("Invoice"));
return invoiceSheets.length;
}
function openInvoiceDialog() {
const html = HtmlService.createHtmlOutputFromFile('InvoiceDialog')
.setWidth(300)
.setHeight(200);
SpreadsheetApp.getUi().showModalDialog(html, 'Invoices');
}
Ensuite, ajoutez un nouveau fichier HTML, « InvoiceDialog ».
<!-- InvoiceDialog.html -->
<!DOCTYPE html>
<html>
<body>
<button onclick="checkInvoices()">Check invoices</button> ...Templating
Jusqu’ici, les pages HTML créées avec HtmlService étaient statiques, ou bien enrichies grâce à des appels asynchrones avec google.script.run. Mais il existe un autre mécanisme qui permet d’injecter des données dès le rendu initial de la page : les templates et leurs balises spéciales, appelées scriptlets. Ces scriptlets agissent comme des balises dans lesquelles on peut injecter du code qui fonctionnerait dans un fichier Apps Script normal.
Un HtmlTemplate permet de mélanger du HTML et du code Apps Script. Le code est évalué côté serveur avant que la page ne soit envoyée au client. En d’autres termes, le HTML généré est déjà complet au moment où le navigateur l’affiche, sans appel supplémentaire. Ce principe est très proche de ce que l’on trouve dans d’autres langages côté serveur comme PHP ou JSP.
1. Utiliser HtmlTemplate et les scriptlets
Au lieu de créer un HtmlOutput classique, on crée un HtmlTemplate avec :
function doGet() {
return HtmlService
.createTemplateFromFile('Index')
.evaluate();
}
La méthode evaluate() exécute tous les scriptlets du fichier HTML et renvoie le résultat sous forme de HtmlOutput. Examinons d’un peu plus près les scriptlets.
Un fichier HTML peut contenir trois types de scriptlets différents :
-
Scriptlets standards <? ... ?>
Ils exécutent du code Apps Script mais n’affichent rien directement. En revanche, le résultat du code à l’intérieur du scriptlet peut toujours affecter le contenu HTML.
Voyons un exemple :
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<? if (true) { ?>
<p>This will always be served!</p>
<? } else { ?>
<p>This will never be served.</p> ...