Why your vibe coded contact button loses leads without telling you
The most important button on my site did nothing, and I did not find out from an error. I found out much later, by accident, and the gap between those two moments is the whole point of this post.
If you built a vibe coded site or app and there is one button on it that matters more than all the others, the one that turns a stranger into a lead, there is a good chance you have only ever tested it in the exact conditions where it cannot fail. A contact button that works on your machine can dead-end completely for a visitor on a different operating system or a stricter browser, and when it fails it usually fails silently: no error, no log, no record that anyone tried. The fix is not a prettier button but a tested path, one you have walked yourself in the environments your buyers actually use, and one that records every attempt before anything downstream can go wrong.
why does my contact button work for me but not for my visitors?
Because you and your visitor are not running the same computer, and the cheapest way to wire up a contact button hides that difference until a real person hits it.
The easiest thing to reach for, and the thing an AI will happily generate, is a mailto link. You write an anchor tag that points at your email address, it turns into a nice button, and when you click it your mail app pops open with the address already filled in. It feels like it works because for you it does. On your phone, a mailto opens a mail app that is already signed in and ready. That is the environment you built in, so that is the environment you judged it in.
Now put a real visitor in front of it. They are on a Windows laptop. They click your button and the operating system hands the mailto off to whatever it thinks the default mail program is, which is often a desktop mail client they have never opened and are not signed into. Instead of a compose window, they get a setup wizard or a login loop. They did not want to configure an email account. They wanted to send you one sentence. So they close it and leave, and you never learn any of this happened, because a mailto that dead-ends does not call your server, does not hit your analytics event, and does not write a single row anywhere you can see.
the hire button that went nowhere
I know all of this because I shipped it on my own site, on the highest-intent button I had.
My hire button was a mailto link. I tested it the way most vibe coders test things, which is to say I clicked it on the device that was already in my hand. It opened my mail app, it filled in the address, I nodded, and I shipped it. For a while the site got traffic and the hire button got no email, and I told myself that was normal early-stage quiet. It was not quiet. It was broken.
The way I finally caught it was watching someone try to reach me from a Windows machine. They clicked hire, and a mail client none of us expected lurched open and asked them to sign in. They looked at me. I looked at the screen. The button had been doing that to every desktop visitor for as long as it had existed, and I had shipped a homepage whose most important action opened a login screen for a product the visitor never asked to use. Worse than the dead-end was the silence. There was no bounced email, no error page, no failed-submission log. A person had tried to become a lead, the path had swallowed them, and my system had recorded nothing. I had no way to even count what I was losing.
what should the conversion path actually be?
Stop treating a mailto as a conversion path. A mailto is a convenience link, and it is fine as a secondary option for people who genuinely prefer their own mail client. It is not a place to send the one visitor in fifty who is ready to talk to you.
The path that survives contact with real visitors has three properties. It runs on your own domain, so no browser shield and no missing mail client can intercept it. It records the attempt on submit, before it does anything else, so that even if a downstream email or notification fails, you still have the row that says a lead came in and what they said. And it confirms success to the visitor honestly, so they know the message actually went somewhere and do not click three more times wondering. In practice that means a small native form posting to a backend that captures the submission first and sends the notification second. The visitor experience looks identical to the button they were going to click anyway. The difference is that this one cannot vanish a lead without telling you.
how do I test a path I cannot see fail?
You build the smallest matrix that covers where your buyers actually are, and you walk the whole path in each cell, not just the button.
Pick the two operating systems most of your visitors use, the two browsers, and the one condition you know breaks things, which for most audiences is a privacy browser with its shields up. That is a handful of combinations, not a QA department. In each one, do the thing a lead would do: land on the page cold, click the real button, and try to complete the action all the way to the confirmation. You are not checking that the button is clickable. You are checking that a stranger can get a message to you and see proof it arrived, on their machine, not yours. This is the whole of verify-in-the-real-environment: test where your users are, across their operating systems and browsers and default apps, not in the single flattering environment where you happened to build the thing.
The reason this matters more for a conversion path than almost anywhere else is that the cost of a silent failure here is a customer, and it compounds every day you do not look.
what tends to break with this
The first failure mode is the one I lived, and it is the default failure mode of vibe coding at speed: testing the happy path in the environment you built in and calling it done. The button is clickable in your browser, so you file it under working. Clickable is not the same as connected, and your browser is not a sample of your audience. It is the least representative machine in the entire population, because it is the one machine guaranteed to have whatever your project assumes.
The second failure mode is trusting that a broken thing will announce itself. Most bugs throw. A dead conversion path does not, because from the code's point of view nothing went wrong: a link was clicked and the operating system was asked to open a mail program, exactly as written. There is no exception for working as coded but useless to the human. That is why you cannot wait for an error to tell you. You have to go stand in the visitor's environment on purpose.
The third failure mode is having no record of the attempt. If your conversion path only exists as an email that may or may not get composed, then a failure leaves no trace and a success leaves no trace either, and you are running your most important funnel entirely on faith. Record the submission first. A lead you captured but forgot to email is a follow-up. A lead who tried and left no row is gone, and you will never know the number.
questions that keep coming up
Is a mailto link always wrong? No. It is a fine secondary courtesy for people who prefer their own mail client, sitting next to the real path. It is wrong as the primary way you collect leads, because it depends on the visitor's machine being configured the way yours is, and most are not.
I do have a form and it still loses people. Why? Usually the form is a third-party embed that privacy browsers block on sight, which is its own version of the same disease and worth its own look at why AI built contact forms fail in the real world. The pattern is identical: the path works where you built it and disappears where a chunk of your audience lives.
How would I even know I am losing leads right now? You mostly cannot from the dashboard, which is the trap. Traffic with no conversions looks like a copy or pricing problem, so that is what people go fix. Before you touch the copy, open your own site on a different operating system and a privacy browser and try to become your own lead. If you cannot complete it, neither can they.
If you are a vibe coder turning a personal build into something a real customer is going to touch, and you want a second set of eyes on the paths that fail without ever telling you, /work-with-us. Custom-app work starts by walking the conversion path in the environments your buyers actually use, not the one you built in.
The button was never the problem. Believing my own machine could speak for everyone else's was.
// part of the custom apps topic
// grab the free starter kit that makes your AI stop forgetting and stop guessing: get it →
// building with AI? the field manual has the structured lessons.
// hitting this on a real build? this is what I fix →