정적 사이트의 문의 폼4분 분량
GitHub Pages 사이트에 문의 폼 추가하기
GitHub Pages는 서버 코드를 실행할 수 없어 폼 POST가 405 Not Allowed를 받습니다. 대신 폼 백엔드로 POST하고 프로젝트 사이트의 리디렉션을 올바르게 설정하세요.
GitHub Pages는 정적 파일만 제공하므로, 여러분의 사이트로 POST하는 폼은 405 Not Allowed를 받고 메시지가 사라집니다. 폼의 action을 Ikiform 엔드포인트로 설정하고, username.github.io와 커스텀 도메인을 Allowed domains에 추가하고, 프로젝트 사이트의 경로가 포함된 감사 페이지로 리디렉션하세요. 저장소나 Pages 설정은 하나도 바뀌지 않으며, 공개 저장소에 비밀이 들어가지도 않습니다.
GitHub Pages에서 다른 점
GitHub Pages는 저장소나 Actions 워크플로가 빌드한 것만 게시합니다. Jekyll을 쓴다면 빌드 시점에 실행되고, 결과물은 파일입니다. 요청 핸들러가 없으므로 무엇을 커밋하든 PHP의 mail(), Node 스크립트, Python CGI 폼은 실행되지 않습니다.
터미널에서 실패를 직접 확인할 수 있습니다. Pages 사이트의 어떤 페이지로든 POST하면 다음을 받습니다.
curl -i -X POST -d "message=hello" https://ada.github.io/notebook/contact.htmlHTTP/2 405
server: Varnish
content-length: 131
<html>
<head><title>405 Not Allowed</title></head>Pages를 다른 정적 호스트와 구별하는 점이 네 가지 더 있고, 모두 문의 폼과 관련됩니다.
| Pages의 특성 | 폼에 미치는 영향 |
|---|---|
프로젝트 사이트는 username.github.io/repo/ 경로 아래에 있습니다 | /thanks.html이라는 감사 URL은 프로젝트가 아니라 사용자 사이트를 가리킵니다. 모든 URL에 /repo/ 부분이 필요합니다 |
| 커스텀 응답 헤더 설정이 없습니다 | Content-Security-Policy는 페이지의 <meta> 태그로만 넣을 수 있습니다 |
| 저장소가 공개인 경우가 많습니다 | 그 안의 모든 것은 공개됩니다. 폼 ID는 괜찮지만, 시크릿 API 키나 이메일 비밀번호는 절대 안 됩니다 |
| GitHub는 Pages 사이트를 비밀번호나 신용카드 번호 전송 같은 민감한 거래에 사용해서는 안 된다고 안내합니다 | 문의 폼은 문의 용도로만 쓰세요. 카드 정보나 계정 비밀번호를 이 폼으로 받지 마세요 |
- Pages가 게시하는 브랜치로 푸시합니다.
- Jekyll이나 Actions 워크플로가 사이트를 한 번 빌드합니다.
- Pages가 결과물을 github.io나 커스텀 도메인에서 정적 파일로 제공합니다.
- 방문자가 문의 폼을 제출합니다. action이 여러분의 사이트를 가리키면 Pages는 405 Not Allowed로 응답합니다.
- action을 Ikiform 엔드포인트로 설정하면 Ikiform이 메시지를 저장하고 이메일로 알려 줍니다.
- Ikiform이 브라우저를 감사 페이지로 리디렉션하고, Pages는 다른 파일처럼 이 페이지를 제공합니다.
폼
직접 작성한 사이트라면 index.html 옆에 contact.html을 추가하세요. 이 예제는 ada.github.io/notebook의 프로젝트 사이트용이므로 리디렉션에 /notebook/이 들어갑니다.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; form-action 'self' https://ikiform.com; connect-src 'self' https://ikiform.com"
/>
<title>Contact</title>
</head>
<body>
<h1>Get in touch</h1>
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<label for="name">Name</label>
<input id="name" name="name" autocomplete="name" required />
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<label for="about">What is it about?</label>
<select id="about" name="about">
<option value="question">A question about the project</option>
<option value="hire">Work together</option>
<option value="other">Something else</option>
</select>
<label for="message">Message</label>
<textarea id="message" name="message" rows="6" minlength="10" required></textarea>
<input type="hidden" name="page" value="docs-home" />
<input type="hidden" name="_redirect" value="https://ada.github.io/notebook/thanks.html" />
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button type="submit">Send</button>
</form>
</body>
</html><meta>Content-Security-Policy는 선택 사항입니다. 이미 있다면 유지하고,form-action과connect-src에https://ikiform.com이 포함되어 있는지 확인하세요. Pages는 이 헤더를 대신 보내 주지 않습니다.about선택 항목을 보면 메시지를 열기 전에 왜 연락했는지 알 수 있습니다. 옵션은 사람들이 실제로 문의하는 내용으로 바꾸세요.- 숨겨진
page입력은 폼이 어느 페이지에 있었는지 기록합니다. 같은 폼을 여러 문서 페이지에 둘 때 유용합니다. - 필드 이름은
email로 유지하세요. 알림 이메일이 이를 회신 주소로 사용합니다.
같은 HTML을 여러 경로에 배포하거나 최종 경로가 무엇이 될지 확실하지 않다면, 페이지 자신의 주소에서 브라우저가 리디렉션을 만들게 하세요. 폼 뒤에 다음을 넣으세요.
<script>
document.querySelectorAll('input[name="_redirect"]').forEach((input) => {
input.value = new URL("thanks.html", document.baseURI).href;
});
</script>Jekyll을 쓰나요? URL을 아예 하드코딩하지 마세요. Jekyll 가이드에 absolute_url로 URL을 만드는 include가 있으며, 프로젝트 사이트라면 baseurl을 붙여 줍니다. Actions 워크플로로 Astro, Vite, Hugo를 빌드하나요? 폼의 에셋이 로드되도록 프레임워크의 base 경로를 /repo/로 설정하고, 폼 자체는 Hugo 또는 프레임워크 가이드를 따르세요.
github.io의 허용 도메인
여러분의 사용자 이름으로 ada.github.io를 추가하세요. 프로젝트 사이트는 같은 호스트를 쓰므로 사용자 사이트와 모든 프로젝트 사이트가 포함됩니다. 커스텀 도메인을 쓴다면 그것도 추가하세요. example.com은 www.example.com도 포함합니다.
github.io만 단독으로 추가하지 마세요. 다른 사람의 사이트에 있는 폼 복사본을 포함해 모든 Pages 사이트가 일치하게 됩니다. 허용 도메인을 설정하면 https://ada.github.io/notebook/thanks.html로의 _redirect를 따르고, 설정하지 않으면 Ikiform이 이를 무시하고 호스팅 감사 페이지를 보여 줍니다.
https:로 시작하는 _redirect 값만 따르는데, 아직 인증서가 없는 커스텀 도메인은 http: 페이지를 제공합니다.mailto: 링크 바꾸기
많은 Pages 사이트가 푸터의 mailto: 링크로 시작합니다. 이를 폼으로 바꾸면 새로운 수집 봇이 페이지에서 주소를 읽어 가지 못하고, 메일 앱이 설정되지 않은 방문자도 드디어 연락할 수 있습니다. 지우기 전에 알아 둘 점이 두 가지 있습니다.
- 주소는 저장소 기록과 예전 페이지의 포크나 아카이브에 남아 있습니다. 폼은 지금부터 도움이 될 뿐, 수년간 공개되었던 주소를 다시 비공개로 만들지는 못합니다.
- 답장은 여러분의 받은편지함에서 보냅니다. 알림 이메일은 보낸 사람을 회신 주소로 설정하므로, Reply를 누르면
mailto:링크가 하던 일을 반대편에서 그대로 합니다.
Ikiform은 방문자에게 이메일을 보내지 않으므로, 언제쯤 답변을 받을 수 있는지 감사 페이지에 적어 두세요. 이메일로 답하기 벅찰 만큼 메시지가 많다면 웹훅으로 각 메시지를 Slack이나 Discord로 보낼 수 있습니다.
작동 확인하기
실제 github.io 주소에서 진행하세요. Pages에는 프리뷰 배포가 없으므로 먼저 로컬 서버로 테스트하세요.
- Allowed domains에
localhost와username.github.io를 추가하고, 커스텀 도메인이 있다면 그것도 추가하세요. contact.html과thanks.html을 커밋하고, 저장소의 Actions 탭에서 Pages 배포가 끝나길 기다린 뒤 실제 페이지를 여세요.- 폼을 제출하세요. 주소창에 프로젝트 경로가 포함된 여러분의
thanks.html에 도착해야 합니다. - 대시보드에서 Submissions를 여세요. 보낸 모든 필드가 담긴 새 제출이 있습니다.
- 알림 수신자마다 받은편지함을 확인하세요. 각자 필드가 담긴 이메일을 받고, 폼에
email필드가 있으면 Reply가 제출한 사람에게 갑니다. - 아무것도 오지 않았나요? 대시보드의 상태 필터를 Spam으로 바꿔 보세요. 스팸은 실제 제출과 같은 성공 응답을 받습니다.
주의할 점
| 문제 | 해결 방법 |
|---|---|
전송을 누른 뒤 405 Not Allowed | 배포된 폼이 아직 여러분의 사이트로 POST합니다. github.io에서 페이지 소스를 보고 action을 확인하세요. 오래된 캐시 빌드가 몇 분 동안 남아 있을 수 있습니다. |
| 여러분의 감사 페이지 대신 Ikiform의 감사 페이지 | _redirect 값에 저장소 경로가 빠졌거나, http:이거나, 폼에 허용 도메인이 없습니다. username.github.io를 추가하고 전체 https: URL을 쓰세요. |
403 origin_not_allowed, 또는 모든 POST가 스팸으로 분류됨 | 페이지의 도메인이 폼의 Allowed domains에 없습니다. 도메인을 추가하고, 로컬 테스트용으로 localhost도 추가하세요. 등록한 도메인의 하위 도메인은 허용됩니다. |
| 로컬에서는 폼 POST가 되는데 github.io에서는 콘솔에 CSP 오류가 표시됨 | 레이아웃의 <meta> Content-Security-Policy에서 form-action 또는 connect-src에 https://ikiform.com이 빠져 있습니다. |
질문
아니요. GitHub Pages는 정적 파일을 제공하며 방문자가 폼을 제출해도 아무 코드도 실행하지 않으므로, Pages URL로 보낸 POST는 405 Not Allowed를 받습니다. 대신 폼의 action을 폼 백엔드로 지정하세요.
네. 폼 ID는 어차피 공개 HTML에 들어갑니다. 허용 도메인과 스팸 검사로 폼을 보호하고, 시크릿 API 키는 절대 커밋하지 마세요. 정적 사이트에는 키를 안전하게 둘 곳이 없습니다.
/thanks.html 같은 경로는 프로젝트가 아니라 username.github.io의 루트를 가리킵니다. 저장소 경로가 포함된 전체 URL을 쓰거나, 브라우저에서 document.baseURI로 만드세요.
네. 어떤 도메인이 페이지를 제공하든 폼은 Ikiform으로 POST합니다. Allowed domains에 username.github.io와 함께 커스텀 도메인을 추가하고, HTTPS가 적용되면 _redirect 값을 커스텀 도메인으로 바꾸세요.
아니요, 무료 플랜은 없습니다. 테스트는 무료입니다. 결제하기 전에 localhost에서 한 달에 50건의 테스트 제출을 보낼 수 있습니다. 실제로 운영하려면 Pro가 제출 500건에 월 $6부터이며, 한 번만 결제해 제출 10,000건을 $49에, 50,000건을 $149에 살 수도 있습니다. 크레딧은 만료되지 않습니다.
막히는 단계가 있거나 내 상황에 맞는 가이드가 필요하다면 이메일을 보내세요: hello@ikiform.com.