Basis-Website

Die kleinste brauchbare sitelo-Website: eine Seite, ein Stylesheet und Hoster-Konfigurationen, die dist/ veröffentlichen. Kopiere die Konfigurationen in jedes sitelo-Projekt — sie setzen nur npm run build → dist/ voraus.

Eine lauffähige Kopie liegt im sitelo-Repository unter examples/basic/.

Was du bekommst

Projektstruktur

my-site/
  sitelo.config.js
  netlify.toml           # Netlify
  vercel.json            # Vercel
  wrangler.jsonc         # Cloudflare Workers
  amplify.yml            # AWS Amplify
  cloudfront-function.js # AWS S3 + CloudFront
  firebase.json          # Firebase Hosting
  .gitlab-ci.yml         # GitLab Pages
  render.yaml            # Render
  .do/app.yaml           # DigitalOcean App Platform
  Caddyfile              # Railway, Fly.io, Heroku, Cloud Run
  Dockerfile             # Railway, Fly.io, Heroku, Cloud Run
  .dockerignore          # Railway, Fly.io, Heroku, Cloud Run
  fly.toml               # Fly.io
  heroku.yml             # Heroku
  nginx.conf             # Your own server
  package.json
  public/
    staticwebapp.config.json  # Azure Static Web Apps
  src/
    index.ht.js
    css/
      styles.css
import { html, head, title, link, body, h1 } from 'javascript-to-html'

export default () =>
  html({ lang: 'de' },
    head(
      title('sitelo — Basis-Beispiel'),
      link({ rel: 'stylesheet', href: '/styles.css' }),
    ),
    body(h1('Hallo von sitelo')),
  )

Build

npm install
npm run build

Deployment

Setze im sitelo-Monorepo das Root- bzw. Basisverzeichnis der Plattform auf examples/basic.

Netlify

[build]
  command = "npm run build"
  publish = "dist"

Vercel

{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "framework": null,
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "installCommand": "npm install"
}

Auf Vercel deployen · Auf Netlify deployen (setze das Basisverzeichnis auf examples/basic, wenn du gefragt wirst).

Cloudflare

Cloudflare empfiehlt für neue Projekte inzwischen Workers. npx wrangler deploy baut und lädt dist/ hoch, oder du verbindest das Repository im Cloudflare-Dashboard. Auf Pages nimmst du Build-Befehl npm run build und Ausgabeverzeichnis dist.

{
  "name": "sitelo-basic",
  "compatibility_date": "2026-10-01",
  "build": {
    "command": "npm run build"
  },
  "assets": {
    "directory": "./dist",
    "not_found_handling": "404-page",
    "html_handling": "drop-trailing-slash"
  }
}

AWS Amplify

Verbinde das Repository in Amplify Hosting.

version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm install
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: dist
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

AWS S3 + CloudFront

Hänge cloudfront-function.js an die Viewer-Requests der Distribution und lege eigene Fehlerantworten für 403 und 404 an, die /404.html mit Status 404 liefern. Danach lädst du jeden Build hoch:

function handler(event) {
  var request = event.request
  var uri = request.uri

  if (uri.endsWith('/')) {
    request.uri += 'index.html'
  } else if (uri.slice(uri.lastIndexOf('/') + 1).indexOf('.') === -1) {
    request.uri += '/index.html'
  }

  return request
}
npm run build
aws s3 sync dist/ s3://my-bucket --delete
aws cloudfront create-invalidation --distribution-id MY_DISTRIBUTION_ID --paths "/*"

Azure Static Web Apps

Lege die Static Web App mit App-Speicherort / und Ausgabespeicherort dist an. sitelo kopiert public/staticwebapp.config.json nach dist/, wo Azure die Datei liest und für unbekannte URLs 404.html ausliefert.

{
  "responseOverrides": {
    "404": {
      "rewrite": "/404.html"
    }
  }
}

Google Cloud

Firebase Hosting: Wähle mit firebase use --add ein Projekt, dann baut firebase deploy die Website und lädt sie hoch. Für Cloud Run baut gcloud run deploy --source . das Dockerfile unten.

{
  "hosting": {
    "public": "dist",
    "predeploy": "npm run build",
    "trailingSlash": false
  }
}

GitLab Pages

Kopiere .gitlab-ci.yml in das Stammverzeichnis eines GitLab-Repositorys; der Job baut und veröffentlicht dist/.

deploy-pages:
  image: node:24
  script:
    - npm ci
    - npm run build
  pages:
    publish: dist
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Render

Lege aus render.yaml einen Blueprint an oder trage denselben Build-Befehl und dasselbe Publish-Verzeichnis bei einer neuen Static Site ein. Saubere URLs und 404.html funktionieren ohne Regeln.

services:
  - type: web
    name: sitelo-basic
    runtime: static
    buildCommand: npm install && npm run build
    staticPublishPath: ./dist

DigitalOcean App Platform

Trage dein Repository in github.repo ein und führe dann doctl apps create --spec .do/app.yaml aus.

name: sitelo-basic
static_sites:
  - name: site
    github:
      repo: your-name/your-site
      branch: main
      deploy_on_push: true
    build_command: npm run build
    output_dir: dist

Railway

Railway baut das Dockerfile (siehe Fly.io unten), du musst also nichts einstellen. In einem Projekt ohne Dockerfile setzt du stattdessen die Service-Variable RAILPACK_SPA_OUTPUT_DIR=dist: Railpack liefert dist/ dann über das Caddyfile aus, das unbekannte URLs mit 404.html beantwortet.

:{$PORT:80} {
  root * /app/dist
  encode zstd gzip
  try_files {path} {path}/index.html
  file_server
  handle_errors {
    rewrite * /{err.status_code}.html
    file_server
  }
}

Fly.io

Das Dockerfile baut mit Node und liefert dist/ mit Caddy aus. Lege die App mit fly launch an und liefere danach mit fly deploy aus.

FROM node:24-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM caddy:2-alpine
COPY Caddyfile /etc/caddy/Caddyfile
COPY --from=build /app/dist /app/dist
node_modules
dist
.git
app = "sitelo-basic"

[http_service]
  internal_port = 80
  force_https = true
  auto_stop_machines = "stop"
  auto_start_machines = true
  min_machines_running = 0

Heroku

Führe einmal heroku stack:set container aus, danach git push heroku main: Heroku baut das Dockerfile und setzt PORT für Caddy.

build:
  docker:
    web: Dockerfile

Dein eigener Server

Kopiere den Build mit rsync -a --delete dist/ you@server:/var/www/my-site/ auf den Server und liefere ihn mit nginx.conf aus — oder mit dem Caddyfile oben, wenn du :{$PORT:80} durch deine Domain und /app/dist durch das Verzeichnis ersetzt.

server {
  listen 80;
  server_name example.com;
  root /var/www/my-site;

  location / {
    try_files $uri $uri/index.html =404;
  }

  error_page 404 /404.html;
}

Render, Railway, Fly.io, Heroku und Cloud Run sehen nur den Ordner, den sie ausliefern, deshalb lässt sich der Verweis file:../.. des Beispiels auf sitelo dort nicht auflösen — liefere eine Kopie aus, die sitelo von npm installiert.

Du arbeitest mit Cursor, Copilot oder einem anderen Agenten? Kopiere die AGENTS.md aus diesem Beispiel (oder siehe Mit KI entwickeln), damit die Werkzeuge keine React-/Next-Muster erfinden.

Erste Schritte · Mit KI entwickeln · Todo-App · Server-Islands-Beispiel