Author: By Raj

Part of our Apps Script Web Apps guides. Need this built for your team? Hire a Google Apps Script developer.

Estimated reading time: 10 minutes

Google Apps Script HtmlService: Building UIs with HTML & JavaScript

HtmlService renders HTML, CSS, and client JavaScript served from Apps Script with special globals: google.script.run, google.script.host, and template <?!= include('Styles') ?> for partials.

Use createTemplateFromFile for dynamic server variables. setSandboxMode was deprecated, default IFRAME sandbox still applies security restrictions on client JS.

Mobile-friendly internal tools should use responsive CSS flexbox, not desktop-only table layouts wider than 900px.

Templates and includes

Split CSS to Styles.html and JS to Client.html. include() helper loads fragments without duplicate DOCTYPE.

Server variables: <?!= JSON.stringify(data) ?> for bootstrapping, escape carefully.

google.script.run patterns

withSuccessHandler and withFailureHandler required for UX, show spinners while awaiting server. Avoid calling run in tight loops; batch server calls.

Server functions must return serializable data, Dates become strings.

UI libraries and design

Bootstrap via CDN works if allowed; some orgs block external CSS. Inline critical styles for reliability.

Use Material-inspired components for familiarity; keep primary action buttons sticky on mobile.

Client-side limits

No direct SpreadsheetApp in browser JS. Long operations may hit google.script.run timeout, chunk server work.

HtmlService output size has practical limits; paginate large tables.

Example code

function saveRecord(record) {
  if (!record || !record.id) throw new Error('Invalid record');
  const sh = SpreadsheetApp.openById('SHEET_ID').getSheetByName('Data');
  sh.appendRow([record.id, record.name, new Date()]);
  return { ok: true };
}
ApproachBest forTradeoff
Apps Script nativeGoogle Workspace-centric workflows6-min limit, quotas
Zapier / MakeNo-code, many connectorsPer-task cost, vendor lock-in
Python + CloudHeavy data / MLHosting cost, separate auth
Apps Script web app developmentProduction custom logicBuild cost, you own code

FAQ

Can I use React in HtmlService?

Heavy SPAs are awkward due to sandbox and bundle size. Vanilla JS or lightweight Alpine-style often ships faster.

Why failureHandler shows ScriptError?

Server threw, check Executions for stack. Surface user-friendly message server-side with custom Error messages.

Can HtmlService call external APIs from browser?

CORS blocks most third-party calls from client, proxy via server UrlFetchApp instead.

setXFrameOptionsMode purpose?

ALLOWALL lets you iframe the app in intranet portals; default DENY protects clickjacking.

Link to doPost forms?

Html forms can POST to deployment URL, see /blog/apps-script-doget-dopost-explained.

Need this done for you? I handle this as part of my consulting work, fixed-price quote within 24 hours.

Book a call with Raj →

Get the full Google Apps Script HtmlService script template

I'll email you a production-ready, commented version you can deploy in 10 minutes.

Need help with this? I handle this as part of my Apps Script Web Apps service.

Internal tools, CRUD apps, HtmlService UIs, and Google SSO.

See how it works →