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)