Sitio básico

El sitio sitelo útil más pequeño: una página, una hoja de estilos y configuraciones de hosting que publican dist/. Copia las configuraciones a cualquier proyecto sitelo — solo asumen npm run build → dist/.

Hay una copia ejecutable en el repositorio de sitelo, en examples/basic/.

Qué obtienes

Estructura del proyecto

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: 'es' },
    head(
      title('sitelo — ejemplo básico'),
      link({ rel: 'stylesheet', href: '/styles.css' }),
    ),
    body(h1('Hola desde sitelo')),
  )

Compilación

npm install
npm run build

Despliegue

Desde el monorepo de sitelo, pon el directorio raíz o base de la plataforma en 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"
}

Desplegar en Vercel · Desplegar en Netlify (pon el directorio base en examples/basic cuando te lo pida).

Cloudflare

Cloudflare recomienda ahora Workers para proyectos nuevos. npx wrangler deploy compila y sube dist/, o conecta el repositorio en el panel de Cloudflare. Si usas Pages, pon npm run build como comando de compilación y dist como directorio de salida.

{
  "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

Conecta el repositorio en 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

Asocia cloudfront-function.js a las solicitudes de visor de la distribución y añade respuestas de error personalizadas para 403 y 404 que devuelvan /404.html con estado 404. Después sube cada compilación:

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

Crea la Static Web App con / como ubicación de la app y dist como ubicación de salida. sitelo copia public/staticwebapp.config.json a dist/, donde Azure lo lee y sirve 404.html para las URL desconocidas.

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

Google Cloud

Firebase Hosting: elige un proyecto con firebase use --add y firebase deploy compila y sube el sitio. Para Cloud Run, gcloud run deploy --source . compila el Dockerfile de más abajo.

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

GitLab Pages

Copia .gitlab-ci.yml a la raíz de un repositorio de GitLab; el job compila y publica dist/.

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

Render

Crea un Blueprint a partir de render.yaml, o pon el mismo comando de compilación y directorio de publicación en un sitio estático nuevo. Las URL limpias y 404.html funcionan sin reglas.

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

DigitalOcean App Platform

Pon tu repositorio en github.repo y ejecuta doctl apps create --spec .do/app.yaml.

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 compila el Dockerfile (ver Fly.io más abajo), así que no hay nada que configurar. En un proyecto sin él, añade en su lugar la variable de servicio RAILPACK_SPA_OUTPUT_DIR=dist: Railpack servirá entonces dist/ a través del Caddyfile, que responde a las URL desconocidas con 404.html.

:{$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

El Dockerfile compila con Node y sirve dist/ con Caddy. Ejecuta fly launch para crear la app y luego fly deploy.

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

Ejecuta heroku stack:set container una vez y luego git push heroku main: Heroku compila el Dockerfile y define PORT para Caddy.

build:
  docker:
    web: Dockerfile

Tu propio servidor

Copia la compilación al servidor con rsync -a --delete dist/ you@server:/var/www/my-site/ y sírvela con nginx.conf, o con el Caddyfile de arriba cambiando :{$PORT:80} por tu dominio y /app/dist por el directorio.

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 y Cloud Run solo ven la carpeta que despliegan, así que el enlace file:../.. del ejemplo a sitelo no se resolverá allí: despliega una copia que instale sitelo desde npm.

¿Trabajas con Cursor, Copilot u otro agente? Copia el AGENTS.md de este ejemplo (o consulta Crear con IA) para que las herramientas no se inventen patrones de React o Next.

Primeros pasos · Crear con IA · App de tareas · Ejemplo de islas de servidor