Why does the input type matter if everything arrives as text?
You pick type="email" and type="number" so the form feels right on a phone and catches typos. Then the messages arrive and some of them are still wrong, like an email address you cannot reply to or a quantity of 125 when the customer meant 12.5.
That happens because the type was never a guarantee of clean data. It shapes the text the browser puts in the request and the check it runs before sending, and on a phone it suggests a keyboard. None of that stops a determined typo. Your server still receives plain name=value text for every field, the same as in our walk-through of how HTML forms work. To see where each type helps and where it does not, we built a form with one input of each type and posted it from Chromium to a local copy of Formgong's form backend.
What does each input type send?
We filled in the form the way a visitor would, ticked one box, chose one radio button and left a few fields alone. This is what Chromium put in the request body and what the backend stored.
| Type | Sent | What to know |
|---|---|---|
| text, search | Emma Clarke | Exactly what was typed, spaces included |
emma.clarke@example.com | The @ arrives encoded as %40 and is decoded back | |
| tel | +44 20 7946 0000 | Any characters at all |
| url | https://emmaclarke.example | Only after the browser accepted it as a URL |
| number | 3 | Text, not a number; your server has to convert it |
| range | 2500 | Never touched: the middle of 0 to 5000 was sent anyway |
| date, time, datetime-local | 2026-11-14, 09:30, 2026-11-14T09:30 | Always this format, whatever the visitor's locale shows |
| month, week | 2026-11, 2026-W46 | Chromium has pickers for both |
| color | #000000 | Never touched: black was sent anyway |
| password | correct horse | Plain text in the body, so only ever over HTTPS |
| checkbox, no value | on | When ticked; an unticked box sends nothing at all |
| radio | phone | The chosen value; with none chosen, the name is missing |
| file, no file chosen | attachment= | An empty value; files need multipart encoding |
| hidden | homepage | Visible and editable by anyone, so never trust it |
| disabled or without a name | nothing | Readonly fields are sent; disabled ones are not |
| submit button with a name | action=send | Only the button that was clicked |
Three rows cause most surprises. A range slider and a colour picker always send a value, even when the visitor never touched them, so you cannot tell “chose the middle” from “ignored it”. An unticked checkbox sends nothing, not “no”, so your server has to treat a missing name as unticked. And dates always arrive as YYYY-MM-DD, which is good news, because you never have to guess whether 03/11 means March or November.
What does the browser check, and what does it let through?
Next we typed values a person would call wrong, one key at a time, and asked Chromium whether the field was valid.
| Type | Bad values accepted | Details |
|---|---|---|
| 4 of 6 accepted | Accepted emma@example, emma@example.c, emma..clarke@example.com, emma.@example.com; refused emma@ and an address with a space | |
| url | 3 of 3 accepted | Accepted htps://example.com, javascript:alert(1), https://example, and refused the example.com and www.example.com that people actually type |
| tel | 2 of 2 accepted | call me after 5 and 12 both passed; tel has no format check |
| number | See note | Typing 12,5 sent 125; 12.50 was refused because the default step is 1; 1e3 and -3 passed; letters could not be typed |
| text with required | 1 of 1 accepted | Three spaces count as filled in |
The email check follows the HTML standard's own pattern for addresses, which allows a domain without a dot. So emma@example passes, and so do two dots in a row before the @. The URL check has the opposite problem. It insists on a scheme, so it refuses the addresses people really type and accepts a javascript: link. For a website field, type="text" with inputmode="url" and a check on the server serves visitors better.
The number field is the one to be careful with. In our English-language Chromium, typing 12,5, as much of Europe writes twelve and a half, silently dropped the comma and sent 125. A price of 12.50 was refused, because without step="any" the field only accepts whole numbers, and the error message (“The two nearest valid values are 12 and 13”) confuses people. Use type="number" for counts such as guests or nights. For amounts, use step="any", or a text field with inputmode="decimal" and a check on the server.
Which keyboard does each type open on a phone?
We did not test phone keyboards on real devices for this article, so this part comes from MDN's reference for the inputmode attribute, which we read on 3 November 2026. Email fields usually get a keyboard with the @ key on it, URL fields one with a prominent /, telephone fields a dial pad with digits, the asterisk and the pound key, and inputmode="numeric" a pad with just the digits 0 to 9.
The useful trick is that inputmode changes the keyboard without adding any checks. A postcode, an order number or a one-time code can be type="text" with inputmode="numeric": the visitor gets the number pad, leading zeros survive, and the browser does not turn it into a spinner. MDN is clear that inputmode enforces nothing, so pair it with a check where the value matters. Our checklist for an accessible contact form adds the autocomplete values that let phones fill these fields in.
What reaches the server when the browser check is skipped?
Everything. The browser's checks only run when a person submits the form in a browser. A bot posts to your endpoint directly, and a page with novalidate or a broken script sends whatever is in the boxes. We posted 18 wrong or awkward values from the test above straight to two forms on our local backend.
The form without field checks stored all 18, including javascript:alert(1) as a website and “call me after 5” as a phone number. The form with field checks refused 11 of the 18 with a 422 answer naming the field, for example {"field":"phone","code":"phone"}, and stored nothing. It refused both bad phone numbers, all three bad URLs, abc and 1e3 as numbers, and 4 of the 6 bad emails. It accepted example.com and www.example.com as websites, which is what you want, and also 12.50, 12,5 and -3 as numbers. It let through emma..clarke@example.com and emma.@example.com too, so our email check is looser than the strict rules for addresses.
If you write your own checks in JavaScript as well, our article on React form validation shows how to put the server's answer back under the right field.
Which types should a contact form use?
For most contact and booking forms, the form below is a good start. It uses email and tel for the keyboards, a text field for the website so “example.com” is not refused, date because the format it sends is unambiguous, and number only for a whole count with a minimum and a maximum. If you would rather not write it by hand, the HTML form generator builds one you can copy.
The form posts to Formgong, a form backend that sends each message to your email and Telegram. Under Settings, then Protection, then Field checks, you can mark any field as required or as an email, URL, number, date or phone number, on every plan including Free. Formgong then refuses a post that breaks a check, before anything is stored or counted, and the answer names each field. The two competitor guides we read on 3 November 2026 cover the types but not that step. The Static Forms guide to all 22 input types, dated 31 May 2026, rightly says client checks never replace server-side validation, and the only check it describes its own service making is a honeypot spam check. Formspree's guide to HTML input fields does not say what its servers check. The HTML forms docs list every field Formgong reads.
<form action="https://formgong.com/submit" method="POST"> <input type="hidden" name="access_key" value="fk_your_access_key"> <label for="name">Name</label> <input id="name" name="name" type="text" autocomplete="name" required> <label for="email">Email</label> <input id="email" name="email" type="email" autocomplete="email" required> <label for="phone">Phone (optional)</label> <input id="phone" name="phone" type="tel" autocomplete="tel"> <!-- type="text" + inputmode: people type "example.com", which type="url" refuses --> <label for="website">Website (optional)</label> <input id="website" name="website" type="text" inputmode="url" autocomplete="url"> <label for="date">Preferred date</label> <input id="date" name="date" type="date"> <!-- a count: type="number" is fine; for money or 12.5, use step="any" or inputmode="decimal" --> <label for="guests">Guests</label> <input id="guests" name="guests" type="number" min="1" max="20" step="1"> <label><input type="checkbox" name="newsletter" value="yes"> Send me the newsletter</label> <button type="submit">Send</button> </form>
Did an input type surprise you?
If an input type behaves differently in your browser, or a phone shows a keyboard we did not expect, tell us at support@formgong.com. We will rerun the test with your case and update this page.
Frequently asked questions
Does type=email check that an email address is real?
No. It only checks the shape, and it accepts addresses without a dot in the domain, such as emma@example. Check on the server too.
What does an unchecked checkbox send?
Nothing. Its name is missing from the request, so treat a missing name as unticked. A ticked box without a value sends on.
Should I use type=number for a phone number or postcode?
No. Use type=tel for phones and type=text with inputmode=numeric for postcodes and codes, so leading zeros and spaces survive.
What format does type=date send?
Always YYYY-MM-DD, such as 2026-11-14, whatever date format the visitor's browser shows on screen.
Is browser validation enough?
No. Bots and scripts post to your endpoint without running it, so the server has to check the fields again.
Sources and documentation
Official references for this guide: Formgong: How do HTML forms work? The HTTP request, Formgong: React form validation without a library, tested. HTML forms, where data is stored.
Related guides
- Lovable form submissions to email and Telegram
- HTML contact form without a backend: a working example
- How to send website form submissions to Telegram
- Contact form not sending email? Check where it stops
- Managing website leads in Telegram without a CRM
- Form backend for Lovable, Bolt, v0, Cursor
- Telegram bot for a contact form: build or skip?
- GDPR form backend: 7 checks before you choose
- Lovable form not sending email? 6 fixes
- Netlify Forms not working? React and Bolt fixes
- Stop contact form spam without a CAPTCHA
- GitHub Pages contact form: a working setup
- Mailto Form in HTML: Why It Fails and What to Use
- HTML form to Google Sheets: 2 free methods
- Webflow form submission limit: what to do at 50
- Turnstile vs reCAPTCHA vs hCaptcha for forms
- Contact Form 7 and Elementor forms to Telegram
- Squarespace contact form not sending email?
- Shopify contact form: where do messages go?
- Google Form to Telegram: free Apps Script way
- Wix contact form not sending email? Fixes
- EU / GDPR Formspree alternatives compared
- HTML form action attribute explained
- How do HTML forms work? The HTTP request
- Types of Injection Attacks on Web Forms (2026)
- Indirect Prompt Injection in MCP
- MCP Rug Pull Attack: Detect Tool Changes
- Form without a backend: 7 ways that work
- Thank-you page after form submission (HTML)
- Indirect Prompt Injection Examples (2023–2026)
- Indirect Prompt Injection via Email
- What Is Tool Poisoning in MCP?
- WordPress contact form without a plugin
- Send email from frontend JavaScript
- How to Prevent Indirect Prompt Injection
- Honeypot Form Field: How to Add One That Works
- Contact Form with File Upload (HTML, No PHP)
- Angular contact form without a backend
- Send form submissions to Slack or Discord without Zapier
- Verify a form webhook signature (HMAC-SHA256)
- Contact forms that send nothing: 793 AI-built sites tested
- v0 contact form that actually sends: 3 ways
- How we tested AI-built contact forms, and 12 bugs we hit
- Cloudflare vs Netlify free plan: hosting that never pauses
- EmailJS 412 “Gmail_API: Invalid grant”: reconnect Gmail
- Resend “You can only send testing emails”: verify a domain
- Supabase Edge Function blocked by CORS policy: 3 causes
- Formspree “Form not found” and other errors: fixes
- Web3Forms errors: “Invalid access key” and 403 explained
- How to add customer reviews to your website for free
- Getform not working? “This form has been deleted” and more
- Next.js contact form not working? 6 errors, reproduced
- Webflow form not sending email? What to check, tested
- FormSubmit not working? “This form needs Activation” fix
- Contact form “TypeError: Failed to fetch”: causes and fixes
- WooCommerce product enquiry form
- Contact Form 7 vs WPForms
- Gravity Forms alternative free
- WordPress contact form block
- 535-5.7.8 Username and Password not accepted (Gmail)
- 535 5.7.3 Authentication unsuccessful: Office 365 SMTP
- Nodemailer “Missing credentials for "PLAIN"”: the fix
- Nodemailer “Greeting never received”: port 465 fix
- Nodemailer SSL “wrong version number”: the port fix
- Nodemailer “self-signed certificate in certificate chain”
- Nodemailer ECONNREFUSED 127.0.0.1:587: missing SMTP host
- SendGrid “authorization grant is invalid”: 401 fix
- Mailgun 401 Forbidden: why the API rejects your key
- “Edge Function returned a non-2xx status code”: the fix
- Next.js “Body exceeded 1 MB limit”: Server Action fix
- Unexpected token '<', "<!DOCTYPE "... is not valid JSON
- “TypeError: Body is unusable”: body has already been read
- Turnstile “timeout-or-duplicate” and other siteverify errors
- Turnstile vs hCaptcha vs reCAPTCHA: speed and size tested
- Judge.me reviews not showing on Shopify: how to fix it
- Judge.me review carousel not showing: how to fix it
- Yotpo reviews not showing on Shopify? Check the app embed
- Loox reviews not showing on product page: how to fix
- Shopify reviews not showing: what to check first
- How to show reviews on Shopify
- GDPR for website forms: what each type of form needs
- WooCommerce reviews not showing: how to fix it
- Stamped.io reviews not showing on Shopify: how to fix it
- Etsy reviews not showing: why and what to do
- Trustpilot widget not loading: how to fix TrustBox
- Yotpo problems in 2026: what merchants report
- Contact Form 7 “error trying to send your message” fix
- Elementor form “Your submission failed because of an error”
- Framer form not sending email or not working: what to check
- Carrd contact form not working: plans, spam and errors
- Google review link not working: what customers see and why
- tawk.to widget not showing on your website: causes and fixes
- How to add questions and answers to your product page
- “Failed to send a request to the Edge Function”: fixes
- Next.js “Failed to find Server Action”: what it means
- Brevo “unauthorized: Key not found” 401: the fix
- Amazon SES “Email address is not verified”: the fix
- Shopify contact form not working: how to fix it
- Judge.me alternative for WooCommerce after the 2025 shutdown
- Free WooCommerce review plugins compared on the free version
- WooCommerce review reminder emails without a paid plugin
- Add Voice Recording to a Website Form
- Contact Form 7 spam: how to stop it
- WPForms not sending email: how to fix it
- Contact form emails going to spam: how to fix it
- HTML form not submitting: how to fix it
- Contact form not working: how to find the fault
- Webflow form spam: how to stop it
- Website form to Notion: how to set it up
- Website form to WhatsApp: what works and what does not
- What 1-star reviews say about AI support chatbots
- Which free form backend gives you the most submissions?
- Elfsight reviews widget not showing? Check the view limit
- Next.js contact form backend vs Server Actions
- Review stars not showing in Google search results
- How to stop duplicate form submissions
- How to see which form leads came from ChatGPT
- What happens when a form webhook fails
- When to send a review request email after an order
- How to collect video testimonials for free
- Add contact form sign-ups to Mailchimp or Klaviyo
- How to migrate from Formspree without losing submissions
- How to get a Google review link for your business
- What is a headless form backend?
- Is it safe to put a form access key in your HTML?
- AI chatbot that answers only from your website
- Minified React error #441 in Next.js
- Squarespace product reviews after Judge.me
- Accessible contact form checklist for WCAG 2.2
- How to ask a client for a testimonial by email
- How to respond to negative reviews, with examples
- 429 Too Many Requests on a contact form
- MCP server for forms in Cursor and Claude
- Can you offer a discount for a review?
- Do EU stores have to say if reviews are verified?
- Webflow form backend options compared
- How to add review schema JSON-LD to a product page
- How to turn a customer review into an Instagram post
- How to make a QR code for Google reviews
- Live chat or chatbot for a small business website
- Why people abandon your contact form halfway
- Which form backend do AI assistants pick? 54 answers
- PHP mail() not sending email, even when it returns true
- What “Failed to fetch” means, tested in three browsers
- 405 Method Not Allowed when you submit a form
- Send a contact form to more than one email address
- What is review syndication, and who needs it?
- How to save HTML form data to a database
- NetworkError when attempting to fetch resource
- Send product reviews to Google Merchant Center
- PHPMailer not working on a live server
- AI review reply generator: does it help?
- React 19 contact form with useActionState
- Astro Actions or a form backend?
- Is no-reply@wixsiteautomations.com legit?
- Where to find the Judge.me review widget code
- AI review summaries: what shoppers actually see
- Photo reviews for WooCommerce, and the GPS inside them
- Review request email templates you can copy
- Reviews in AI search: what ChatGPT and Perplexity cite
- Lead capture form with UTM tracking, built and tested
- Form design best practices, with our own form data
- Client intake form template with file upload
- What is social proof? Meaning and examples
- What is user-generated content (UGC)?
- Benefits of negative reviews for your store
- How to get your first reviews as a new store
- How to use customer reviews in your marketing
- How to get more customer reviews
- React form validation without a library, tested
- jQuery submit form with validation
- reCAPTCHA v3 setup with the server score check
- Shopify social proof that shoppers can check
- HTML file input: accept, multiple, capture and size checks
- How to add hCaptcha to a form, with the server check
- How to add invisible reCAPTCHA to a form
- Bug report form template with browser details
- What the FTC fake reviews rule bans for online stores
- How to show reviews on your homepage
- Do reviews increase sales? What the studies show
- HTML textarea, tested in a real form
- HTML dropdown menu in a form, tested
- Do reviews help SEO? What Google says and shows
- How to add a review carousel people can read
- Product review examples that help shoppers decide
- Which trust badges actually mean something
- Customer satisfaction survey with CSAT and NPS
- JavaScript FormData and what fetch actually sends
- JavaScript form validation without a library
- Server-side form validation and what it catches
- Email validation in JavaScript, tested on 33 addresses
- Zod form validation with FormData, tested
- Store reviews vs product reviews
- How to send review requests through Klaviyo
- How to tag customer reviews by topic and mood
- Custom review form questions worth asking
- Online reputation management for small businesses
- HTML radio button groups and what they send
- HTML label tag and what screen readers hear
- HTML autocomplete attribute, tested with Chrome autofill
- HTML fieldset and legend, and what disabled leaves out
- HTML button tag and what a form button sends
- Vite contact form that still works after the build
- How to test a contact form, end to end
- How to embed a Google Form, and what it loads
- Customer feedback questions that get real answers
- How to convert a file to base64 in JavaScript
- FilePond with a form backend, and when to skip it
- Bootstrap form validation and server errors
- Tailwind form validation, tested in three browsers
- Donation form in HTML, and where the payment goes
- How to ask for a review in person or by text
- Which review sites matter for your business
- What are customer reviews, and which kinds count
- Online review statistics, checked at the source
- Best review app for Shopify and WooCommerce
- Why Gmail sends your self-hosted mail to spam
- htmx contact form that sends to another domain
- AI form builders tested, from prompt to sent form
- Headless WordPress forms with Contact Form 7, tested
- React Hook Form watch vs useWatch, and what gets sent
- Elfsight widget not working? It vanishes when views run out
- Jotform not sending emails? Check Jotform's bounce list
- Typeform not working? A white box means a blocked script
- Positive review response examples that don't sound copied
- How to remove a Google review when you can't delete it
- Google reviews not showing up? 8 causes to check in order
- Is buying Google reviews illegal? Even a review swap counts
- Which reviews can you hide? A review moderation checklist
- Average star rating: what 4.8 from 5 reviews means
- Reviews on a product page: where and how many to show
- SaaS testimonials: 3 of 27 had a number in them
- Do reviews reduce returns? Not when they're too good
- Testimonial examples for business: what makes one believable
- Testimonial questions to ask clients, by type of business
- Testimonial page design: a page or a section?
- Testimonial advertising rules: what the FTC requires
- Form submission canceled because the form is not connected
- Input type date format dd/mm/yyyy: what you can change
- How to disable textarea resize, or allow only vertical
- How to prevent Enter from submitting a form
- form.submit() vs requestSubmit(): what submit() skips
- Custom HTML checkbox CSS that doesn't break required
- How to reset a form after submit, and what reset() keeps
- Input type number maxlength not working? What to use
- How to create an HTML form, step by step
- Best form builder: free plans and branding, checked
- Best WordPress contact form plugin: 10 free ones compared
- How to increase form conversion rate: start with the count
- Form backend vs form builder: which one do you need?
- WordPress contact form not sending email? 3 plugins tested
- Contact Form 7 webhook? Turning it on switched our email off
- Gravity Forms webhook: what it sends and the URLs it rejects