GioJSdocs

Configuration

All GioJS configuration lives in gio.toml at the project root. Every field is optional - defaults are production-ready.

Full reference

toml
[app]
name = "my-app"
router = "app"          # "app" | "pages"

[server]
host = "0.0.0.0"        # bind address
port = 3000
http2 = true            # HTTP/2 support
max_body_bytes = 2097152  # request body limit (2 MiB)

[server.tls]
enabled = false         # set true to terminate TLS in GioJS directly
cert_path = "/path/to/cert.pem"
key_path  = "/path/to/key.pem"

[[fonts]]               # self-hosted fonts, repeat per font file
family = "Inter"
url    = "/fonts/inter.woff2"
weight = 400            # default 400
style  = "normal"       # default "normal"

[images]
allowed_widths = [16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]
quality = 75            # 1-100
disk_max_bytes = 536870912    # on-disk image cache cap (512 MiB)
max_remote_bytes = 20971520   # max fetched remote source size (20 MiB)

[[images.remote_patterns]]
protocol = "https"      # default "https"
hostname = "images.example.com"
pathname = "/photos/*"  # optional; exact match, or prefix with trailing *

[css]
enabled = true          # CSS pipeline
minify = true
critical_extraction = true

[websocket]
enabled = true
max_connections = 1000
ping_interval_secs = 30

[[rate_limits]]         # repeat per path rule; /_gio/image honors these too
path = "/api/*"
per_ip = 100            # requests per window (default 100)
window_seconds = 60     # default 60
burst = 20              # default 20
key_header = "x-api-key"  # optional: key on a header value instead of IP

[[redirects]]           # evaluated in Rust before routing (see Middleware)
from = "/old-blog/:slug"
to = "/posts/:slug"
status = 301            # 301/302/307/308, default 302

[[rewrites]]            # serve another route without changing the URL
from = "/latest"
to = "/posts/newest"

[[headers]]             # stamp response headers on matching paths
path = "/api/*"
[headers.headers]
x-frame-options = "DENY"

[[guards]]              # cookie gate: redirect when the cookie is absent
path = "/admin/*"
require_cookie = "session"
redirect_to = "/login"

[i18n]
locales = ["en", "de"]  # empty = i18n disabled
default_locale = "en"
detect_from = ["path", "accept-language", "cookie"]

[metrics]
enabled = false         # expose /_gio/metrics (Prometheus); off when this section is absent
token = ""              # require "Authorization: Bearer <token>" when set
ip_allowlist = []       # restrict by client IP, e.g. ["10.0.0.5"]

Health & metrics

GioJS serves two built-in observability endpoints directly from the Rust layer - no Node round-trip, so they stay responsive even under load:

EndpointDefaultDescription
/_gio/healthalways onLiveness probe - always returns 200 with a JSON body: {status, http2, tls, deploymentId, nodeReady, cacheEntries, uptimeSecs}. nodeReady is false while the Node SSR worker is respawning (cached and static content still serves) - readiness probes should check that field.
/_gio/metricsoffPrometheus exposition (request counts, latency histograms, cache hit ratio, IPC timing). Returns 404 until enabled via [metrics].

Metrics are opt-in so you never expose them by accident. Turn them on, and lock them down for anything beyond localhost:

toml
[metrics]
enabled = true          # serve /_gio/metrics

# Secure it for production - use either or both:
token        = "a-long-random-secret"     # require Authorization: Bearer <token>
ip_allowlist = ["10.0.0.5", "10.0.0.6"]   # only allow these client IPs
bash
# Scrape with a token:
curl -H "Authorization: Bearer a-long-random-secret" \
  http://localhost:3000/_gio/metrics
In production (NODE_ENV not development), GioJS logs a warning at startup when neither token norip_allowlist is set - unauthenticated metrics are fine on localhost but should never face the public internet.

Environment variables

A few runtime knobs live in the environment rather thangio.toml (the listen host and port are configured in[server], not via env):

VariableDescriptionDefault
GIO_APP_DIRPath to the app/ directory; gio.toml is loaded from its parentapp
GIO_DEPLOYMENT_IDPin the deployment ID across pods (otherwise derived from the build content)content-derived
GIO_SOCKET_PATHRust-to-Node IPC path; the server passes the resolved value to the Node workerper-instance .gio/ipc-<pid>-<rand>.sock (Unix), unique named pipe (Windows)
GIO_SITE_URLAbsolute base URL for sitemap.xml during gio exportunset
NODE_ENVdevelopment enables dev mode (file watcher, dev endpoints)unset
RUST_LOGRust log filter (info/debug/trace)info

Static page caching

Export revalidate from any page module to control caching:

typescript
// Cache forever (ISR: never revalidate)
export const revalidate = false;

// Cache for 60 seconds, then revalidate
export const revalidate = 60;

// Never cache (default when not set)
// (omit the export)
revalidate = false maps to a one-year TTL (31536000 seconds) in the Rust cache layer - the standard sentinel for "cache indefinitely."