A form collects information from visitors: a contact form, an enquiry, a booking request. You define the fields once in the admin, place the form on a page, and every submission is kept for you to read, optionally emailed to you as it arrives. By the end of this chapter you will have a contact form on a page.
Forms are a feature: a package you add to the site and list in site.config.ts. A site that was created with forms chosen already has this, and a contact form too. In that case go straight to “Make a form”.
pnpm add @jamiemcconnell/cms-formssite.config.ts, import forms and list it under features:import { defineConfig } from '@jamiemcconnell/cms';
import { forms } from '@jamiemcconnell/cms-forms';
export default defineConfig({
// …the rest of your settings stay as they are…
features: [forms()],
});pnpm dev with Ctrl+C and run it again. No migration is needed. Forms now appears in the admin's sidebar.contact. Blocks refer to the form by its key.The field types are Text, Email address, Phone number, Number, Paragraph (a longer, multi-line answer), Drop-down, Checkbox and Image upload. A drop-down takes a list of choices, and an image upload takes the most pictures one answer may carry.
A Form field can be half width, so two sit side by side, and can have its own label, placeholder, help text and number of rows. The Form block holds the words for the button and for every message the visitor might see, so they can be in your own voice.
The starter site's contact page is a form like this one.
Every submission is kept. Open Forms and choose a form to see its Submissions, with the unread ones counted on the Forms list. Open a row for the whole submission, including any uploaded images as thumbnails that open full size. Download CSV gives you all of them in a spreadsheet, and Mark all read clears the count.
The email each submission sends is one of the site's emails, and its wording is under Content → Emails. It only goes out once the site has a real email provider (Going live). Until then the submissions are safe in the admin, but nothing is emailed.
After sending, the visitor lands on the form's success page. Every form gets one, which you edit like any page under Content → Callback pages. Visitors can only reach it through the form. To send them somewhere else instead, open the form, find “After submitting” on the Fields tab and choose another callback page.
A field of type Image upload lets visitors attach images, up to the number you set on the field. Images upload when the visitor presses Send, with a progress bar, and are stored beside the site's media without appearing in the Media library.
The site sets the limits in site.config.ts. These are the defaults, except that types allows every image type the cms serves (JPEG, PNG, WebP, GIF and AVIF) unless you list fewer:
features: [
forms({
uploads: {
maxBytes: 5 * 1024 * 1024,
maxFiles: 5,
types: ['image/jpeg', 'image/png'],
},
}),
],Sign-in, registration and every form are protected by two checks. A CSRF token, which the page fetches, stops other websites posting to your forms. A proof-of-work check, from a tool called ALTCHA, makes a bot do some work before it can send. It solves itself in the background as soon as the visitor focuses a field, and no third party is involved.
The check is invisible by default: nothing on the page and no room taken. You can change it in site.config.ts:
// Show an “I'm not a robot” box above the button again:
security: { captcha: { display: 'standard' } },
// Ask for more work from every browser, for a site under pressure:
security: { captcha: { cost: 5000 } },
// Turn the check off:
security: { captcha: false },Use one of these lines, not all three. The check needs a secure context, which means https or localhost, so a site on a plain-http address on your local network should turn it off. While the check is on, visitors need JavaScript to send a form; with it off, forms post without script.