Desktop preview says the page is fine. The phone disagrees, and you find out after the client already has the link. Here's the loop that catches it first — and the part of the problem no host can fix for you.
There is a version of this that has happened to everyone who has ever handed over a web page. You built it, probably with an AI, in one file. On your monitor it is fine — spacing right, type right, the whole thing lands. You send the link. And the reply is a screenshot from a phone where the heading has wrapped into four lines, a button is half off the edge, and something you were quite pleased with is now sitting under something else.
Nothing broke. You just never looked at it on the device most people were going to open it on.
The awkward part is that the obvious way to look at it first — send the file to yourself — is the one route that does not work.
A desktop has spent thirty years being taught that .html means open this in a browser. A phone mostly has not. Tap an HTML attachment on a phone and the operating system usually hands it to a file previewer or a text viewer, which shows you the source code, a blank sheet, or a share menu. It is not a bug and there is no setting on your end that fixes it. If you have hit this from the other direction — a recipient telling you the thing you sent will not open — that is the same mechanism, seen from their side.
The thing every phone does know how to open is an address. So the fix for previewing is the same as the fix for sending: stop moving the file, and put it somewhere it has a URL.
Which raises the fair objection: I don't want to publish it yet — it isn't finished.
That objection is only true if publishing means becoming public. It doesn't have to. A link that is unguessable and carries noindex is at an address without being on the web in any sense that matters: nobody can find it, nothing lists it, and search engines are told to stay away. You are not shipping. You are giving the file a door number so your own phone can find it.
Open devtools, switch to device mode, pick a phone width. It takes four seconds and it catches most layout problems, which makes it the correct first move — not a lesser one.
Then be clear about what it did not check:
100vh gets clipped by exactly that much. Emulation holds the viewport still, so this class of bug is invisible in it. (100dvh is the unit that accounts for it.)Everything on that list is a difference between a small window and a phone. Emulation gives you the first one honestly and does not claim to give you the second.
One thing worth checking in the file itself before you blame anything else — if this line is missing, a phone renders the page at desktop width and then shrinks the whole thing:
<meta name="viewport" content="width=device-width, initial-scale=1">
Most AI-generated pages include it. Some don't, and the symptom — everything correct but tiny — looks like a hosting problem and isn't.
Your phone caches. You replace the file, re-scan the same code, see the identical broken layout, and start hunting for a bug you already fixed.
Pull to refresh. If it still looks stale, open the link in a private tab — that skips the cached copy entirely. It costs two seconds and it is worth doing reflexively after every replace, because the failure mode is indistinguishable from "my fix didn't work."
If you are editing the page line by line and want it to update on the phone as you type, publish-and-recheck is the wrong shape and you will feel it by the third round. What you want is a live connection to the file on your machine: a framework dev server exposed on your local network, or a tunnel — ngrok or Cloudflare Tunnel — pointed at localhost. Both give you hot reload on the phone, which is genuinely better for that job.
The reason publish-and-recheck fits most AI-built pages is that they are not edited so much as regenerated. You go back to the model, ask for the fix, and get a whole new file. There is no live edit to reload — there is a new file to put in the same slot. When that is the shape of the work, a tunnel is a server you have to keep running for no benefit.
And one thing no host can do for you: if the layout breaks because of how the page is written, that is in your file, not in where it lives. A preview tells you that it broke and where — it cannot un-break it. The fix goes back to whatever made the page.
The page is not finished when it looks right on your monitor. It is finished when it looks right on the device it will actually be opened on, and the only way to know that is to open it there.
Give the file an address that nobody can find, put it on your phone, and be your own first recipient. It takes about a minute, and it moves the moment you discover the wrapped heading from after you sent it to before.
Bolt.new previews live behind a session URL that changes and can lapse. How to pull a static export — one HTML file or a built dist folder — out of Bolt and turn it into one stable, private link.
Three paths to turn a multi-asset HTML page into a single self-contained file: a build-tool step, an LLM prompt, or a manual pass with DevTools. When each one fits.
Client-side encryption tools turn your page into an encrypted file, so the protection and the artifact are the same object — every edit means re-running the tool and re-uploading. What that actually costs, the salt setting that decides whether your old share links survive, and when a hosted password is the better trade.
miinideck turns a single HTML file into an unguessable link with optional password and expiry. Default-private, never indexed.