FormData when the visitor submits and passes the answer to your function, and the same post carries files and a spam blocker token.
Prerequisites
Before you start, you need:- A formcarry account. Sign up is free.
- A form in the dashboard. Its endpoint is on the form’s Setup page. The examples use
https://formcarry.com/s/AbC123xyz; put yours in its place.
The script tag
To include the library, add the script tag before the closing</body> tag, after the form:
formcarry. It is 3.8 KB gzipped and carries its own fetch and Promise fallbacks, so it runs in browsers without them. It is not on npm; the script tag is the only way to include it.
The form
To send a form through the library, give the form anid, give every field a name, and call formcarry() after both the form and the script:
name of each input is the field name formcarry stores. The email field is the visitor’s address, so it becomes the reply-to address of your notification email and the recipient of the auto response.
The library sends Accept: application/json, so the answer is JSON and the visitor stays on your page; the thank you page and the redirect are not used. The form’s Setup page in the dashboard shows this call with your form id filled in.
Call formcarry() after the form is in the page rather than in the <head>, otherwise element matches nothing and the call throws. Give the button type="submit" rather than type="button" with your own click handler, otherwise the form never fires submit and the library sends nothing. The browser’s own checks, such as required and type="email", still run before submit fires.
Options
form(required). The form id, the part of the endpoint after/s/. The library builds the URL from it and ignores the form’sactionandmethod.element(required). A CSS selector for the<form>, such as#contact. The first match is used. Point it at the<form>itself rather than a wrapper around it, otherwise the library throws aTypeErroron submit and sends nothing.onSuccess(required). A function called with the answer when the submission is stored. Without it a stored submission ends inonErrorwith aTypeError.onError(required). A function called with the answer when formcarry refuses the submission, or with theErrorwhen the request never reaches formcarry. Without it a refused submission is an unhandled rejection in the console and the visitor sees nothing.extraData. An object whose entries are added to the submission as fields, each stored under its key. The object is read when the visitor submits, so a value set on it after the call is sent too. Defaults to no extra fields.
extraData:
page and language next to the fields the visitor typed.
Success and error
The library callsonSuccess when the answer’s code is 200 and onError for every other answer. Both receive the answer object: code, status, title and message, plus errors on a 422.
When the request never reaches formcarry, or onSuccess throws, onError receives the thrown Error instead, which has a message and no code. To tell the two apart:
answer.code rather than showing answer.message as it comes, otherwise a dropped connection shows the browser’s own wording to the visitor.
To send the visitor to your own page after a stored submission, set window.location.href in onSuccess:
429, again in onError. To disable the button until the answer arrives, add your own submit listener before the call and enable the button again in onError:
FormData and the submission arrives without them.
Files
To send files, add a file input with aname to the form:
FormData, so the files go with the other fields. A multiple input sends every chosen file under its name, and several file inputs each send theirs under their own.
The library sets no Content-Type, so the browser adds the multipart boundary itself and the form needs no enctype. Files are stored on paid plans; on the free plan the rest of the submission is stored without them.
A File or Blob in extraData is sent as a file too. To send a file the visitor dropped outside the form, set it on the extraData object when the drop happens:
attachment, next to the fields from the form.
Spam blocker
To add a challenge, load the vendor’s script, put the widget’sdiv inside the form, and paste the secret key into the form’s settings under Form Security. With reCAPTCHA v2:
g-recaptcha-response to the form, so the FormData post carries the token and the call stays as it is. hCaptcha and Turnstile work the same way with their own script, widget class and token field:
An unsolved challenge posts an empty token, and formcarry answers
403 for reCAPTCHA or 400 for the others, in onError; show answer.message and let the visitor try again. Add localhost to the challenge’s allowed domains while you test.
The library posts the moment the visitor submits, before grecaptcha.execute() returns a reCAPTCHA v3 token, so a v3 post gets 403. For v3, post with fetch as on the JavaScript page.
Validation errors
A422 reaches onError with errors, one entry per failing field, each with a message. To show each one next to its field:
What’s next
- Field validations: the rules you can set per field.
- Spam protection: the challenges, the filter and the honeypot.
- Email notifications: the auto response the visitor gets, keyed on
email.