Forms — Ciketo Next.js
Ciketo has one form, the quote request, and it works as soon as you run the site. It appears in three places with the same fields and copy:
- “Get a Quote” on Home, beside a photo;
- the Contact page, on the cover next to your contact details;
- every service page, after “How it works”.
It checks the required fields, shows a spinner while sending, says “Thank you” and clears the fields, keeps what the visitor typed when something fails, and drops spam with a hidden honeypot field.
Out of the box, submissions are written to the server log (FORM_PROVIDER=console). That’s fine while you build, but
useless once you publish, so pick a destination before launch.
The quickest way to receive submissions
Section titled “The quickest way to receive submissions”-
Copy the example settings:
Terminal window cp .env.example .env.local -
Choose one:
You want Set An email for every quote request FORM_PROVIDER=resend+RESEND_API_KEY,FORM_EMAIL_TO,FORM_EMAIL_FROMIt in your CRM, Slack, a spreadsheet… FORM_PROVIDER=webhook+FORM_WEBHOOK_URL(Zapier, Make, n8n, Formspree, your own API)The sender in a Mailchimp audience FORM_PROVIDER=mailchimp+MAILCHIMP_API_KEY,MAILCHIMP_AUDIENCE_IDSeveral at once work:
FORM_PROVIDER=resend,mailchimp. -
Restart
npm run devand send a test request. -
Put the same variables in your host’s dashboard before deploying.
.env.localis not uploaded.
Details for each provider, the webhook payload, Mailchimp consent settings and how to write your own provider are in Forms reference.
What the form asks for
Section titled “What the form asks for”| Field | Name it arrives under | Required |
|---|---|---|
| Full Name | name |
yes |
| Company Name | company |
|
| Work Email | email |
yes |
| Phone Number | phone |
|
| Origin | origin |
|
| Destination | destination |
|
| Shipping Method (Ocean Freight, Air Freight, Road Freight, Multimodal) | method |
yes |
| Estimated Weight | weight |
|
| Preferred Departure Date | date ("2026-11-02") |
|
| Tell us about your shipment | message |
|
| The consent checkbox | consent ("yes" when ticked, labelled “Agrees to be contacted”) |
Each submission carries the title “New quote request”, so you can tell it apart in your inbox or tool. Resend puts the
sender’s name after it in the email’s subject and sets the reply address to the sender’s e-mail. Mailchimp stores the
name as FNAME and the phone as PHONE, tags the contact with the title and keeps the rest as a note.
Changing the form
Section titled “Changing the form”The labels, placeholders, the shipping methods, the group titles (“Contact Information”, “Shipment Details”,
“Additional Details”), the consent line, the button texts (“Request My Quote”, “Thank you”, “Something went wrong”),
the heading and photo beside the form and the title of each submission are content: quoteForm in
src/content/site.ts. The Contact page uses the same copy.
A field arrives at your provider under its name, so keep the names you already map somewhere.
What the form sends is decided in src/lib/actions.ts (submitQuote), which lists the fields and which are required:
- To make a field required, set
required: trueon it inquoteForm.fields(the browser checks it first) and add its name torequiredinactions.ts. - To add a field, add it to
quoteForm.fields, then place it inQuoteForminsrc/components/sections/QuoteFormSection.tsx(<FormField {...fields.incoterm} />, in the group you want) and add its name to theQuoteFieldstype at the top of that file. The Contact page uses the sameQuoteForm, andactions.tssends every field ofquoteForm.fields.
Testing before launch
Section titled “Testing before launch”- Submit the form on your own site after deploying, with a real address.
- Check the destination (inbox, spreadsheet, audience) and reply to the test.
- Try a failure on purpose: set a wrong API key, submit, and confirm the visitor sees “Something went wrong” and their text is still there.
The honeypot stops the usual bots: a bot that fills the hidden field is shown “Thank you” and nothing is sent. If you start getting spam anyway, put a service in front through the webhook provider (Formspree, Web3Forms and Basin all include spam filtering), or add a captcha to the form component.
Privacy
Section titled “Privacy”Submissions go only where you point them; nothing is sent anywhere else. Most countries expect you to say what happens
to the data people send you. The form ends with a consent line (quoteForm.consent) and a checkbox, and the footer
links your Privacy Policy, whose text in src/content/collections/legal.ts is a demo to replace with your own.
The checkbox is optional. If you add senders to a marketing audience, make it ask for that and make it required: add
required to the checkbox in src/components/sections/QuoteFormSection.tsx and "consent" to required in
actions.ts.