Forms on Vercel-hosted sites, straight to Google Sheets
Static output or SSR, form action or route handler relay - every submission from your Vercel-hosted site lands as a row in Google Sheets or Excel.
Vercel does not ship a native forms product - a form on a Vercel-hosted site posts to whatever you point it at. SheetLink Forms makes that a one-line decision: every form gets a permanent endpoint at https://sheetlinkforms.com/f/{token} that accepts urlencoded, JSON, or multipart POSTs (bodies up to 256KB) and files each accepted submission as a row in Google Sheets or an Excel Online table.
Delivery is direct: an asynchronous worker writes to the Google Sheets API or Microsoft Graph with retries at 5 minutes, 30 minutes, and 2 hours, and every attempt is visible in a delivery log. Field names matching your column headers map automatically (case and punctuation insensitive), and a formula-injection guard escapes leading =, +, -, and @ in cell values. The full pipeline is on how it works.
The product is free during beta and invite-gated - join the waitlist - and there are no per-submission fees, ever.
The best path for Vercel-hosted sites
Match the integration to your deployment shape. Static output on Vercel - an exported Next.js site, Astro, Hugo, plain HTML - needs nothing but the form's action attribute pointed at the endpoint, with the 303-redirect thank-you flow doing the rest. Frameworks running server code on Vercel get a second option: a route handler or serverless function that relays the payload, which adds a place for validation and enrichment and keeps CORS out of the picture.
The relay in the snippet uses the Web-standard Request/Response shapes, so the same dozen lines work as a Next.js route handler, a SvelteKit endpoint, a Nuxt server route, or a bare function in api/. A direct client fetch from the browser is also fully supported - send Content-Type: application/json and the endpoint answers {"ok":true,"id":"..."}.
1. Connect a sheet and get your endpoint
Connect Google Sheets with one-click OAuth (the drive.file scope means the product only sees sheets you pick or create - never the rest of your Drive) or connect Excel Online and pick a table. You get a permanent endpoint of the form https://sheetlinkforms.com/f/{token}. On an empty sheet the header row is seeded for you; rows then append under it.
2. Static sites: point the form at the endpoint
Use the HTML form from the snippet. Name inputs after your sheet's column headers so mapping is automatic, keep the honeypot input in place, and the browser follows a 303 redirect to a hosted thank-you page or a custom URL after submitting. No functions, no environment variables, no build-time configuration.
3. Server frameworks: add the relay
Drop the commented handler into your framework's server route location and post to it from your form component. The relay is the right place for validation, added fields, or swapping the destination later without touching client code. It relays the endpoint's {"ok":true,"id":"..."} straight back to the browser.
4. Or fetch from the client
Skip the hop entirely and fetch the endpoint from the browser with a JSON body including "_slhp": "". Cross-origin browser posts are supported, and the per-form origin allowlist can pin submissions to your production domains once you are live.
5. Add sl.js for attribution
The optional embed captures utm_* plus gclid, wbraid, gbraid, fbclid, and msclkid from landing URLs, persists them in localStorage across pages, and attaches them to the submission - useful the moment the site runs paid traffic. It binds forms marked data-sheetlink or posting to /f/, with SPA navigation handled by a MutationObserver.
6. Test and read the delivery log
Send a test submission and watch the row land - or try the live demo first. The delivery log records every attempt, and the docs list the error responses worth handling in a relay: 404 unknown token, 410 paused form, 403 origin not allowed, 413 payload too large, 429 rate limited, 400 unreadable body.
FAQ
Doesn't Vercel have its own forms feature?
No - Vercel provides hosting, serverless functions, and storage primitives, but no native forms product. The usual choices are building your own handler plus a database, or pointing the form at an external endpoint. SheetLink is the second option with a spreadsheet as the destination and no code to maintain.
Form action or route handler relay - which should I use?
Use the plain form action when the deployment is static or the form is simple - it is the whole integration in one attribute. Use the relay when you want server-side validation, enrichment, or one place to change the destination. Both file the same row and both are first-class paths.
Do preview deployments complicate the origin allowlist?
Each Vercel preview gets its own URL, so a strict allowlist would reject posts from previews. The allowlist is optional and per form: a common pattern is to leave it off while iterating, then pin it to your production domains before launch. Rate limits, the honeypot, and quarantine protect the form either way.
Does this depend on which framework I deploy?
No. The integration is one HTTP POST. Next.js, SvelteKit, Nuxt, Astro, Remix, or a folder of static files all post the same way - the differences are only in where your relay lives, if you use one at all.
What happens if the Sheets API is briefly down?
Acceptance and delivery are decoupled. The endpoint accepts the submission, then an asynchronous worker writes the row with retries at 5 minutes, 30 minutes, and 2 hours. The delivery log shows the outcome of every attempt, so nothing is lost to a transient failure.
Also on: Next.js · Netlify-hosted sites · SvelteKit