Uploading an HTML file to “a website” sounds like one job.
In practice, it can mean three different things:
- publish one self-contained HTML file
- publish HTML with local CSS, JavaScript, images, or fonts
- publish the output of a React, Vue, Vite, or other framework project
The correct workflow depends on which artifact you actually have.
That distinction matters because many failed static deployments come from uploading source code when the host expects browser-ready output.
Case 1: one self-contained HTML file
If your page is one complete .html document, you do not need to create a repository or ZIP just to share it.
A browser-ready file normally contains:
<!doctype html>- an
<html>element -
<head>metadata - a
<body> - inline CSS/JavaScript, or external resources that the browser can reach
Open the file locally first.
If it renders correctly, the publishing workflow can be as short as:
- upload the
.htmlfile - wait for the static deploy
- open the returned HTTPS URL
- share it
This is useful for AI-generated landing pages, reports, dashboards, calculators, design proofs, and one-file demos.
Case 2: HTML with local assets
An HTML file is not self-contained when it references files such as:
./styles.css
./assets/logo.png
./scripts/app.js
./fonts/inter.woff2
Uploading only index.html will leave those paths unresolved.
Package the full static structure instead:
site/
├── index.html
├── styles.css
├── scripts/
│ └── app.js
└── assets/
└── logo.png
Upload the folder or a ZIP that preserves the same relative paths.
Two details cause a surprising number of failures:
-
Logo.pngandlogo.pngare different filenames on many hosts. -
index.htmlmust be at the entry point the host expects, not hidden under an extra nested directory.
Case 3: a framework source project
A folder with package.json, src, and node_modules is usually not a website that a static host can serve directly.
It is source code.
Build it first:
npm install
npm run build
Then deploy the generated static output:
dist/
build/
out/
public/
The exact directory depends on the framework and configuration.
Before deploying, confirm that the output contains index.html and the assets needed by that file.
A simple decision tree
Use this rule:
- One complete
.htmlfile → upload the file directly. - HTML plus local assets → upload a static folder or ZIP.
- React/Vue/Vite/Next source → build first, then upload the output.
- Backend, database, authentication, or server routes → use a production application platform.
Preview hosting and production hosting are different jobs.
A preview URL is ideal when the immediate goal is review, QA, client approval, or sharing an AI-generated artifact.
It is not a substitute for a production release process.
Troubleshooting a blank page
If the URL loads but the page is blank:
- open browser developer tools
- check the Console
- check Network for 404 responses
- confirm
index.htmlexists - confirm asset paths and filename case
- for framework apps, check the configured base path
If you uploaded source code, go back and deploy the build output.
Hosting cannot infer the build process of every framework from a random source ZIP.
Publishing with PreviewShip
I built PreviewShip for the narrow “browser-ready artifact in, review URL out” workflow.
It supports:
- direct HTML upload
- pasted HTML
- Markdown and PDF files
- ZIP/static folders
- CLI deployment
- MCP deployment from AI coding agents
- VS Code and Cursor workflows
The detailed upload guide is here:
The useful mental model is not “How do I upload my repository?”
It is:
What is the smallest browser-ready artifact that preserves the page correctly?
Once that artifact exists, turning it into a shareable URL should be the easy part.
Top comments (0)