Launching a site and handing it over have become the same click, which is why freelancers stall when a client says 'looks great, put it live' before the last invoice is paid. What you can hold back until payment, what you can't, six ways to show the work without launching it, and a step-by-step for static builds.
The site is done. The client opened it, said they love it, and asked you to put it live. The last 50% hasn't been paid.
That exact situation is a thread on r/webdesign, and the replies split the usual way: some people say launch it and trust them, others say never launch before payment. Both camps are arguing about the same thing, which is that launching has quietly turned into handing over.
Once the site is on the client's domain and running from their hosting, they have the thing they were paying for. The invoice becomes a request. So most freelancers stall, and the client can't see why "make it live" is a big ask when the work is obviously finished.
The way out is to treat showing and handing over as two separate steps. The client gets to see and click through the whole site now. They get the parts that make it theirs once the invoice is paid.
Before choosing how to show the site, it helps to be honest about what any preview can protect.
What you can hold back until payment:
These four are what turn "a site I've seen" into "a site I own and can run". A preview leaves all of them with you.
What you can't hold back:
So a preview protects your leverage over the site itself: the client can't run it as their live site, edit it, or move it to their own hosting without you. It won't stop a client who has decided not to pay. That's the contract's job, which is covered at the end.
Which one fits depends mostly on how the site was built and what the client needs to do with it: look at it, click through it, or test a form or a checkout.
| Option | What the client gets | Fits best when | Watch for |
|---|---|---|---|
A staging subdomain on your own hosting (like clientname.yourstudio.com) | The real site, running, at an address you control | The site needs a server, a database or a CMS, and you already run hosting | Password-protect it and keep it out of search, or it becomes a second public copy |
| The host's temporary address | The site running on its future host, before the domain points at it | You're building directly on the hosting the client will use | That account may already be in the client's name, which makes it the handover |
| The preview or staging feature of your build tool (WordPress, Webflow, Framer) | The site in the tool's own preview or staging environment | The site was built in that tool | Check what the tool's preview exposes and who it's shared with |
| A screen recording or a live video walkthrough | Your cursor moving through the site | Early sign-off, or a client who wants to watch rather than click | They can't click around themselves, so feedback is narrower |
| A PDF of screenshots | Static images of each page | Copy and layout approval | No interaction, no responsive view, nothing to test |
| A static build uploaded to a private link | The front-end, clickable in their browser, at an unguessable address with an expiry, and a password if you need one | The site builds to static files: Vite, React, Astro, a plain HTML/CSS/JS site | No backend runs, so forms, logins and checkouts that need a server won't work |
A note on the last row, since it's ours. miinideck takes self-contained HTML, ZIP bundles, PDFs and images. It doesn't run a backend or a CMS admin, and it isn't a staging server. If your site needs a server to render pages or process forms, use the staging environment on your own hosting, or the preview deployments on Vercel or Netlify, which run the code. The private-link route covers sites whose finished output is a folder of files.
For the same question asked about design files rather than a built site, we compared the usual channels in how agencies preview client work without exposing the WIP.
If npm run build gives you a folder with an index.html and some assets, this is the whole process.
This step comes first because it's the one that leaks.
A source map is a file your bundler can write next to each JavaScript bundle, usually named something like app.js.map, so that browser dev tools can show readable code instead of minified code. Many source maps include the original source text. If the .map files end up in the folder you upload, the host serves them like any other file.
We tested this on miinideck on 2026-10-07. We uploaded a ZIP containing index.html, style.css, app.js and app.js.map, then requested /app.js.map from the link. It came back with a 200 response, and the original source was in the file in full. With no password on the link, anyone who had it could read your source. A password keeps strangers out (we checked: the same .map came back locked once a password was set), but the client you send the password to can still open it.
So:
.map. If you find any, the setting didn't take. Fix it and rebuild rather than deleting files by hand, so the next build doesn't bring them back.Zip the folder the build produced, the one with index.html at the top. Before you upload, open index.html from that folder to check that styles, scripts and images load. If the page comes up unstyled, the build is probably using absolute asset paths like /assets/app.js. Set the build's base path to relative and rebuild.
Click through every page and state you want the client to see. Whatever works in that folder is what the client will see.
Upload the ZIP from a logged-in account and set the link to expire.
How expiry works depends on the plan. On Free, links expire after 7 days, which covers a typical review week. On Solo and Studio you choose the expiry date, or turn expiry off. There's more on expiry in how to make a shared link expire.
Two things to know before you send it:
Review. The link is already unguessable and kept out of search, and it expires on the date you set. That is enough for most previews, and it lets the client sign off on the page itself. Turn on Review for the page. The client opens the link, clicks anywhere on the page (a headline, a button, a footer line) and leaves a comment pinned to that spot. They don't need an account. You mark each comment resolved as you fix it. We tested Review on a ZIP upload in the same October check: the bundle rendered in the review workspace and a pinned comment saved.
Review and commenting are free on every plan. Exporting the comment thread as markdown, which you can paste into your notes or give to an AI assistant to work through, is a Studio feature. There's no reply thread on a comment, so if a note needs a back-and-forth, take it to email or wherever you already talk to the client.
A full set of comments, all resolved, also works as a record of sign-off: the client went through the page and these are the changes they asked for.
A password, if the preview must be locked. If the work is under NDA, say, also set a password, which is free on every plan. It works alongside Review: the client opens the review link, enters the password once, and then comments as usual. Send the password in a separate message from the link.
Drop a single HTML file to see what the client sees. For a client preview, sign in first so the link can have an expiry and Review, and add a password if you need one.
This isn't legal advice. Have a lawyer in your jurisdiction review your contract.
A preview link does its job when both sides already agree what it is. Three clauses do most of the work:
With those written down, "looks great, put it live" gets an easy answer: "Great. Once the final invoice clears, I'll point the domain and send over the repo the same day."
If you're delivering previews on a free hosting plan, also read the host's terms, because some hosts restrict paid client work on free tiers. That's covered in is client work allowed on a free hosting tier?
Then it's the handover you held back:
The preview link needs no cleanup. It expires on the date you set, and the client's own domain is the address that's left.
You built a sample site for a local business on spec and it's still sitting in your AI builder. What the owner needs to be able to do with the link, what the builder's own URL, a Vercel deploy and a screen recording each give you, and how to send it as a private link that stays out of search and ends on its own.
Figma is designed for collaboration, so the share link shows comments, version history, and the frames you parked. Channel options for a client-facing preview, and where private-link hosting fits.
Five channels agencies use for client previews — and what each accidentally reveals about the work in progress. Where private-link delivery sits, and when it's worth the swap.
miinideck turns a single HTML file into an unguessable link with optional password and expiry. Default-private, never indexed.