Want to add a contact form to your site without spinning up a backend?
Looking for something quick, free, and serverless?In this article, I’ll show you two practical ways to embed Google Forms into your Next.js site, with clean UI and no server-side headaches.
See the working version on my portfolio:
👉 https://satty-portfolio.vercel.app/
✅ What You’ll Learn
- ✅ How to embed Google Forms using an iframe
- ✅ How to customize your own UI and POST to Google Forms
- ✅ The pros and cons of both approaches
- ✅ Code examples using Next.js (App Router) + MUI
- ✅ Live example from my own portfolio site
🎯 Who Is This For?
- Developers who want a simple contact form
- Those looking for a serverless solution
- Next.js + MUI users who want better design flexibility
🛠 Tech Stack (My Portfolio Site)
Feature | Stack |
---|---|
Framework | Next.js (App Router + TypeScript) |
UI Library | MUI (Material UI) |
Form Submission | Google Forms |
🧩 Option 1: Embed Google Form with <iframe>
(Easiest Way)
🔧 Steps
- Create your form at Google Forms
- Click Send → <> Embed icon
- Copy the iframe code
🧪 Example
<iframe src="https://docs.google.com/forms/d/e/xxxxxxxx/viewform?embedded=true" width="100%" height="800" frameborder="0" marginheight="0" marginwidth="0" > Loading… </iframe>
✅ Pros & Cons
Pros | Cons |
---|---|
Super fast setup | Limited styling/customization |
Google Sheets support | May not feel "native" to your site |
Works out of the box | Not great for brand consistency |
🎨 Option 2: Create a Custom Form and POST to Google Forms
Google Forms has a hidden endpoint (formResponse) that lets you POST data directly. This allows full UI freedom while keeping your form submission serverless.
✨ What You’ll Need
- The form’s action URL (formResponse)
- Each field’s name attribute (entry.XXXXXXX)
🔍 How to Get the Form Action URL and Field Names
1.Get the action URL
- Open your Google Form
- Right-click → “View Page Source”
- Look for:
<form action="https://docs.google.com/forms/d/e/xxxxxx/formResponse" ...>
2.Get the field names
Search the source code for:
<input name="entry.123456789" /> <input name="entry.987654321" /> <textarea name="entry.192837465" />
Use these entry.XXXXXXX values in your code.
🧪 Simplified Code Example
'use client'; import { useState } from 'react'; const FORM_URL = 'https://docs.google.com/forms/d/e/xxxxxxxx/formResponse'; export default function ContactForm() { const [form, setForm] = useState({ name: '', email: '', message: '' }); const [submitted, setSubmitted] = useState(false); const handleChange = (e: any) => { setForm({ ...form, [e.target.name]: e.target.value }); }; const handleSubmit = async (e: any) => { e.preventDefault(); const formData = new FormData(); formData.append('entry.123456789', form.name); formData.append('entry.987654321', form.email); formData.append('entry.192837465', form.message); try { await fetch(FORM_URL, { method: 'POST', mode: 'no-cors', body: formData, }); setSubmitted(true); } catch (err) { alert('Something went wrong. Please try again.'); } }; if (submitted) return <p>📨 Thanks! Your message has been sent.</p>; return ( <form onSubmit={handleSubmit}> <input name="name" placeholder="Your Name" onChange={handleChange} required /> <input name="email" placeholder="Your Email" type="email" onChange={handleChange} required /> <textarea name="message" placeholder="Your Message" onChange={handleChange} required /> <button type="submit">Send</button> </form> ); }
⚖️ Which Method Should You Use?
Scenario | Recommendation |
---|---|
Want something super quick | ✅ Use method |
Need full control over styling | ✅ Use POST method |
Want to track events in Google Analytics | ✅ Use POST + GA4 event |
🔗 Live Example
See the working version on my portfolio:
👉 https://satty-portfolio.vercel.app/
✅ Summary
Google Form Integration | Value |
---|---|
Free and easy | ✅ No server required |
Embed or customize | ✅ Two flexible methods |
Integrates with MUI/Next | ✅ Works in any frontend project |
Whether you're launching a portfolio or MVP, Google Forms is a rock-solid, free, and fast option. Start simple, scale smart.
Top comments (0)