Build1 distinct publisher3 min readPublished
The rig is one Cloudflare Function, one D1 table and an inline script. The part that makes the data mean anything is a movement and duration filter on pointerup, tuned by hand on a site whose only conversion is a phone call.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The dead-tap detector is a single line of DOM traversal. It calls `closest` against `a`, `button`, `input`, `select`, `textarea`, `summary`, `label` and `[role="button"]`, and when nothing matches, it posts the coordinates as a dead tap [10]. That line only produces a signal because of the filter sitting above it. Feed it raw `pointerup` and any scroll that happens to end with a thumb resting over a paragraph becomes a dead tap, because every scroll gesture terminates in a `pointerup` [6]. Dead-tap precision is bounded by the tap definition [3], which is why the author treats deciding what a tap is as the hard part of the build [5].
The definition is two thresholds measured from `pointerdown`. Discard the event if either axis moved more than 12 pixels, discard it if more than 600 ms elapsed, and ignore anything whose `pointerType` is not `touch` [7]. The rage detector then runs on that filtered stream and needs three entries in its window before it can fire, which puts the average gap between consecutive taps under 450 ms [1]. A double-tap cannot trip it.
Coordinates are stored as percentages rather than device pixels: x against viewport width, y against full document height including scroll offset [9]. Round to whole percent and one percent is 3.6 px on a 360 px viewport and 4.3 px on a 430 px one [2]. So the rounding discards less positional detail than the 12 px of movement the tap filter already tolerates [7]. Right order of operations.
Two flags on the listener do real work. `capture: true` means it runs before any handler that might call `stopPropagation`, so a tap on a component that swallows its own events is still counted [8]. `passive: true` keeps the listener off the scroll critical path [8]. That is careful work, and it is the sort of detail that decides whether telemetry costs you frame budget.
Every detector holds its state in page-lifetime JavaScript variables, so with no cookies and no localStorage there is nothing that recognises a returning visitor [4]. That is the trade for having no consent banner [3]. Session stitching is not a feature you can add later without changing the legal posture of the whole thing.
For the 12 px and 600 ms pair to carry to your page, two things have to be true. Your interactive targets have to be spaced far enough apart that 12 px of slop does not straddle two of them. And your content must not invite slow, deliberate touches: a map, a slider or a drag handle generates exactly the gesture the 600 ms cutoff throws away [7]. On a page whose only interactive element that matters is a `tel:` link, those constraints hold easily. On a product configurator they do not, and the pair needs re-tuning against real gestures before the dataset means anything.
One note on reading the source: the published snippet cuts off inside `document.querySelectorAll('a[href^=`, so the exact set of observed elements is not in the post [16]. And the failure this whole apparatus exists to catch is a phone number styled to look tappable that was never wrapped in a `tel:` link, which passes every design review it is ever shown [11].
Ranked by verification strength, evidence, and original report placement.
The author runs the website for a small emergency locksmith service in southern Germany and built the mobile UX measurement himself.
On that site roughly half the traffic is mobile and the entire business outcome is a single phone call.
The implementation is one Cloudflare Pages Function, one D1 table and one inline script, with no cookies, no localStorage and no consent banner.
The author states that pageviews and bounce rate cannot answer whether the phone number was ever on screen, whether the visitor tapped something that was not tappable, or whether they had to pinch-zoom to read it.
The author identifies deciding what counts as a tap as the genuinely hard part of the project.
A naive implementation that listens for pointerup and records a tap produces garbage data on a real phone, because every scroll gesture, every swipe and every long-press on an image ends with a pointerup.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · September 1, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
An internal app pushed its reporting reads into the browser rather than resize D11 distinct publisher
product
A 2x LLM bill is not a bug report: token spend is an observability problem1 distinct publisher
security
ONCD stakes Texas water security on six months of donated vendor red teaming1 distinct publisher
security
PavinLoader: the lures keep changing, the MSBuild stage does not1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Code you can read, results you cannot
Every mechanism in this story is verifiable on the spot, because the handlers are pasted rather than paraphrased: the 12-pixel and 600 ms guards, the three-tap window, the 1.15 scale trigger, the 0.6 observer threshold. A reader can reason about the logic without trusting the author at all. What never appears is a single row out of that D1 table — no dead-tap counts, no zoom positions, no call rate before or after a fix — so the design is documented and its effect is not. The one place the story contradicts itself, over whether the observer's selector is shown, resolves against the summary and in favour of the printed code.
One site, one author
The install base described is a single locksmith website in southern Germany, run by the person writing about it. No repository, no package, no second deployment, nobody else quoted as having tried the thresholds. That is enough to call the technique real and running, and far too little to call it adopted.
Restrained, with unearned certainty about the numbers
The post sells nothing and says so quietly, which keeps this close to honest. The overreach is narrow and specific: '12 pixels, 600 milliseconds... those two numbers are the difference between a usable dataset and noise' is asserted, never demonstrated, and the same goes for the dead-tap cluster framed as a conversion bug you would otherwise never find. Plausible, undoubtedly useful, hand-tuned on one site — presented as settled fact.
No product behind it
The author is the customer here: he runs the site, wrote the script, and has no vendor, package or paid tier riding on whether anyone agrees with him. Cloudflare gets a free showcase and the post gets its author reputational credit for a clean build — real but mild pressures. The stronger distortion is structural rather than commercial: a build log written by the builder has no reason to publish the run where the thresholds misfired.
Checkable logic, unchecked practice
Confidence splits down the middle. That this code does what the post says it does is easy to believe, because it is on the page. That the constants generalise past one German locksmith site, or that a storage-free beacon really escapes consent obligations, rests entirely on one practitioner's judgement with no corroboration anywhere in our coverage — and the discrepancy over the observer selector is a reminder to read the snippets rather than the summary.