Example#
Usage#
Use a honeypot and a timestamp on public forms to turn away most spam bots without a CAPTCHA. The honeypot is a field people never see; the timestamp records when the form appeared. checkSpam on the server rejects a filled honeypot or a send faster than 2.5 seconds.
Honeypotsits off-screen (notdisplay: none, which bots skip), holds a labelled field "Leave this field empty", is out of the tab order and has autocomplete off.FormTimestampfills a hidden input with the time on mount, on the client, so static pages do not stamp the build time.checkSpam(formData)returns{ spam, reason }; a missing timestamp is not spam.
Anatomy#
- Honeypot: an off-screen
div.mk-honeypotwith a labelled text input, hidden from assistive tech and out of the tab order. - Timestamp: a hidden input named
_t, filled when the form mounts.
Neither prints anything, so there is nothing to draw.
Volume#
Neither prints anything, so both are the same at every volume.
Content#
- The honeypot's label, "Leave this field empty", is the only copy, and only a bot ever reads it.
Do and don't#
Do
<Form action="/api/quote">
…fields…
<Honeypot />
<FormTimestamp />
</Form>Don't
A CAPTCHA on a three-field quote form.
Accessibility#
- The field is off-screen,
aria-hiddenand out of the tab order; people never meet it. - On the server,
checkSpam(formData)flags a filled honeypot or a submit faster than 2.5 s.
| Keys | What happens |
|---|---|
| Tab | Never stops here: the field is out of the tab order and hidden from assistive tech |
The colour pairs it prints, with their contrast on both papers:
It prints no text of its own (art layer or layout only), so it has no pair to check.
Props#
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | company_website | The field's name (default `company_website`, `checkSpam`'s default). |
label | string | none | The label bots read (literal copy). |
idPrefix | string | mk-hp | The input's id prefix (default `mk-hp`): two forms on one page pass one each, as QuoteForm does (D-N101). |
Tokens#
It reads no --mk-* token of its own: it lays out the components inside it.
Changelog#
Arrived in 0.1.0.
- The reading layer's controls, overlays, forms and visitor prefs (P2-T1 to P2-T5): every Button is the comic hit key, with IconButton, Link and Tooltip; Input, Textarea, Select, Checkbox and CheckboxGroup, Radio and RadioGroup, Switch, Slider with the ruler, RulerReadout and SegmentedControl; Dialog, Drawer, NavSheet, Tabs, Disclosure, Faq and faqJsonLd on Base UI 1.9 where the platform falls short; Field, Fieldset, Form with the site's inline validation, ErrorSummary, Callout, Honeypot, FormTimestamp and QuoteForm; PrefsScript under 1 KB, usePref and setPref with cross-tab sync, ThemeToggle and the visitor VolumeDial; VisuallyHidden.