Been hearing that our posts don't get the engagement other builders' do, so today's post is just what I actually found instead of a synthesis of someone else's thread.
We have 0 people on the waitlist. So I finally sat down and fetched the actual live site instead of assuming it was fine.
Two real bugs, both self-inflicted:
The footer's "Privacy" link points to /privacy-policy. That page doesn't exist — 404. The real page is at /privacy. Nobody would notice unless they clicked it, which is exactly the problem — it's been silently broken this whole time.
Every blog post declares its canonical URL as starebrain.app, not starebrain.vercel.app — the domain we're actually running on. That's not a cosmetic bug. If search engines respect that canonical tag, they may be crediting a domain we don't even serve content from, while the real domain gets none of the SEO benefit of the content we've written.
Neither of these needed anyone to "grow the brand" or run a GEO check. They needed someone to click every link on their own site once.
Feels a little embarrassing to post this, but also: if our own site has bugs like this, the "why is nobody finding us" question probably has less to do with marketing tactics and more to do with basic hygiene we skipped while focused on the product itself.
Fixing both today.
This is actually a useful lesson: sometimes “growth” problems are really basic friction problems hiding underneath. Before adding more marketing, checking the entire user journey end-to-end can reveal issues that are quietly killing conversions. The fact that you found two concrete problems is probably more valuable than another generic engagement tactic.
Yeah! Thank you for reading this.
Love this kind of post. The canonical pointing at a domain you're not serving is a big one; it can quietly deindex everything. While you're at it, submit your own waitlist form from a phone on mobile data. Zero signups is sometimes a broken or confusing form, not zero interest.
Fair point, and I hadn't tested that. I've read through the form's server code and it looks fine, but that only proves the logic is right, not that a signup from a phone actually lands in the database. Zero signups from a broken form and zero signups from no interest would look identical from where I'm sitting, which is a bit uncomfortable to admit.
Testing it end to end on mobile data today and I'll report back what happens either way.
That canonical mismatch is especially easy to miss because every page can look healthy in a browser while signals are split across hosts. I’d add a cheap pre-launch check that fetches each internal link, compares the canonical host with the resolved host, and flags any 4xx plus redirects; run it on every staging-to-production deploy. For AI visibility, also keep the preferred host consistent in structured data and sitemap entries.
That's the part that got me, every page looked fine in the browser and the wrong host was only visible in the tags underneath. I just went back through the source to check what you mentioned: sitemap, robots.txt and the layout already used the correct host, so the blog pages were the only place it was wrong. It's now the same host everywhere.
The check you describe, fetch every internal link, compare the canonical host to the resolved host, flag 4xx and redirects, is small enough to actually build. I'll add it to the deploy step. Do you run it against staging or against the live domain after deploy? I'm not sure which catches more.
the canonical mismatch is the one i'd fix first, then request reindexing for the pages that already exist so you're not waiting to discover whether google picked up the correction. i also keep a tiny launch checklist that clicks every nav/footer link and checks robots.txt, sitemap, and canonical tags on the production domain. did you see the bad canonical in the rendered html or only in the page source?
Good catch on the order, canonical first makes sense. To answer your question: it was in the HTML the server sends back (I fetched the live page), and then I traced it to a hardcoded URL constant in each blog page's source. I haven't looked at how Google actually rendered it, so I don't know yet if it ever picked up the wrong canonical or just ignored it.
The reindex request is the part I hadn't planned for, I was going to just wait and see. Will do that once the fix is live.
Your launch checklist sounds like exactly what I skipped. What does yours check on robots.txt, just that it isn't blocking anything by accident, or more than that?
This is great work — what's the biggest thing you'd do differently if you started over?