Deploy as a web app
A script with a doGet(e) or doPost(e) function can be deployed as a web app (Deploy, New deployment, Web app) and gets a URL. doGet returns HtmlService.createHtmlOutput(...) for a page or ContentService.createTextOutput(JSON.stringify(obj)).setMimeType(ContentService.MimeType.JSON) for an API; e.parameter holds query parameters and e.postData.contents the POST body. Each code change needs a new deployment version.
Syntax
function doGet(e) { return ContentService.createTextOutput(text); } | function doPost(e) { const body = JSON.parse(e.postData.contents); }| Part | What it is |
|---|---|
e.parameter | Object of query string parameters, for example e.parameter.id |
e.postData.contents | Raw POST body as a string |
Execute as | Me (script runs with your permissions) or User accessing the web app |
Who has access | Only myself, anyone in the domain, or Anyone (needed for public forms and webhooks) |
Examples
function doGet(e) {
const sheet = SpreadsheetApp.openById("1AbC...xyz").getSheetByName("Prices");
const rows = sheet.getDataRange().getValues();
const headers = rows.shift();
const data = rows.map(r => Object.fromEntries(headers.map((h, i) => [h, r[i]])));
return ContentService.createTextOutput(JSON.stringify(data)).setMimeType(ContentService.MimeType.JSON);
}Result: Opening the web app URL returns the sheet as JSON: [{"item":"Pens","price":2.5}, ...]
function doPost(e) {
const body = JSON.parse(e.postData.contents);
SpreadsheetApp.openById("1AbC...xyz").getSheetByName("Leads").appendRow([new Date(), body.name, body.email]);
return ContentService.createTextOutput(JSON.stringify({ok: true})).setMimeType(ContentService.MimeType.JSON);
}Result: A POST with {"name":"Ana","email":"ana@x.com"} adds a row and gets {"ok":true} back
function doGet(e) {
const name = e.parameter.name || "there";
return HtmlService.createHtmlOutput("<h1>Hello " + name + "</h1>");
}Result: URL?name=Ana shows a page with Hello Ana
Common mistakes
- The web app still runs the old code: you saved but did not deploy; create a new version under Deploy, Manage deployments, Edit, Version: New.
- Script function not found: doGet: the function is missing or misspelled; a web app needs doGet for browser visits and doPost for POST requests.
- External callers get a login page: access is set to Only myself or domain users; for webhooks and public forms set Who has access to Anyone.
- doPost receives e.postData undefined: the request was sent as GET or with no body; check the method and content type on the client.
Practice Deploy as a web app
These drills check your answer on live data, free, no account needed.
- Parse a query stringParse a URL query string such as `"?page=2&tag=js&tag=web"` into an object of strings. The leading `?` is optional. `+` means a space and `%XX` escapes are decoded. A key without `=` gets `""`. Only the first `=` separates key from value. Empty pieces (as in `a=1&&b=2`) are skipped. A key that appears more than once maps to an array of its values in order.
- CSV text to objectsParse simple CSV text (no quoted fields) into an array of objects. The first non-blank line holds the headers. Lines end with `\n` or `\r\n`, and blank lines are skipped. Headers and values are trimmed of surrounding spaces and stay strings. A row with fewer values than headers gets `""` for the missing ones.
- Pick some keysReturn a new object with only the listed `keys` of `obj`. Skip keys that `obj` does not have, but keep keys it has even when the value is `0`, `false`, `null`, `""` or `undefined`. Do not change `obj`.
Questions
Is the test deployment URL different from the real one?
Yes. The /dev URL always runs the latest saved code and only works for you; the /exec URL runs the deployed version and is the one to share.
Can doPost return a redirect or set CORS headers?
No custom headers. Web apps already respond with permissive CORS for simple requests; for redirects, return HTML with a meta refresh or a script that changes window.top.location.
Related
- UrlFetchAppCall APIs from Google Apps Script with UrlFetchApp.fetch: GET and POST requests, headers and bearer tokens, JSON payloads, muteHttpExceptions, to a sheet.
- JSON.parse and JSON.stringifyUse JSON.parse and JSON.stringify in Google Apps Script: turn an API response into objects, write nested fields to a sheet, store objects as properties.
- appendRowAdd a row to a Google Sheet with Apps Script: appendRow for a single row after the last row with data, and setValues for many rows at once, with examples.
- Dialogs, prompts and sidebarsShow dialogs in Google Sheets with Apps Script: ui.alert for messages, ui.prompt for text input, Yes No buttons, and HtmlService dialogs and sidebars.
Previous: try, catch and finallyNext: map, filter and reduce