This is a submission for the DEV April Fools Challenge
What I Built
Please Verify is a satirical single-page web app disguised as a legitimate SaaS verification system — clean design, professional fonts, a fake browser chrome — that traps you in an endless loop of the internet's most infuriating UX patterns.
It looks like a real product. It has trust badges. It says "Secure. Simple. Streamlined." It is none of these things.
🔗 Live demo: https://please-verify-app.web.app
💻 GitHub: https://github.com/watts4/please-verify
The gauntlet, in order:
Cookie Consent (×4) — Four rounds of increasingly unhinged cookie categories. Round 4 includes "Void Telemetry" ("The void remembers. The void consents on your behalf.") and "Final Form Data Collection" ("Acceptance is non-reversible across all planes of existence."). All categories must be accepted to continue. Every time.
Age Verification (animal years) — Select your spirit animal and calculate your age in that animal's measurement system. Dog: ×7. Cat: odd years ×15, even years ×8 (parity modifier applied). Tortoise: age × π × 4. Elephant: convert to base-8 first, then ×3. Wrong answer? New animal. After 3 failures, we give up verifying your age and proceed anyway.
Terms of Service (procedural, never-ending) — 30 clauses that load in batches as you scroll. You cannot click "Accept" until you've read everything. When you finally do click it — the checkbox unchecks itself and Section 47.3 appears, which requires you to scroll through the entire document again before agreeing. Clauses include "No Warranty of Vibe" and "Governing Law: a jurisdiction to be determined at a later date."
CAPTCHA (25% pass rate) — Select all images matching increasingly impossible instructions: "Click all squares that are lying." "Identify the squares that feel like a Wednesday." You have a 25% chance of passing regardless of what you select. After 3 failures, Enhanced Verification activates (a loading spinner, then resets).
Password Creation (progressive impossible requirements) — Requirements reveal themselves as you type, escalating from "8+ characters" to "must contain a haiku," "must evoke the feeling of a Tuesday afternoon," and "must not begin with the letter you are currently thinking of." The last character also deletes itself every 3 seconds.
Create Account — A normal-looking form. Your password field is blank. "Not transferred for security reasons."
Sign In → 418 I'm a teapot — Incorrect password (always). "Reset it here" → link expires in 3 seconds → "Your account doesn't exist" → Create New Account → repeat. The server's response:
HTTP 418 I'm a teapot — server refuses to brew authentication.
Demo
Code
watts4
/
please-verify
A satirical web UX obstacle course — cookie consent hell, animal-years age verification, procedural ToS, impossible passwords, circular login loops.
React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Oxc
- @vitejs/plugin-react-swc uses SWC
React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.
Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...…Stack:
- React + TypeScript + Vite
- Tailwind CSS v3
- Google Gemini API (for procedurally-generated ToS clauses)
- Firebase Hosting
Key files:
-
src/components/CookieConsent.tsx— 4-round cookie consent with 20 categories of nightmare tracking -
src/components/AgeVerification.tsx— Spirit animal calculation engine (6 animals, 6 formulas) -
src/components/TermsOfService.tsx— Scroll-triggered clause loading + Gemini integration + self-unchecking checkbox -
src/components/Captcha.tsx— 25% random pass rate, 10 rotating impossible instructions -
src/components/PasswordCreation.tsx— Progressive requirements + 3-second character deletion timer -
src/components/Login.tsx— Circular authentication trap + HTTP 418
How I Built It
The whole thing is a React state machine. App.tsx tracks a step variable cycling through: landing → cookie → age → tos → captcha → password → create-account → login. Each component calls an onComplete() prop when it decides you've suffered enough.
The step counter lies. Steps skip from 3 to 5 (no Step 4), repeat Step 5 twice, then go to "Step 8 of 7" and "Step 9 of 7". This was deliberate — a small detail that makes it feel like something has gone wrong with reality.
Google Gemini for the ToS: On mount, TermsOfService.tsx hits gemini-1.5-flash with a prompt asking for 5 absurd legal-sounding clauses. The result replaces the first batch of fallback clauses, making each visit's terms of service unique. If no API key is set (open-source deployment), it falls back to 30 handwritten clauses that are somehow funnier.
// The API call is client-side — key is in .env, never committed
fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${key}`, {
method: 'POST',
body: JSON.stringify({
contents: [{ parts: [{ text: 'Generate 5 absurd, legal-sounding Terms of Service clauses...' }] }]
})
})
The self-unchecking checkbox: When you finally reach the ToS checkbox, clicking it sets rereadRequired: true, unchecks itself, and injects Section 47.3 at the bottom of the document. The "Accept & Continue" button becomes disabled until you scroll to the bottom again. This works via a scroll event listener that sets rereadScrolled: true only when scrollTop + clientHeight >= scrollHeight - 40.
Cookie consent architecture: It's just 4 separate arrays of CookieCategory objects with a round counter. The trick is that the "Accept All" button only sets all categories to true — you still have to click "Save & Continue" separately. And all non-required categories must be accepted before continue works. This creates just enough friction to feel authentic.
The 418: HTTP 418 I'm a teapot is RFC 2324, written by Larry Masinter in 1998 as an April Fools joke about a Hyper Text Coffee Pot Control Protocol. It was never removed from the HTTP spec. The server in Please Verify refuses to brew authentication — which is only appropriate, because there is no server, there is no authentication, and there never was.
Prize Category
Best Ode to Larry Masinter — The HTTP 418 I'm a teapot error is displayed on every failed login attempt: "Server responded: 418 I'm a teapot — server refuses to brew authentication." It's fitting: RFC 2324 is itself a satire of over-specified internet protocols. Please Verify is a satire of over-engineered user verification flows. Larry Masinter would understand.
Best Google AI Usage — Gemini 1.5 Flash generates the opening ToS clauses on each visit. The prompt asks specifically for "absurd, legal-sounding" clauses — and Gemini delivers: "The Company reserves the right to interpret your inaction as action, your silence as consent, and your confusion as a binding agreement." Each visitor's terms are unique.
Built in one session for the DEV April Fools Challenge 2026. The site does nothing. It verifies no one. It has never successfully authenticated a single user. That was always the plan.
Top comments (0)