DEPLOYMENT GUIDE

3 Ways to Add a Contact Form to a Static Site

Choose between built-in forms, an external service, and your own API

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

Where a form sends its data · Conceptual diagram
Public pageDisplay the form
Submission handlerHost feature, external service, or your own API
RecipientReceive the message in a dashboard or notification
The static page and the service that handles submissions can be hosted separately.
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.

Code
<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

Code
<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.

How your API accepts submissions · Conceptual diagram
ValidateCheck required fields, length, and repeated submissions
SaveAssign an ID and show confirmation
NotifyNotify the recipient and match the submission to its record
Saving first lets you verify that a submission arrived even when notification fails.

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.

See KamuiDash for how to publish static sites and web APIs from GitHub. KamuiDash