Vue ships as static assets when you build for production
Whether you use Vite + Vue or an older Vue CLI project, production mode emits HTML, JS, and CSS. StaticHost hosts that emission. It does not run vue-cli-service build or vite build for you, and it does not rewrite missing paths to index.html. History-mode vue-router URLs 404 on hard refresh unless you change approach.
Build with Vite + Vue
vite.config.js:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
base: '/',
build: { outDir: 'dist' },
})
npm ci
npm run build
cd dist && zip -r ../vue-site.zip .
Env: VITE_* only, baked at build time. See Vite hosting.
Build with Vue CLI
npm ci
npm run build
vue.config.js knobs:
module.exports = {
publicPath: '/',
outputDir: 'dist',
}
Wrong publicPath (for example '/repo-name/') breaks assets on a root-hosted StaticHost site.
vue-router and =404
History mode:
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [/* … */],
})
On StaticHost, try_files $uri $uri/ =404 means /users/42 must be a real file or it 404s.
Hash mode (compatible):
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes: [/* … */],
})
URLs become /#/users/42. The server serves /index.html; Vue reads the hash.
Alternative: SSG/pre-render plugins that write HTML per route so history URLs exist on disk. That is generating files—not requesting a fictional nginx fallback. Companion reading: SPA guide, React counterpart.
Deploy and verify
- Upload zip or GitHub artifact branch (no remote npm).
- Open HTTPS preview immediately.
- Click client navigations, then paste a nested path into the address bar and press enter.
- Confirm hash mode survives hard reload; note history mode failure if still enabled.
- Roll back from deploy history if needed.
- Add custom domain; certificate after DNS verification.
Watch mixed content if any plugin still injects http:// asset URLs.
Pinia/Vuex and API bases
Store libraries are client-side; they do not need server support. Configure API base URLs via import.meta.env.VITE_API_BASE and rebuild per environment. Use Pro staging (3 sites, 10 GB, $30) for a staging bake separate from production.
Plans and boundaries
Starter $9 (1×2 GB), Pro $30 (3×10 GB + staging), Scale $65 (10×30 GB), Business $130 (30×100 GB + teams). Trial ~1 day. No forever-free, cPanel, email, built-in CDN, or PHP/WordPress runtime.
Nuxt note
Nuxt can generate static sites (nuxt generate / static target depending on major version). Only the generated output belongs on StaticHost. A Node-targeted Nuxt server does not. Treat output like any other dist/public tree—host a dist folder.
A realistic week shipping host a vue build online
Monday starts with a broken relative CSS path that only appears once the files leave a designer’s laptop. You flatten the zip so index.html sits at the archive root, redeploy to StaticHost, and HTTPS preview finally matches local intent. Preview HTTPS is available immediately; custom-domain certificates issue only after DNS verifies.
Wednesday adds a custom domain. DNS is created exactly as the dashboard specifies; verification lags an hour; the certificate appears afterward. Someone asks whether email is included—you point them at a mail vendor and keep MX untouched. Deploy history supports rollback when a publish goes wrong.
Thursday an engineer enables history-mode routing for a “cleaner URL.” Refresh on a nested path 404s. You revert to hash routing for the week’s deadline and schedule prerender work properly instead of inventing an nginx rewrite StaticHost will not apply. WordPress/PHP needs a different kind of host.
Friday staging on Pro receives a build with staging API URLs baked via public env prefixes. Production stays on last week’s known-good deploy until Monday’s review. Rollback remains one click if marketing’s late copy drop breaks mobile layout. There is a short trial (~1 day), not a forever-free tier; no cPanel, no email, no built-in CDN product.
StaticHost serves prebuilt files via zip or GitHub and does not run npm, Hugo, or Jekyll remotely.
That week is what host a vue build online looks like when the host stays boring and the team respects file truth.
Worked example: Vue Router history → hash before launch
You are two days from launch. Product wants pretty paths. StaticHost will 404 them on refresh.
// router/index.js — launch-safe
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Account from '../views/Account.vue'
export default createRouter({
history: createWebHashHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/account', component: Account },
],
})
npm ci
VITE_API_BASE=https://api.staging.example.com npm run build
cd dist && zip -r ../vue-staging.zip .
Deploy to Pro staging ($30/mo includes staging). Hard-refresh /#/account—expect the account view. Hard-refresh /account—expect 404 unless you also prerendered a file. That teaches the team more than a wiki paragraph.
When staging API calls look right, rebuild with production VITE_API_BASE, deploy production, then DNS → verify → certificate. Do not edit minified bundles on the host to flip environments.
Failure table (Vue on StaticHost)
| Symptom | Likely cause | Fix |
|---|---|---|
JS under /repo/assets 404 | base / publicPath leftover | Set base: '/' or publicPath: '/'; rebuild |
Refresh on /users/1 404 | createWebHistory without files | Hash history or SSG files |
| Blank app, console MIME/path errors | Nested zip | Zip dist contents |
| Staging data in production UI | Wrong VITE_* at build | Rebuild with production env |
| Pinia state “resets” oddly after deploy | Expected server session | Keep state client-side or call your API |
| Nuxt server routes 500 ideas | Node target uploaded | Only upload static generate output |
Nuxt reminder: static generate output only—host a dist folder online. No remote npm, no forever-free after ~1 day trial, no email, no cPanel, no built-in CDN, no PHP. Plans: Starter $9 (1×2 GB), Pro $30 (3×10 GB + staging), Scale $65 (10×30 GB), Business $130 (30×100 GB + teams).
Env bake discipline for Pinia-powered screens
Pinia stores often read import.meta.env.VITE_API_BASE once at startup. If production accidentally ships the staging base, every screen looks “fine” while writing to the wrong backend.
Always rebuild—never patch the store in DevTools as a release step. Keep a one-line README reminder: VITE_API_BASE=… npm run build. Use Pro staging to prove the staging bake, then a clean production bake for the live site. Preview HTTPS is enough to catch CORS allowlist mistakes before you touch DNS.
FAQ
Does createWebHistory(import.meta.env.BASE_URL) fix 404s?
It aligns router base with Vite base. It does not add SPA fallback.
Can I use Vite SSR with Vue here?
No. SSR needs a server process.
Why do in-app links work but refresh fails?
In-app links are client-side; refresh asks the server for a file that does not exist. Hash mode or SSG files fix that class of bug.
Should I enable fallback: true in some config?
That is not a StaticHost feature. Ignore advice copied from other hosts’ redirect files.
How do I host VuePress or VitePress docs?
Build the docs site to static files, upload the output directory contents. Same zip discipline applies.