Framework Frankfurt, Germany

Deploy Static sites and SPAs on Nodion

Nodion builds frontends such as Vite, Angular, Create React App, Gatsby and Eleventy with its Node.js buildpack, then serves the output folder with a static web server. A repository with a root index.html and no package.json is served as it is. Your site runs in Frankfurt, and the smallest app size is enough.

Deploy to Nodion ›

from 1 EUR / month

Up to 15 € credit when signing up

Detected by
A static framework in package.json, a static.toml or a root index.html
Output
dist/, build/, public/, _site/ or your static.toml
Served by
static-web-server with index.html fallback
Region
EU Central (Frankfurt)

Deploy Static sites and SPAs step by step

  1. Commit a lockfile and a build script Commit your lockfile; the build fails without one. Nodion runs the build script and takes the output folder from your framework: dist/ for Vite, build/ for Create React App, dist/<project>/browser for Angular, public/ for Gatsby and _site/ for Eleventy. package.json
    "scripts": {
      "dev": "vite",
      "build": "vite build"
    }
  2. Set build variables Your bundler writes variables such as VITE_*, REACT_APP_* or GATSBY_* into the files during the build, so they need the Build flag on the Environment tab. Everything in them is public, so never put secrets there.
  3. Name other output folders in static.toml Other generators work too: Nodion looks for an index.html in dist, build, out, .output/public, public and _site. If yours writes somewhere else, as VitePress does, add a static.toml next to package.json. It also makes Nodion treat the repository as a static site when it would not detect one. fallback names the file served for paths that do not exist. static.toml
    output-dir = "docs/.vitepress/dist"
    fallback = "index.html"
  4. Plain HTML needs no build A repository with an index.html in the root and no package.json is served as it is. Nodion leaves out .git, .env files and some common key files, but treat everything you commit as public and keep secrets out of the repository.
  5. Create the app and push In the dashboard, create an application from your GitHub, GitLab, Bitbucket or Gitea repository in the region EU Central and pick the smallest size. Every push builds a new release, and traffic moves to it once / answers, which your index.html takes care of.

Good to know

  • Client-side routing worksPaths that match no file get your index.html, so React Router, Vue Router and Angular routes survive a reload. The fallback cannot be switched off; fallback in static.toml only swaps the file.
  • No Procfile processes, no server codeProcfile processes have no effect on a static site, and only the output folder ships. A release: line would still run, but in an image that holds only the built files, so leave it out. If your repository is a Node.js server with a build script, read the Node.js guide for how Nodion tells the two apart.
  • Angular SSRNodion builds Angular projects as static sites, also with @angular/ssr, so server rendering does not run. For SSR, use a Dockerfile.
  • Hugo and JekyllNodion does not run Hugo or Jekyll builds. Build the site yourself, commit the generated folder (public/ or _site/) and set the app's base directory to it: a folder with an index.html and no package.json is served as it is. Or build the site in a Dockerfile.

What Nodion runs for you

  • Deploys without downtime Push to your branch and Nodion builds a new release. Traffic switches once the new instances answer their health check; a failed release leaves the running one in place. Apps with a local volume restart instead, because the disk belongs to one instance.
  • Databases next to the app Managed PostgreSQL, pgvector, MySQL, Valkey and ClickHouse in the same region. Attached databases arrive as DATABASE_URL, REDIS_URL or CLICKHOUSE_URL.
  • Previews per pull request Turn on previews and pull requests from your repository get their own app with its own URL and fresh, empty databases, created automatically or by hand. Forks and bot pull requests are skipped.
  • Workers, cron jobs and scaling Run workers as extra processes of the same app, schedule jobs on the Cron tab, and scale every process to up to 16 instances.
  • Release step With buildpacks, a Procfile release: line runs with every new build. Dockerfile apps, and redeploys or rollbacks to an earlier image, use a release command set on the app itself, which also takes precedence over the Procfile line. On static sites a release step runs in an image that holds only the built files.
  • Logs and metrics Build, release and runtime logs plus CPU, memory, disk and network metrics for every instance in the dashboard.
  • Domains and HTTPS A default hostname with HTTPS from the first deploy; your own domains get certificates automatically.

Further reading

Static sites and SPAs on Nodion: questions and answers

Why does my build fail with "could not determine static output directory"?

After the build, Nodion found no index.html in the folders it checks. Make sure your build script writes one, or name the folder with output-dir in a static.toml.

Can a static site read environment variables at runtime?

No. No server runs that could read them, so every value has to be there during the build: give it the Build flag. After you change one, deploy again to rebuild the files.

Which Node.js version builds my site?

Node.js 24, unless you pin 22 or 26 in .node-version, .nvmrc or engines.node. A range such as ">=20" resolves to the newest matching release.

Where does my Static sites and SPAs app run?

In the EU Central region in Frankfurt, Germany. Build, registry, the app and its databases, volumes, buckets, logs and metrics stay in that region, and Nodion's API and control plane are hosted in Germany. Nodion GmbH is based in Stuttgart.

Can I use Static sites and SPAs in line with the GDPR?

Nodion provides the basis for it: Nodion GmbH is based in Stuttgart, Germany, in the Frankfurt region the app, its databases and volumes run in Germany, and you conclude the data processing agreement (DPA) under Art. 28 GDPR electronically in the dashboard. Whether your setup complies also depends on how you configure and use the app.

How much does it cost to run Static sites and SPAs on Nodion?

An app instance starts at 1 EUR per month. The setup in the cost box costs 1 EUR per month: App 1 EUR. Prices are net and billed per second, and you pick bigger sizes or more instances whenever you need them.

Can I use my own domain for my Static sites and SPAs app?

Yes. Every app gets a default hostname with HTTPS. Add your own domain on the app's Domains tab; the TLS certificate is issued and renewed automatically.

Give your agent a cloud.

Earn up to 15 € in credit when signing up.

Continue with GitHub

or with email

Stay in the loop.

Product news, no spam. Unsubscribe anytime.