Forms
Choose where your site's contact forms send submissions: Formspree, Web3Forms, any form service with a custom endpoint, or WordPress.
Forms
Your site is static, so a contact form needs somewhere to send its submissions. Forms settings picks that place once, for every form on the site.
Opening Forms Settings
Open Site ▾ › Forms settings (in the Settings column), or press ⌘K (Ctrl+K) and type "Forms".
Choosing a Provider
Pick one option and fill in its field:
| Option | What you enter | Where submissions go |
|---|---|---|
| None | Nothing | Forms stay disabled: the submit button is greyed out |
| Formspree | Formspree form ID (for example xyzabc12) | Your form on formspree.io |
| Web3Forms | Web3Forms access key | web3forms.com, which emails them to you |
| Custom endpoint | Form endpoint URL | Any service that accepts a form POST, such as Formspark, Getform or Basin |
| WordPress | Recipient email (optional); defaults to your WordPress admin email | Sent with wp_mail by your WordPress site |
Click Save.
Custom endpoint
Use this for any form service that isn't listed. Paste the full URL the service gives you for the form, form ID included, for example https://submit-form.com/your-form-id for Formspark. The URL must start with https:// (or http://); Forms settings won't save anything else.
The form is sent from the visitor's browser as a regular form POST (multipart/form-data) with an Accept: application/json header. Any status from 200 to 299 counts as sent, unless the service answers with JSON containing "success": false. On an error, the form shows the service's error or message text if it sends one.
WordPress
WordPress needs a connected WordPress site with the PhantomWP Connect plugin. Without a connection, the option is greyed out with Connect WordPress to enable this option.
Forms post to your own site at /api/contact, which passes the message to WordPress using your project's WP_API_URL and WP_ACCESS_SECRET. Saving with this option also writes that route (src/pages/api/contact.ts). The route runs on the server, so your hosting has to support server-side routes, as Vercel and Cloudflare Workers do. If WordPress delivery returns an error, update the PhantomWP Connect plugin.
What Gets Saved
Saving writes:
src/config/forms.json: the provider and its setting. If the file doesn't exist yet, Forms settings says so and creates it when you save.src/lib/forms.ts: the helper your forms read. It's rewritten every time you save Forms settings, so don't put your own code in it.src/pages/api/contact.ts: only with the WordPress option.
Like any other edit, the change goes live when you publish.
Which Forms Use It
These read Forms settings:
- the Contact Page template in the Create Page dialog
- the contact sections in the Component Library
Each one sends name, email, subject and message fields, plus a hidden _gotcha field that many services use to catch spam bots. With Web3Forms, the access key is sent as a hidden access_key field. After sending, the form shows "Thank you! Your message has been sent." or an error, without leaving the page.
Your own forms
To make a form you wrote yourself use the same setting, read it from @/lib/forms:
---
import { getFormDelivery } from '@/lib/forms';
const delivery = getFormDelivery();
---
<form action={delivery.action} method={delivery.method}>
{delivery.accessKey && <input type="hidden" name="access_key" value={delivery.accessKey} />}
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<button type="submit" disabled={!delivery.enabled}>Send</button>
</form>delivery.enabled is false until a provider is chosen and its field is filled in. A form written like this does a full-page POST to the provider. The Component Library's contact sections include a small script that sends the form in the background and shows the result on the page instead.
Next Steps
- Working with Files: create a contact page
- Component Library: add a contact section
- PhantomWP Connect Plugin: needed for WordPress delivery