Forms — Tustel HTML
The Tustel HTML template has one form, the project enquiry on the Contact page, and it sends to the form service or webhook of your choice.
Visitors leave their name, e-mail, organization, project type, budget, timeline and a message. The form checks the required fields, shows a spinner while sending, says “Thank you” and clears the fields, keeps what the visitor typed when something fails (“Something went wrong”), and drops spam with a hidden honeypot field.
Out of the box it runs in demo mode: nothing is sent, and the fields are logged in the browser console. Pick a destination before you publish.
Connect a form service
Section titled “Connect a form service”A static site has no server of its own, so submissions go to a form service or a webhook. All of these have a free tier:
| Service | What it does | formEndpoint |
|---|---|---|
| Formspree | Emails you each submission | https://formspree.io/f/<form id> |
| Web3Forms | Emails you each submission, no account needed | https://api.web3forms.com/submit, and your key in formAccessKey |
| Getform, Basin | Inbox, email, integrations | The form’s endpoint URL |
| Zapier, Make, n8n, Pipedream | Send submissions anywhere: Google Sheets, Slack, a CRM, your project tracker | The webhook (“catch hook”) URL |
-
Create a form at the service and copy its endpoint.
-
Open
assets/js/config.jsand paste it:window.siteConfig = {formEndpoint: "https://formspree.io/f/abcdwxyz",formAccessKey: "", // Web3Forms only}; -
Serve the folder (
npx serve .), submit the form on the Contact page, and check that the submission arrived. -
Upload
config.jswith the site.
Every page loads the same config.js. The short sample form in style-guide.html stays in demo mode whatever you set
there (it carries data-form-demo), so it never sends anything.
What the service receives
Section titled “What the service receives”Each field by its name, as multipart/form-data:
| Field | Name | Required |
|---|---|---|
| Name | name |
yes |
email |
yes | |
| Organization | organization |
|
| Project Type: Photography, Brand Identity, Web Design, Creative Direction, Art Direction or Other | project |
yes |
| Estimated Budget: Under $2,000, $2,000 – $5,000, $5,000 – $10,000 or $10,000+ | budget |
yes |
| Timeline | timeline |
|
| Message | message |
The form also sends form (contact) and subject (“New project enquiry”), so you can tell an enquiry apart in your
inbox or tool, and access_key when formAccessKey is set. The honeypot field is left out. The request asks for a
JSON answer (Accept: application/json), so the service answers the page instead of showing its own thank-you page.
Changing the fields
Section titled “Changing the fields”The fields are ordinary <input>, <select> and <textarea> elements inside the <form> of contact.html, each in
a <label> with its text. Change a label or a placeholder in place; the choices of Project Type and Estimated Budget
are the <option> elements of the two selects (the first, empty one is the placeholder). The form has two columns from
tablets up (one on phones), and the message takes both (md:col-span-2).
- To make a field required, add
requiredto it, and the orange asterisk after its label’s text:<span aria-hidden="true" class="text-orange">*</span>. The browser checks it before sending. - To add a field, copy a
<label>…</label>and give its input a newname. The service receives whatever the form contains, so there are no settings to update. - To remove a field, delete its
<label>…</label>.
A field arrives under its name, so keep the names you already map somewhere. “Thank you” and “Something went wrong”
are written twice: in the button, and in the form’s data-success and data-error, which screen readers announce.
Change both. “Send message” is in the button twice too (the second copy is read while the form is sending). The title
of each submission is the value of the hidden subject field, and the note next to the button (“All fields marked
with * are required.”) draws its asterisk in orange.
Testing before launch
Section titled “Testing before launch”- Submit the form on the live site with a real address, and reply to the test.
- The service must answer with a success status (2xx). If it doesn’t, the visitor sees “Something went wrong” and keeps
what they typed. Try it once by pasting a wrong endpoint into
config.json your local copy. - The browser console tells you what happened: in demo mode it logs
[forms] demo mode — set formEndpoint in assets/js/config.js to send submissionswith the fields; after a failure,[forms] could not send the formwith the reason.
Spam and privacy
Section titled “Spam and privacy”The honeypot stops the usual bots (a bot that fills the hidden field is shown “Thank you” and nothing is sent); the services above filter spam on their side as well. The endpoint is visible in the page source, which is how these services are designed to work.
Submissions go only where you point them. Most countries expect you to say what happens to the data people send you. Tustel has no privacy policy page and no consent checkbox: if you need a policy, add a page for it (Editing the site) and mention it in the Contact page’s text.