A FREE Hack to Add Custom Contact Forms to Your Website Using Google Forms
(No Subscriptions Needed!)
Hey devs! 😎
I just have to share this gem of a hack — especially if you're tired of shelling out ₱₱₱ for form subscriptions just to get a simple contact form working on your site.
What if I told you that you can have a fully custom, beautifully styled contact form that submits in the background, works like magic, AND costs you absolutely zero?
Yep, zero. 💸
Welcome to my favorite secret weapon:
Google Forms + Custom Frontend Integration.
Let’s get into it. 🚀
⚙️ What You’ll Build
You'll be creating a completely custom contact form that:
Looks amazing (styled with Tailwind)
Submits data silently in the background
Uses Google Forms as your backend (for FREE!)
Requires no backend server or expensive SaaS tools
Works on React + TypeScript
Ready? Let's gooo! 🙌
🧰 What You Need
A free Google account (duh)
Basic React + TypeScript setup
Tailwind CSS (for styling)
Coffee or adrenaline 😄
🛠 Step 1: Set Up Your Google Form
Go to Google Forms and create a new form.
Add the following fields:
Name (Short answer)
Email (Short answer — enable validation for email)
Subject (Short answer)
Message (Paragraph)
Hit "Send", then copy the form link. You’ll use this in a bit.
🕵️ Step 2: Find Your Form’s Entry IDs (This Is the Secret Sauce)
Now here comes the hacky part 👇
Open the published Google Form in a browser.
Right-click → View Page Source.
Hit
Ctrl+F
(orCmd+F
) and search for entry. — this is where you’ll find the field IDs.
They’ll look something like this:
<input type="hidden" name="entry.1168164901" value="">
Take note of each ID and which field it corresponds to:
entry.1168164901
→ Nameentry.1218904268
→ Emailentry.1726878304
→ Subjectentry.25819410
→ Message
💻 Step 3: Code Your Custom Form in React
Here’s the React component that ties it all together:
tsx
CopyEdit
// ContactForm.tsx
import { useRef, useState } from 'react'
export default function ContactForm() {
const formRef = useRef<HTMLFormElement>(null)
const [isSubmitting, setIsSubmitting] = useState(false)
const [isSubmitted, setIsSubmitted] = useState(false)
const [error, setError] = useState<string | null>(null)
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
setIsSubmitting(true)
setError(null)
const formData = new FormData(e.currentTarget)
const name = formData.get('name') as string
const email = formData.get('email') as string
const subject = formData.get('subject') as string
const message = formData.get('message') as string
const googleFormData = new FormData()
googleFormData.append('entry.1168164901', name)
googleFormData.append('entry.1218904268', email)
googleFormData.append('entry.1726878304', subject)
googleFormData.append('entry.25819410', message)
fetch('https://docs.google.com/forms/d/e/YOUR_FORM_ID/formResponse', {
method: 'POST',
mode: 'no-cors',
body: googleFormData,
})
.then(() => {
setIsSubmitting(false)
setIsSubmitted(true)
formRef.current?.reset()
setTimeout(() => setIsSubmitted(false), 3000)
})
.catch(() => {
setIsSubmitting(false)
setError('Something went wrong. Please try again.')
})
}
return (
<form ref={formRef} onSubmit={handleSubmit} className="bg-white/5 p-8 rounded-2xl border border-white/10">
<input name="name" required placeholder="Name" className="input" />
<input name="email" type="email" required placeholder="Email" className="input" />
<input name="subject" required placeholder="Subject" className="input" />
<textarea name="message" required placeholder="Message" className="input h-32" />
<button type="submit" disabled={isSubmitting} className="btn">
{isSubmitting ? 'Sending...' : 'Send Message'}
</button>
{isSubmitted && <p className="text-green-400 mt-2">Message sent!</p>}
{error && <p className="text-red-500 mt-2">{error}</p>}
</form>
)
}
Add some styling magic with Tailwind or your preferred CSS framework.
🎨 Sample Tailwind Styling (Optional but Recommended)
tsx
<input className="w-full mb-4 p-3 bg-white/10 border border-white/20 rounded-lg text-white placeholder:text-white/50 focus:outline-none focus:ring-2 focus:ring-blue-400" />
tsx
<button className="px-6 py-3 bg-blue-600 text-white rounded-xl hover:bg-blue-700 transition-all duration-200"> Send </button>
Add animations with Framer Motion for extra ✨ if you're feeling fancy.
✅ Why This Rocks
No need for backend code
No expensive tools like Typeform, Jotform, or Formspree
Reliable backend powered by Google
Fully customizable frontend
Works with any modern frontend framework
🧠 Final Tips
Make sure your Google Form is publicly accessible
Don’t worry about CORS warnings —
no-cors
still worksIf fields don’t submit, double-check the entry IDs
You can track form submissions directly in your Google Sheets (just connect your form!)
💡 Bonus Idea: Use This For...
Support tickets
Newsletter sign-ups
Event RSVPs
Lead generation forms
Feedback surveys
💬 Share This Hack!
If this saved you money and dev time, share it with your fellow devs! 🧡
Let’s stop overpaying for basic features and start building smarter.
Happy coding!