Do you need to move your portfolio to add a contact form? HTML can display the form. The choice depends on where you want to receive submissions and what you need to do with them.
In this article
Three ways to add a form to a static site
| Method | When it fits | What to check first |
|---|---|---|
| Your host’s form feature | Your current host can accept submissions and meet your notification and storage needs | Submission limits, notification recipients, and setup after publishing |
| External form service | You want to keep your current host and delegate submission handling | Submission URL, submission limits, and retention |
| Your own API | You want to build your own routing or integrate with internal tools | Input validation, spam prevention, storage, and notifications |
First decide where the form should send its data. In this HTML, action is the destination and name identifies each field in the submission. For an external service or your own API, replace the example URL. For a built-in feature, follow your host’s setup instructions.
<form action="https://example.com/contact" method="POST">
<label>Reply email <input name="email" type="email" required></label>
<label>Message <textarea name="message" required></textarea></label>
<button type="submit">Send</button>
</form>
1. Use your host’s form feature
If your host can accept submissions, check whether it supports the notifications and storage you need. After publishing, send a test submission and verify the record and the notification separately.
If you already use Netlify, Netlify Forms is one example. Enable form detection, remove the example action, and add name="contact" and data-netlify="true" to the form in the HTML. Then redeploy. Netlify Forms setup
2. Send submissions to an external form service
If your host has no form feature, you can keep the page where it is. Set action to the URL issued by the external form service. With Formspree, for example, copy your form URL from the dashboard. Formspree HTML form setup
<form action="https://formspree.io/f/YOUR_FORM_ID" method="POST">
Before choosing a plan, check the monthly submission limit, what happens when you reach it, and how long the service keeps submissions. If you collect email addresses, check who can view them and how to delete them.
3. Accept submissions through your own API
If an external service cannot meet your routing, tracking, or retention needs, consider your own API. For the form above, set the opening tag to <form action="https://api.example.com/contact" method="POST"> and accept an application/x-www-form-urlencoded body on the server. Save the submission with an ID before sending the notification so you can look it up if the email fails. Redirect the browser to a confirmation page after saving.
The HTML required attribute helps users fill in the form. The API should also validate required fields and lengths and limit repeated submissions. Keep mail API keys and database passwords in server-side environment variables. A regular HTML form can send a POST to another origin. If you use JavaScript fetch to read a response from another origin, configure the origins your API allows. Fetch CORS specification
KamuiDash can publish a static site and a Node.js or Python web server separately. You can also keep your existing site and deploy just the form API to the platform. KamuiDash app settings
Test the full path after publishing
Submit from the live URL and verify the confirmation page, submission record, and notification. Leave a required field blank to check the browser’s validation. With your own API, also send missing fields and overly long messages directly to the endpoint and verify that it rejects them without creating a record. Start with a method that works with your current host and revisit the choice when storage or routing needs change.
Related articles
See KamuiDash for how to publish static sites and web APIs from GitHub. KamuiDash