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)