Save one email from a page that has no server.
A static page can remember a signup. The trick is to decide the shape of the row before you write the form, and to put only a public key in the browser.
1. Write the row down first
A waitlist needs almost nothing. Two fields cover the usual form:
email, a required string, unique so the same address does not fill the list twicename, an optional string
Keep the names in lowercase. Add a field only if the form actually collects it. Types you can expect from a simple table service are string, number, boolean, datetime, and json. If you need files or a private per-user history, stop. This tutorial is the wrong tool, and a page with no server is the wrong home for that data.
Apply the schema from a place that holds your account token: a CLI or a dashboard. Do this before the page tries to insert anything. A browser SDK that can create tables is a security bug. Visitors would be able to create tables.
2. Split the keys
You will be offered two values. Learn them apart before you touch the HTML.
- The account token deploys and changes schema. It stays in your terminal or in an environment variable. Search the project afterward and make sure it did not leak into a component “just for testing.”
- The site key, sometimes called a project key, identifies this one app. The page sends it when it inserts or lists rows. It is public. It still should not be your account token with a friendlier name. Read the prefix and the docs until you are sure which value you copied.
3. Call the table from the page
The page’s job is small. Initialize the client with the site key. On a published HTTPS page, the client should know the data host already. On your own laptop, point it at the local data API your tool documents, and do not aim localhost at the production API by accident. Then insert a row and, when you need to, list the rows.
A minimal shape, in plain browser JavaScript:
{ email, name } into the waitlist table. Keep the returned row id if you will update or remove that row later. List the table when you want to see what was saved.
Handle the empty and error cases in the form. If the insert fails because the table does not exist, the schema was never applied. Applying it again is the fix. Inventing a second backend in the same afternoon is how the email goes back to being a console.log.
4. Prove it without your dev server
Submit one address you control. Refresh. Confirm the row is still there. Open the published URL on a phone that is not on the same wifi, submit a second address, and confirm both rows exist wherever you read the table. Then view source on the live page and confirm the account token is absent.
If the second phone can submit, the page no longer depends on a server you wrote. It depends on a table and a public key. That is the whole design, and it is enough until the data stops being a shared list.
5. Know when to stop using this pattern
Stop when a visitor must see only their own rows, when you store secrets, or when a bad insert would be expensive. Until then, resist the agent’s offer to generate an API. The email’s job is to be in the table tomorrow morning. A server you have to keep alive is extra moving parts around that job.