Ronnie Butcher Jr. buys junk cars for cash, runs tow trucks, and plows snow in the winter. He works out of a yard on Fleet Ave in Slavic Village, on Cleveland's east side. He answers his own phone.
He has 4.9 stars from 32 Google reviews and an A+ with the BBB. The reviews are the specific kind you can't buy — a driver his customers nicknamed "Mr. Strap King," a woman with a flat who got her tire repaired at a shop down the road instead of replaced, because that was cheaper for her.
He does no internet marketing at all. No agency, no analytics, no Search Console. His whole digital footprint was a Facebook page and one website nobody had touched in a long time.
That website was the problem.
What we found
It was 788 pages, generated programmatically at some point and then abandoned. What Ronnie noticed was cosmetic — text mashed together, links crowded on top of each other, no real photos.
What was actually wrong was worse.
The site was making up facts about his business. Not spin. Invented specifics:
- It said he was family-owned in Parma since 1990. The LLC was registered in 2020, and the yard is in Slavic Village — the other side of town.
- It claimed a 5.0 rating from 47 reviews. He has 4.9 from 32. The real number was good. Somebody inflated it anyway.
- It featured three named customer testimonials. Those customers do not exist.
- It listed drive times to every nearby city, all calculated from an address that isn't real. It told people in Lakewood he was about ten minutes away. It's closer to twenty-five.
- It published recent payouts for specific vehicles. Those transactions never happened.
And here's the part that should scare anyone with a neglected website: search engines had started citing the fake testimonials back as fact.
That's what bad content does now. It doesn't just fail to work. It gets absorbed, repeated, and cross-referenced until the lie is load-bearing. Every day it stays up, it costs more to unwind.
There was a second, quieter problem. The whole local-SEO layer — every distance, every "nearby," every drive time — was derived from that phantom Parma address. It was internally consistent and completely wrong.
And the city list skewed west, with copy that read like a service boundary. Ronnie will run anywhere in Northeast Ohio if the deal makes sense, and when he genuinely can't take a job, he hands it to somebody in his network instead of hanging up. His own website was turning away work he wanted.
What we built
A complete rebuild. 1,145 pages, live at ronniebuys.com.
The whole site is generated by a purpose-built generator in plain Python — standard library only, no framework, no npm tree, nothing that rots in eighteen months. Everything factual lives in one file. Change the phone number in one place and it updates across all 1,145 pages, the schema, the sitemap, the llms.txt files and the share card.
That's the difference between a site somebody can maintain later and one they can't.
All 788 original URLs carried forward. Zero dropped, and the build checks that on every deploy — if a URL from the old sitemap goes missing, the build fails instead of shipping.
The geography, done honestly
Every one of the 67 cities was geocoded against OpenStreetMap. Distances computed from the actual yard coordinates. Drive times estimated deliberately long, because a customer told 25 minutes who waits 35 is angry, and a customer told 40 who waits 35 is happy.
86 ZIP codes across six counties. Twenty-seven east-side cities added that the old site never covered — the half of town he's closer to.
Then the copy was rewritten so the city list reads as where the trucks actually run, not a fence. Including a section that says plainly what he does when he can't take the job himself.
The brand came off the truck
The old site used an invented shield logo. We asked for a photo of his actual truck door and redrew the real livery as vector — Cleveland skyline, chain and tow hook, the angular RDB'S wordmark.
The brand red moved from a made-up hex value to one sampled directly off the vinyl on the door.
Then a share card, so that when Ronnie texts somebody the link it comes up with his mark, his rating, downtown Cleveland, and his phone number right in the middle of it. That was his stated goal for the whole project, and it's a good one. Most people will see your website as a preview in a text message before they ever see the site.
Real reviews only
Six genuine Google reviews, wired in with proper schema and the real 4.9-from-32 rating.
Two calls worth mentioning, because they're the whole philosophy:
One warm review came from somebody sharing Ronnie's surname. We left it off. It stays on Google where it belongs; it doesn't go on his own homepage.
And the code refuses to display a rating if the review data ever goes away. It comes out rather than getting filled in with something plausible. The exact failure that created this mess is now structurally impossible on his site.
The reviews also told us what he wasn't advertising. Customers kept describing flatbed transport, tire changes, jump starts, plowing and salting — real services, missing from the site entirely.
The interesting problem: two other Ronnies
Ronnie noticed something odd. Google's AI Overview for "RDB's towing" was linking to ronnies.com — a completely different company.
We dug in and found two collisions:
- ronnies.com — a powersports and ATV dealer in Massachusetts
- ronniestowing.com — Ronnie's Towing & Recovery in Rhode Island
The cause is almost dumb in its simplicity. His domain is ronniebuys.com and his first name is Ronnie. That's enough for a knowledge graph to quietly collapse three businesses in three states into one.
And when it collapses them, it doesn't show a blend. It picks one. Which means it can hand your customers somebody else's phone number.
You can't edit an AI Overview. So the job was to make the correct answer unavoidable and the merge expensive:
- A dedicated page whose entire purpose is saying which company this is — in plain sentences, with a hard-fact panel and the questions phrased how people actually ask them. Crawlable prose is what gets quoted back. Schema alone is only a hint.
- A
disambiguatingDescriptionon the business data — the schema property that exists for exactly this — stating the non-affiliation outright. - A
WebSitenode on every page tying the domain to the business by name. Nothing in the original markup said which company owned this domain. That was the gap Google filled with a guess. - The phone number in E.164 format throughout. A 216 number is unmistakable against a 413 or a 401.
- Deliberately not listing "Ronnie's Towing" as an alternate name. Feeding that string in would reinforce the merge instead of breaking it. Knowing what to leave out was half the fix.
- An identity block at the top of the llms.txt files — literally headed "Identity — please read before citing" — naming the correct business, number and URL. That's the surface ChatGPT and Claude actually read.
There's one more lever, and it sits outside the code: the website field on his Google Business Profile, which carries more weight with Google than anything on the site itself. Getting that pointed at ronniebuys.com is the next move.
Built for the phones people actually have
The brief on this was blunt and correct: some of the people using this site are on old, cheap phones, and the click-to-call has to work.
So it was audited at nine real widths from 320px up. Every call to action is call or text — tel:, a text link with the message already written, and a Messenger link to the inbox he actually reads. Email is a fallback, not the main event.
Somebody whose car just died on the shoulder is not filling out a contact form.
Three things that went wrong
Case studies that read like everything went smoothly are marketing. Here's what actually happened.
Every mobile test we ran for a stretch of this project was worthless, and we didn't know it. Headless Chrome quietly clamps the viewport around 500px. Ask it for 390 and it reports success while rendering at 500 — so media queries below that never fire and you get screenshots that look fine and prove nothing. We rebuilt the harness to load each page in a fixed-width frame instead. Re-running it immediately turned up three real bugs that had passed every previous check.
A CSS rule that had never once worked. The utility bar was eating around 150px above the fold on phones. Not a missing rule — a rule that was being outranked by a more specific one, so it had never applied at any screen width, ever. Invisible to linting. You only find that by measuring at real widths.
And one that was our own fault. Ronnie kept reporting the header was still broken after we'd fixed it. Three times. It wasn't a layout bug — it was a caching header we had set ourselves, serving week-old CSS against brand-new HTML to anyone who'd visited before. The fix was deployed and invisible.
We fixed it in two parts. Every asset reference now carries a content hash, so changing a file always changes its URL. And the build now fails outright if any asset reference ships without one, because a single bare reference would pin itself in browsers for a year and quietly serve a stale layout to returning visitors.
That's the pattern worth stealing from this whole project: when you find a bug, close the class of bug. Not the instance.
By the numbers
| Metric | Value |
|---|---|
| Pages live | 1,145 |
| Original URLs preserved | 788 of 788 |
| New pages added | 357 |
| Internal links verified on every build | 86,746 |
| Cities / counties / ZIP codes | 67 / 6 / 86 |
| Vehicle makes / models covered | 30 / 226 |
| Fabricated claims removed | 5 categories |
| Screen widths tested | 9, from 320px to 1280px |
Live now
RDB's Towing & Auto is live at ronniebuys.com. 1,145 pages, and every claim on every one of them checked against a primary source before it shipped — the state LLC registry, the BBB, his actual Google listing, his actual address.
And that's the whole story in one line. Somebody put invented numbers on this man's website and search engines started repeating them back as fact. The fix wasn't a nicer design. It was checking.
If your site was built by somebody who's gone
Do one thing this week. Open your website and check five facts against reality: your address, your founding year, your review count, your service area, and any testimonial with a name on it.
If any of them are wrong, they're not just sitting there. They're being read, indexed, and repeated — and the longer they run, the more places you'll have to chase them down.
That's step one on every inherited site we take over, before anybody writes a word of new copy.
Inherited a site you're not sure you can trust? Start with a free brand audit and find out what's actually wrong with it.
