ai-builders
How to Export and Host a Bolt.new Website
By PreviewSend Team · Jul 20, 2026 · 7 min read

You built something in Bolt and now you want it living at a URL you control, with your own password or custom domain, off Bolt's own hosting. The short version: get the project's source out of Bolt, build it on your machine, and upload the compiled output. The one step people skip is that last distinction. Bolt hands you source files, and a static host serves a built site. Those are not the same folder.
Here's the whole path once the source is on your machine:
npm install # install the project's dependencies
npm run build # compile the source into a static output folder (often dist/)
cd dist
zip -r ../site.zip .
Then upload site.zip. Everything below is the detail that keeps each step honest: how to get the source out two different ways, how to tell whether your project can be static at all, and how to run the build the repository actually expects.
Get your project out of Bolt
There are two routes, and you only need one. The direct route is Download: open your project, click the project title at the top left, then choose Export > Download. Bolt gives you a zipped folder of your project files. Note what that archive is: source and project files, the same thing Bolt can later restore through StackBlitz. It is a backup of the project, not a ready-to-serve site.
If you'd rather work from a repository, click the GitHub icon in the top right, authorize the connection, and create a private repository from your project. Clone it locally and you have the same source, under version control. Bolt is explicit that once your code lives in GitHub you can publish it with services beyond Bolt hosting or the Bolt/Netlify integration, which is exactly what you're doing here.
Either way you end up with a folder of source on your machine. Unzip the download, or clone the repo, and open it.
Check whether your project can be static
This is the step that decides whether the rest of the guide applies to you. Bolt builds JavaScript web projects, and that covers a wide range: browser-only frontends, but also Node.js backends, server-rendered apps, and projects wired to Bolt Cloud for a database or server functions. Only the first kind moves cleanly to a static host.
Open the project and look for what has to run on a server:
- A Node backend or an API defined inside the project, serving responses per request.
- Server-side rendering, where pages are generated on the server rather than in the browser.
- Bolt Cloud database or server functions the app depends on to work.
If any of those are load-bearing, the whole app can't become a single static ZIP; the server half needs a runtime a file host has no way to execute. A static frontend can still talk to a separately hosted API over the network, and that's a fine setup. What can't happen is bundling the server into the upload. And when the frontend does call an external API, keep server-only secrets and environment variables out of the client build; anything compiled into the frontend is readable by anyone who opens the site.
If the project is a browser-only frontend that compiles to plain files, you're static, and the build below produces something a file host can serve. The static-versus-server split goes deeper on what counts as static if you're unsure.
Find the build command and package manager
Don't guess the command. The repository tells you both what to run and what to run it with.
The lockfile at the project root names the package manager:
package-lock.json→ npmpnpm-lock.yaml→ pnpmyarn.lock→ yarnbun.lock→ Bun
Open package.json and read the scripts block. The build script is the one that produces your output. A Vite-based Bolt project usually looks like this:
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
Run that script with the tool the lockfile points to: npm run build, pnpm build, yarn build, or bun run build. Not every Bolt project is Vite, and not every build writes to dist, so treat the config as authoritative. If vite.config.js sets build.outDir, the output lands wherever that names.
Build and test the output locally
Install dependencies, then build:
npm install
npm run build
When it finishes, open the output folder. For a Vite project that's dist by default, and a healthy build looks like a generated index.html next to a hashed assets/ directory:
dist/
├── index.html
└── assets/
├── index-a1b2c3.js
└── index-d4e5f6.css
That output folder is the build artifact a host should serve. A Vite source project also has a root index.html, because Vite treats it as source code and the application entry point. Identify the build by the configured output directory and its generated assets, not by assuming index.html was absent from source. If the folder you are about to zip contains package.json, src/, and node_modules, you are looking at the source tree; zip the configured build output instead.
Before you package it, look at the build. Most build tools have a local preview command (npm run preview for Vite) that serves the output at something like http://localhost:4173. Open it, click through, and watch the browser's Network tab for assets that fail to load. This is a check, not the deployment; the hosted copy comes from your upload, not from the preview server. If your app uses client-side routing and refreshing a deep link only works because of a fallback, building a Vite dist folder without Git covers that case and the base-path detail in full.
Zip the build with index.html at the root
Package the contents of the output folder, so index.html sits at the top of the archive rather than inside a dist/ wrapper:
cd dist
zip -r ../site.zip .
The trailing . compresses what's inside the folder, not the folder itself. Without a terminal, open the output folder, select everything inside it, and compress the selection. Right-clicking the dist folder and compressing that buries the entry file one level down, which is the most common reason an upload gets rejected. The ZIP hosting walkthrough covers the layout and the asset-path traps in one place.
Upload and keep the same URL
With site.zip holding an index.html entry, the upload is the simple part. Start a free PreviewSend workspace and upload the archive (up to 100 MB compressed). PreviewSend checks the ZIP's size and safety limits, selects an index.html, extracts the files, makes that version active, and returns a stable URL; it does not execute the project or prove that the build has no backend dependency. Eligible first-time owners get a one-time 14-day Pro trial on their first workspace without entering a card. Afterward, Free limits apply: the most recently updated site stays live and excess sites are archived.
The stable URL is the reason this beats emailing a ZIP around. When you change something in Bolt, export or pull the source again, rebuild, re-zip the output, and upload it to the same project. The new build becomes the active version at the same address, and earlier versions stay on file up to your plan's retention limit. The file-level version diff is available on Pro, Agency, and during the active Pro trial.
New projects enable client review by default, so a client can pin comments or request changes directly on the Bolt-built page without creating an account. Those notes stay attached to the version they saw. You can export all comments as CSV or Markdown, or turn unresolved feedback into an AI-ready revision plan before rebuilding in Bolt. For final handoff, named version-specific approver links are available on Starter and above or during the trial; stamped sign-off PDFs require Pro, Agency, or the active trial and are audit records, not electronic signatures.
You can also add a password before you share, or set an expiry date so the link stops working after a deadline. Normal hosted-site responses and password challenges carry an X-Robots-Tag: noindex, nofollow header, which asks supporting search engines not to index the page. Active projects without a password also serve a robots.txt disallow to restrict crawling. Neither directive is access control; anyone with the link can still open the site until you turn on the password. On a purchased Starter, Pro, or Agency plan you can point a custom domain at the project; custom domains are not included in the trial.
The build-and-upload half of this is the same for any AI builder that produces a static frontend. If you started in a different tool, moving a compatible Lovable build off Lovable's hosting follows the same shape from a different export.
FAQ
Can I just upload the ZIP that Bolt's Download gives me?
Usually no. Export > Download gives you a zipped folder of project files (the source), not a finished site. You install dependencies, run the build script, and upload the generated output instead. The exception is a project that already contains a root index.html with only static HTML, CSS, and assets and no build step; unzip and check before you assume.
My Bolt app uses a Node backend or Bolt Cloud. Can I host it as a static ZIP?
Not in full. Anything that runs on the server per request (a Node backend, server-side rendering, Bolt Cloud database or server functions) needs a runtime a file host cannot provide. You can still host a static frontend that calls a separately hosted API over the network. Never put server-only secrets or environment variables in the client build.
Do I have to connect GitHub to get my code out?
No. Export > Download and the GitHub integration are two routes to the same source. Download hands you a ZIP directly; GitHub creates a private repo you can clone. Use whichever you already have. Bolt notes that once your code is in GitHub you can publish it with services other than Bolt.
Which build command should I run?
Read the repository, not a guess. package.json's scripts block names the build command, and the lockfile names the package manager: package-lock.json means npm, pnpm-lock.yaml means pnpm, yarn.lock means yarn, bun.lock means Bun. A Vite project's build script runs vite build and writes a dist folder, but confirm from the config rather than assuming.
Have a site to host? Upload it and get a live link in seconds.
Get it free