Next.js is auto-detected on Node 22, with standalone output handled for you. Push to GitHub and it builds with no adapter or config step.
Last updated
These are the defaults. Override any of them in Settings → Build.
Make sure package.json has the standard scripts:
"scripts": {
"build": "next build",
"start": "next start"
}That's it for most apps. We build on Node 22 by default. If your app needs a specific version, set "engines": { "node": "20.x" } in package.json and that wins.
Standalone output is supported. If your next.config sets output: "standalone", we run the standalone server, copy public/ and .next/staticnext to it (so CSS, JS and images don't 404), and install sharpfor image optimization. You don't need to do any of that yourself.
Add variables in the project's settings. They're available both while the app builds and while it runs, so build-time values (like framework-public keys) work without extra setup. See Environment variables.
NEXT_PUBLIC_* values reach the browser, so never put secrets in them.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY (a base64 key of 16, 24 or 32 bytes) so the key stays the same between builds.Add a Postgres addon and DATABASE_URL is injected automatically. With Prisma, generate the client during the build and apply migrations with migrate deploy (never migrate dev in production):
"scripts": {
"build": "prisma generate && next build"
}Keep prisma in dependenciesso it's available at build time. To run migrations on each deploy, set the project's Build command to prisma migrate deploy && npm run build in Settings → Build.
<project-slug>.ethiodeploy.com. Every push to the default branch redeploys, and the old version keeps serving until the new one is healthy.A NEXT_PUBLIC_ value is empty or undefined in the browser
Cause: The variable wasn't set when the app was built, so nothing was inlined.
Fix: Add it in Settings, then trigger a new deploy.
Build passes but the health check fails
Cause: The server isn't reachable on the port we expect.
Fix: Use the default next start or standalone output. If you set a custom start command, keep it listening on 0.0.0.0 and $PORT, for example next start -H 0.0.0.0 -p $PORT.
Page shows an old env var value
Cause: The route was prerendered at build time.
Fix: Make the route dynamic so it reads the value on each request.
Unstyled page or broken images with a custom start command
Cause: Standalone output needs public/ and .next/static copied beside server.js.
Fix: Leave the start command blank so we handle it, or copy both folders yourself.
Build fails with a Node version error
Cause: Your app needs a different Node version than 22.
Fix: Set engines.node in package.json.
Failed to find Server Action after a redeploy
Cause: The Server Action encryption key changed between builds.
Fix: Set NEXT_SERVER_ACTIONS_ENCRYPTION_KEY as a fixed env var.
Still stuck? Check the deployment's build log in the dashboard, or see Troubleshooting.
Ready to deploy? Sign in with GitHub and pick your repo. No Dockerfile, no YAML.
See the full docs for custom domains, env vars, addons, and billing.