build, then a small server to serve the dist/ folder.
Set up
serve is what runs in production. Vite is for building.
In package.json, set a start script that boots serve against the build output:
package.json
-s flag tells serve to fall back to index.html for unknown routes (so client-side routing works). The -l ${PORT:-3000} makes it respect Nubo’s port.
Test locally:
Deploy
Push to GitHub, then in the Nubo dashboard:Client-side routing (React Router)
serve -s already redirects unknown paths to index.html. If you use a different static server, make sure it does the same. Otherwise hitting /dashboard directly returns 404.
Things that trip people up
- No
startscript. Withoutnpm start, Nubo triesnode index.jswhich doesn’t exist in a Vite project. Definestartexplicitly. vite previewinstart.vite previewis for local checking only; it’s not a production server. Useserveor another static server.- Hardcoded
serve -l 3000. Use${PORT:-3000}so the Frame’s port setting actually applies.
Going truly static
If you don’t need a Node container, build locally and deploy with the Static pack instead: commit yourdist/ (or rename it to public/) and remove package.json from the repo. Nubo will then ship the files behind nginx with no Node runtime at all. Useful for cheap landing pages; not useful when you want to redeploy from a git push.
