정적 웹사이트에 Contact Form 추가하는 방법 (Backend 없이)
Source: Dev.to
번역할 텍스트가 제공되지 않았습니다. 번역이 필요한 본문을 알려주시면 한국어로 번역해 드리겠습니다.
소개
정적 사이트는 빠르고 저렴하며 배포가 쉽지만, 폼 제출을 처리할 내장된 방법이 없습니다. 백엔드(PHP, Node, 데이터베이스 등)가 없으면 데이터를 수집하고, 이메일 알림을 보내며, 스팸을 방지하기 위해 서드파티 서비스를 사용해야 합니다.
이 가이드는 가장 간단한 2분 설정부터 완전 맞춤형 솔루션까지 세 가지 접근 방식을 보여주며, 예시 서비스로 SnapForm을 사용합니다.
옵션 1: SnapForm 백엔드가 있는 일반 HTML 폼
가장 빠른 방법은 HTML 폼을 SnapForm 엔드포인트에 연결하는 것입니다. SnapForm은 제출 내용을 저장하고, 이메일 알림을 보내며, 스팸 방지(허니팟)를 기본 제공합니다.
기본 폼
<form action="https://snapform.cc/api/f/YOUR_FORM_ID" method="POST">
<label>
Name
<input type="text" name="name" required />
</label>
<label>
Email
<input type="email" name="email" required />
</label>
<label>
Message
<textarea name="message" required></textarea>
</label>
<button type="submit">Send Message</button>
</form>
JavaScript 없이, 빌드 단계 없이, 의존성 없이. 모든 제출은 SnapForm 대시보드에 표시되고 이메일 알림이 트리거됩니다.
무료 기능
- 이메일 알림
- 파일 업로드 (대부분의 서비스는 이에 비용을 부과)
- 스팸 방지(허니팟, CAPTCHA 없음)
- CSV 내보내기
파일 업로드 추가하기
<form action="https://snapform.cc/api/f/YOUR_FORM_ID" method="POST" enctype="multipart/form-data">
<label>
Attach your resume
<input type="file" name="resume" />
</label>
<button type="submit">Submit</button>
</form>
지원 파일 형식: JPEG, PNG, GIF, PDF, DOC/DOCX, XLS/XLSX, TXT, CSV, ZIP.
JavaScript로 파일 업로드하기
const form = document.querySelector('form');
const formData = new FormData(form);
// Do NOT set Content-Type; the browser adds the multipart boundary automatically
const res = await fetch('https://snapform.cc/api/f/YOUR_FORM_ID', {
method: 'POST',
body: formData,
});
팁:
fetch를 사용해 파일을 업로드할 때는Content-Type헤더를 생략하세요. 브라우저가 올바른 multipart 경계값을 자동으로 설정합니다.
옵션 2: JavaScript로 제출 처리하기 (페이지 리다이렉션 없음)
단일 페이지 경험을 선호한다면(예: React, Vue, Astro) 폼 제출을 가로채서 fetch를 통해 데이터를 전송하세요.
const form = document.querySelector('#contact-form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData(form);
const data = Object.fromEntries(formData);
try {
const res = await fetch('https://snapform.cc/api/f/YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (res.ok) {
form.reset();
alert('Message sent!');
} else {
alert('Something went wrong. Please try again.');
}
} catch (err) {
alert('Network error. Please try again.');
}
});
SnapForm이 CORS를 지원하기 때문에 모든 도메인에서 작동합니다.
React 예시
import { useState } from 'react';
function ContactForm() {
const [status, setStatus] = useState('idle');
async function handleSubmit(e) {
e.preventDefault();
setStatus('sending');
const data = Object.fromEntries(new FormData(e.target));
const res = await fetch('https://snapform.cc/api/f/YOUR_FORM_ID', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
setStatus(res.ok ? 'sent' : 'error');
}
if (status === 'sent')
return <p>Thanks! Message received.</p>;
return (
<form id="contact-form" onSubmit={handleSubmit}>
{/* form fields go here */}
<button type="submit" disabled={status === 'sending'}>
{status === 'sending' ? 'Sending...' : 'Send'}
</button>
</form>
);
}
옵션 3: 고급 통합 (웹훅, API)
슬랙, Zapier 또는 자체 API로 제출 전송
SnapForm 대시보드에 웹훅 URL을 추가하세요. 각 제출은 다음 페이로드와 함께 POST 요청을 트리거합니다:
{
"formId": "your-form-id",
"formName": "Contact Form",
"submissionId": "abc123",
"data": {
"name": "Jane Doe",
"email": "jane@example.com",
"message": "Hello!"
},
"createdAt": "2026-02-28T10:30:00.000Z"
}
프로그래밍 접근 (Pro/Business 플랜)
API를 통해 양식과 제출을 조회할 수 있습니다.
# 모든 양식 목록 조회
curl -H "Authorization: Bearer sk_live_xxx" \
https://snapform.cc/api/v1/forms
# 페이지네이션을 사용한 제출 조회
curl -H "Authorization: Bearer sk_live_xxx" \
"https://snapform.cc/api/v1/forms/FORM_ID/submissions?page=1&limit=10"
맞춤 대시보드 구축, CRM과 동기화, 혹은 정기적인 내보내기에 유용합니다.
가격 비교
| 서비스 | 무료 티어 (제출/월) | 유료 티어 (가격) | 파일 업로드 |
|---|---|---|---|
| SnapForm | 50 | $9/월, 2,000개 | 예 |
| Formspree | 50 | $24/월, 1,000개 | 아니오 |
| Getform | 50 | $16/월, 1,000개 | 아니오 |
| FormSubmit | 무제한 | 무료 | 아니오 |
결론
대부분의 정적 사이트에서는 옵션 1(일반 HTML + SnapForm 백엔드)만으로 충분합니다. GitHub Pages, Vercel, Netlify, Cloudflare Pages 또는 로컬 HTML 파일 등 어디서든 작동하며 JavaScript, 백엔드, CAPTCHA가 필요 없습니다.
보다 부드러운 사용자 경험이 필요하다면 옵션 2를 사용해 JavaScript로 제출을 처리하세요. 복잡한 워크플로우의 경우 옵션 3을 웹훅 또는 SnapForm API와 통합합니다.