# Static Sites Quickstart

> Deploy a Vite, React, Astro, or exported Next.js frontend as a NexHost Static Site.

Source: https://nexthomelabs.com/docs/quickstarts/static-sites
Markdown: https://nexthomelabs.com/docs-md/quickstarts/static-sites
Slug: quickstarts/static-sites
Section: Quickstarts
Last updated: 2026-08-30
Reading time: 5 min read

---

# Static Sites Quickstart

Use a [Static Site](/docs/services/static-sites) when your project produces files that can be served without a running Node or application server. The platform builds the output once per deployment and uploads the resulting directory — there is no long-lived process to keep alive and no health check to keep passing.

This quickstart covers the two things that actually cause static deployments to fail: running the wrong build command, and publishing the wrong directory.

## When to use this

Use this flow when:

- The deliverable is pre-built HTML, CSS, JS, and assets — hand-written HTML, a Vite/React build, an Astro static build, or a Next.js project configured with `output: "export"`.
- Every page can be generated at build time. If any page needs server rendering, middleware, or API routes at request time, use [Frontend App](/docs/services/frontend-app) instead.

## Before you begin

- Node.js installed locally so you can verify the build produces the directory you plan to publish.
- A workspace and permission to create a project in the dashboard.
- The project’s framework confirmed (Vite, Astro, Next.js, SvelteKit with a static adapter, plain HTML).

## Example: Vite and React

From an empty parent directory, create a small Vite + React site:

```bash
npm create vite@latest my-site -- --template react
cd my-site
npm install
npm run build
```

What that last step does: the `build` script (typically `vite build`) produces the static output in `dist`. Inspect it:

```bash
ls dist
# index.html, assets/, etc.
cat dist/index.html | head -n 5
```

If this listing looks right locally, the identical listing on the deployment detail page should match after the dashed settings you provide.

## Configure the service

1. Select **Static Site** in **New Project**. Do not select Frontend App — a static site and a frontend runtime are distinct products even when the framework name is similar.
2. Connect a **repository, folder, or ZIP archive** as the source. Confirm the branch and root directory when the dashboard shows them.
3. Set **Build command** to `npm run build`. If your repository tracks only source, this rebuilds on the platform — which is the normal path. If the repository already contains the pre-built directory, you may leave the build command empty.
4. Set **Publish directory** to `dist` (for the Vite example). The platform uploads only this directory after the build finishes.
5. Deploy and open the generated hostname displayed by the dashboard. The site should load the built UI directly.

What success looks like: the deployment detail says the publish directory was found and contained `index.html`; the generated hostname serves the page; refreshing a client-side route works when the framework’s fallback is configured (many static hosts redirect unknown paths to `index.html` — add that configuration in the framework if the UI uses client routing).

## Other static outputs

The same four-field configuration (service type, build command, publish directory, environment variable scope) applies to every static framework — only the values differ.

| Project | Typical build command | Publish directory | Notes |
| --- | --- | --- | --- |
| Vite or React (default template) | `npm run build` | `dist` | Vite writes `dist/index.html` + `dist/assets`. |
| Astro (static) | `npm run build` | `dist` | Astro’s static output is `dist`. |
| Next.js with `output: "export"` | `npm run build` | `out` | Only after setting `output: "export"` in `next.config.js`; without that flag the project is not static and needs a Frontend App. |
| SvelteKit with static adapter | `npm run build` | `build` | Install and configure `@sveltejs/adapter-static`; then `npm run build` writes `build/index.html`. |
| Plain HTML | none | `.` | Hand-written `index.html` already in the repository; no build step needed. |

If the application needs a runtime server after build — server rendering, API routes, middleware, `@next/image` optimization — use [Frontend App](/docs/services/frontend-app) instead of mapping a static directory over a server build.

> [!WARNING]
> Do not publish `.next` from a normal Next.js project as static files. `.next` is the server build; `out` is the static export. Uploading `.next` as a Static Site produces confusing "index not found" errors.

## Environment variables for static builds

Static configuration is baked into the artifact. A public API endpoint that your framework inlines at build time (for example `VITE_API_URL` for Vite or `NEXT_PUBLIC_API_URL` for Next) must be set with a **Build** scope before that build runs, and changing it requires a **new deployment** — saving without redeploying leaves the old HTML/JS live. Never store secrets in client-inlined variables; anything with a `VITE_` or `NEXT_PUBLIC_` prefix is observable in the browser bundle.

## Troubleshooting

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| "Publish directory not found" | The path does not exist at the chosen root | Run `npm run build` locally, confirm `ls <publish-dir>` contains `index.html`, and fix the directory in the dashboard. |
| Page loads but assets return `404` | Base path or asset prefix misconfigured | Check the framework’s base/asset configuration and rebuild; confirm `assets/` is alongside `index.html` in the published directory. |
| API routes / `next/image` missing | App needs a server, not static files | Recreate as [Frontend App](/docs/services/frontend-app) and ship source rather than a directory of HTML. |

## Related documentation

- [Static Sites](/docs/services/static-sites) — full description of the static service contract.
- [Frontend Apps](/docs/services/frontend-app) — when the app needs a running Node server.
- [Deployment Troubleshooting](/docs/deployments/troubleshooting) — diagnose missing outputs vs build failures.
- [Environment Variables](/docs/configuration/environment-variables) — build vs runtime scope.

