There was a case where I wanted to build a lightweight app or tool that used a spreadsheet as its database by publishing a Google Apps Script web application.
It was too small to justify deploying to S3 or another hosting platform, but editing the spreadsheet directly was also not ideal. In that kind of situation, this approach lets you build a web app with Svelte, React, or Vue.
Repository
svelte-with-tailwindcss-on-gas
It is set up so you can use GitHub’s template repository feature.
If you do not need TailwindCSS, you can remove it without any problem.
Tech stack
Directory structure
The client directory is the layer that contains the frontend implementation created with Svelte.
The server directory contains the server-side implementation that runs on GAS.
src/├── client/│ ├── api/│ │ ├── mocks│ │ └── index.ts│ ├── components│ ├── features│ ├── stores│ ├── types│ ├── utils│ ├── App.svelte│ └── main.ts├── server/│ ├── main.ts│ └── types.ts└── vite-env.d.tsServer side
Use the GAS web app feature to serve HTML
Add a doGet function in server/main.ts.
Even if you change the title tag or favicon in the frontend, those changes are not reflected, so if you need them, set them in doGet.
const HTML_TITLE = "App name";const HTML_FAVICON_URL = "https://example.com/favicon.ico";
function doGet() { const html = HtmlService.createTemplateFromFile("index.html").evaluate(); html.setTitle(HTML_TITLE); html.setFaviconUrl(HTML_FAVICON_URL); return html;}Create API endpoints
In server/main.ts, you only need to export the functions you want to expose as endpoints.
type APIResult<T> = | { ok: true; data: T; } | { ok: false; error: Error; };
const doSomething = (): APIResult<string> => { return { ok: true, data: "success", };};
export { doSomething };Frontend
Bind to the server-side API in src/client/api/index.ts.
Internally, this uses google.script.run.
import { GASClient } from "gas-client";import type * as Server from "../../server/main";
const { serverFunctions } = new GASClient<typeof Server>();
export const APIClient = serverFunctions;Call the server-side API
<script lang="ts"> import { APIClient } from "./api";
const promise = APIClient.doSomething();</script>
{#await promise}<div>Loading...</div>{:then result}<p>{result}</p>{:catch error}<p>error</p>{/await}Summary
By combining Google Apps Script with Svelte, you can build a capable web app that uses a spreadsheet as the backend.
With gas-client, you can call GAS functions in a type-safe way, which also makes the developer experience much better.
hsb.horse