문서 /
폼
Lobsite 사이트의 모든 HTML 폼은 메시지를 받을 수 있습니다. action을 /_lobsite/forms/<name>으로 지정하고 배포하세요. 작성할 백엔드도, 추가할 스크립트도, 붙여 넣을 키도 없습니다. 제출 내용은 대시보드의 제출 내용 페이지와 이메일로 들어옵니다.
<form action="/_lobsite/forms/contact" method="POST">
<input name="email" type="email" required>
<textarea name="message" required></textarea>
<button>Send</button>
</form>
폼의 작동 방식
- action이 폼의 이름을 정합니다.
/_lobsite/forms/contact는 폼contact입니다. 이름은 소문자, 숫자,-,_입니다. 목적별로 이름 하나를 사용하며(contact,newsletter,quote), 여러 페이지가 폼 하나를 공유할 수 있습니다. - 폼은 배포 시 찾습니다. 배포가 HTML 파일을 읽어
/_lobsite/forms/로 전송하는 각 폼을 기록합니다. 폼은 배포된 폴더의 HTML 파일에 있어야 합니다. JavaScript 렌더링 후에만 존재하는 폼은 찾지 못합니다(프레임워크 참고). - 입력란은 이름 그대로 저장됩니다.
name이 있는 모든 입력란이 텍스트로 보관됩니다.email이라는 입력란은 알림 이메일의 Reply-To와 제출 내용 페이지의 제목으로 사용됩니다. 파일 업로드는 지원되지 않습니다. - 스팸 방지가 자동으로 추가됩니다. 페이지가 제공될 때 숨겨진 허니팟 입력란과 서명된 타임스탬프가 폼에 추가됩니다. 허니팟을 채우거나 2초 안에 돌아온 제출은 스팸으로 분리되며, 한 방문자의 연속된 과다 제출은 거부됩니다.
- 전송 후 방문자는 돌아가기 링크가 있는 감사 페이지 또는
redirect로 설정한 페이지를 봅니다. - 폼은 프로덕션 URL에서 작동합니다. 미리보기 배포는 제출을 받지 않으며, 계정 없이 배포한 사이트는 가져온 후 받습니다.
폼 유형
각 폼은 문의 폼 또는 대기자 명단입니다. 유형에 따라 제출 내용 페이지의 표시가 결정됩니다. 문의 폼의 행은 메시지를, 대기자 명단의 행은 누가 어느 페이지에서 등록했는지를 보여 주며, 대기자 명단은 표 위에 수가 표시됩니다. 둘 다 같은 알림 이메일을 보냅니다.
Lobsite는 배포 시 유형을 선택합니다.
- 방문자가 이메일과 최대 이름만 입력하는 폼은 대기자 명단입니다. 숨겨진 입력란,
_로 시작하는 입력란, 체크박스(동의 상자)는 계산하지 않습니다. waitlist,newsletter,signup,subscribe,early-access,beta,notify라는 이름의 폼도 입력란과 관계없이 대기자 명단입니다.- 그 외의 모든 폼은 문의 폼입니다.
직접 선택하려면 lobsite.toml에서 type을 설정하세요.
[forms.launch]
type = "waitlist" # or "contact"
대기자 명단 등록 내용은 폼이 있는 동안 보관되며, 다른 제출 내용은 플랜의 보관 기간 동안 보관됩니다(한도 참고).
문의 폼
이름, 이메일, 메시지가 있는 완전한 페이지입니다. 라벨과 autocomplete 값으로 입력하기 쉽고, required 속성이 빈 제출을 전송 전에 막습니다.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Contact</title>
</head>
<body>
<h1>Get in touch</h1>
<form action="/_lobsite/forms/contact" method="POST">
<label>Name
<input name="name" autocomplete="name" required>
</label>
<label>Email
<input name="email" type="email" autocomplete="email" required>
</label>
<label>Message
<textarea name="message" rows="5" required></textarea>
</label>
<button type="submit">Send</button>
</form>
</body>
</html>
같은 입력란을 서버에서도 확인하고 방문자를 직접 만든 감사 페이지로 보내려면 lobsite.toml에 폼을 추가하고 thanks.html을 만드세요.
[forms.contact]
required = ["name", "email", "message"]
types = { email = "email" }
redirect = "/thanks"
대기자 명단
출시 전에는 이메일 입력란만 있으면 됩니다. 폼 이름이 대기자 명단으로 만들며, type을 설정하면 명시할 수 있습니다. 등록 내용은 제출 내용 페이지에서 계산되고 폼이 있는 동안 보관됩니다.
<form action="/_lobsite/forms/waitlist" method="POST">
<label for="wl-email">Get early access</label>
<input id="wl-email" name="email" type="email" autocomplete="email" placeholder="you@example.com" required>
<button>Join the waitlist</button>
</form>
[forms.waitlist]
type = "waitlist"
required = ["email"]
types = { email = "email" }
뉴스레터 가입
입력란 하나면 충분합니다. 같은 사이트의 두 번째 폼에는 자체 이름을 주므로 가입과 메시지가 제출 내용 페이지와 내보내기에서 분리됩니다. 이메일 입력란만 있는(최대 이름 포함) 폼은 대기자 명단입니다. 폼 유형을 참고하세요.
<form action="/_lobsite/forms/newsletter" method="POST">
<label for="nl-email">Get updates by email</label>
<input id="nl-email" name="email" type="email" autocomplete="email" required>
<input type="hidden" name="_redirect" value="/subscribed">
<button>Subscribe</button>
</form>
_redirect는 전송 후 표시할 페이지를 고르는 숨겨진 입력란입니다. 같은 사이트의 경로나 URL이어야 하며, lobsite.toml의 redirect가 우선합니다.
견적 요청
선택 목록, 라디오 버튼, 체크박스는 평소처럼 작동합니다. 이름이 같은 체크박스는 쉼표로 구분된 값 하나로 저장됩니다.
<form action="/_lobsite/forms/quote" method="POST">
<input name="name" autocomplete="name" required>
<input name="email" type="email" autocomplete="email" required>
<input name="phone" type="tel" autocomplete="tel">
<select name="budget">
<option>Under $1,000</option>
<option>$1,000 to $5,000</option>
<option>Over $5,000</option>
</select>
<fieldset>
<legend>Services</legend>
<label><input type="checkbox" name="services" value="Design"> Design</label>
<label><input type="checkbox" name="services" value="Development"> Development</label>
<label><input type="checkbox" name="services" value="Hosting"> Hosting</label>
</fieldset>
<textarea name="details" required></textarea>
<button>Request a quote</button>
</form>
페이지를 떠나지 않고 보내기
새 페이지를 로드하지 않고 제자리에 메시지를 표시하려면 fetch로 폼을 보내세요. 숨겨진 스팸 입력란도 함께 가도록 new FormData(form)으로 본문을 만들고, Accept 헤더로 JSON을 요청하세요.
<form id="contact" action="/_lobsite/forms/contact" method="POST">
<input name="email" type="email" required>
<textarea name="message" required></textarea>
<button>Send</button>
<p id="contact-status" role="status"></p>
</form>
<script>
const form = document.getElementById("contact");
const status = document.getElementById("contact-status");
form.addEventListener("submit", async (event) => {
event.preventDefault();
status.textContent = "Sending…";
const res = await fetch(form.action, {
method: "POST",
body: new FormData(form),
headers: { Accept: "application/json" },
});
const answer = await res.json();
if (answer.ok) {
form.reset();
status.textContent = "Thanks! We'll be in touch.";
} else {
status.textContent = answer.errors ? Object.entries(answer.errors).map(([field, why]) => `${field}: ${why}`).join(", ") : "Something went wrong. Please try again.";
}
});
</script>
응답은 {"ok": true}, 통과하지 못한 입력란의 경우 {"ok": false, "errors": {"email": "Required"}}, 또는 {"ok": false, "error": "rate_limited"}(그 외 too_large, not_found, forms_off)입니다. 스크립트가 없어도 같은 폼은 일반 폼으로 작동합니다.
프레임워크
React, Vue, Svelte, Astro 등은 폼이 빌드된 HTML에 있으면 작동하며, 이는 사전 렌더링과 정적 내보내기가 생성합니다(Astro와 Eleventy는 기본, output: "export"의 Next.js, prerender의 SvelteKit, nuxt generate의 Nuxt). action과 method 속성은 <form> 요소 자체에 유지하세요.
싱글 페이지 앱에서 폼은 빌드된 HTML에 있고 제공된 그대로 유지되어야 합니다. JavaScript에만 존재하는 폼은 기록되지 않아 제출이 거부되며, 브라우저가 다시 렌더링하는 폼은 스팸 입력란을 잃어 메시지가 스팸으로 분류됩니다.
// React: a plain form element, prerendered into the HTML.
export function Contact() {
return (
<form action="/_lobsite/forms/contact" method="POST">
<input name="email" type="email" required />
<textarea name="message" required />
<button>Send</button>
</form>
);
}
설정
각 폼은 lobsite.toml에 섹션을 가질 수 있습니다. 모든 키는 선택 사항이며 설정은 배포와 함께 이동합니다.
[forms.contact]
type = "contact" # contact or waitlist; inferred when left out
required = ["email", "message"] # fields that can't be empty
types = { email = "email", phone = "tel" } # text, email, number, url or tel
redirect = "/thanks" # the page shown after sending
notify = ["you@example.com"] # who gets an email for each message
webhook = "https://example.com/hooks/contact" # POSTs each submission as JSON
required나 types에 실패한 제출은 저장되지 않으며, 방문자는 고칠 내용과 돌아가기 링크를 봅니다. 무료 플랜에서 notify는 계정 이메일만 가능하고 webhook은 사용할 수 없습니다.
제출 내용 읽기
- 대시보드의 제출 내용 페이지는 모든 폼의 제출 내용을 표 하나로 보여 줍니다. 검색하고, 사이트와 폼 유형으로 좁히고, 스팸으로 전환하여 검사에서 걸러진 것을 볼 수 있습니다. 제출 내용은 열 때까지 새 항목입니다.
- 각 메시지는 계정 주소로 이메일로 전송되며 Reply-To는 보낸 사람으로 설정됩니다.
lobsite forms ls는 폼을 나열하고,lobsite forms export contact --csv는 폼 하나의 제출 내용을 다운로드합니다. 제출 내용 페이지의 CSV 내보내기는 표에 표시된 내용을 다운로드합니다.
무료 플랜에서 폼은 제한 모드로 실행됩니다. 사이트별 월간 할당량, 계정 이메일로만 알림, 웹훅 없음입니다. Standard 플랜에는 웹훅, 인증된 모든 알림 주소가 추가되며 월간 상한이 없습니다. 한도를 참고하세요.