GioJSdocs
On this page

defineConfig

Type gio.config.ts, the file for settings only JavaScript can express - today, Node plugins.

gio.config.ts
import { defineConfig } from '@gio.js/core';
import { auditPlugin } from './lib/audit-plugin.ts';

export default defineConfig({
  plugins: [auditPlugin],
});

Reference

defineConfig(config) returns config unchanged; it gives the default export the GioConfig type. The file is gio.config.ts or gio.config.js at the project root, next to gio.toml, and it is optional.

KeyTypeDefaultDescription
pluginsGioNodePlugin[][]Node plugins, run in order around every request the worker handles. Each one needs a name.

Plugin fields

Each entry of plugins is a GioNodePlugin; the gio.config.ts reference covers its hooks in full.

FieldTypeDefaultDescription
name (required)string-Shown in errors and logs.
version (required)string-Your plugin's version (required by the type).
onRequest(req: IPCRequest) => Promise<IPCRequest | IPCResponse>-Runs before routing. Return the (possibly changed) request, or a response to answer without rendering - the remaining plugins are skipped.
onResponse(req: IPCRequest, res: IPCResponse) => Promise<IPCResponse>-Runs on the response before it goes back to Rust. Its presence turns streaming SSR off, since it must see the whole body.
onStartup() => Promise<void>-Runs when a worker process starts - in every worker of a pool, and again after a respawn.
onShutdown() => Promise<void>-Runs when a worker shuts down, plugins in reverse order.

Behavior

  • The worker loads the file once at boot. An onRequest that throws answers that request with a 500 (Internal Server Error (plugin: name)); an onResponse that throws is logged and the response goes out as it was. Neither crashes the worker.
  • The file is strict, like gio.toml: an unknown key, a plugins value that is not an array, or a plugin without a name stops the worker at boot with an error naming the file.
text
gio.config.ts: unknown key "plugin" - did you mean "plugins"? (gio.config takes plugins; server settings belong in gio.toml)

Examples

A response header plugin

gio.config.ts
import { defineConfig, type GioNodePlugin } from '@gio.js/core';

const workerHeader: GioNodePlugin = {
  name: 'worker-header',
  version: '1.0.0',
  async onResponse(req, res) {
    return { ...res, headers: { ...res.headers, 'x-rendered-by': `worker ${process.env.GIO_WORKER_INDEX ?? '0'}` } };
  },
};

export default defineConfig({
  plugins: [workerHeader],
});

Every page and route-handler response then carries x-rendered-by: worker 0 (or the index of the pool worker that answered).

Good to know

  • Server settings belong in gio.toml. Ports, caching, security, rules - everything declarative - lives there, read by the Rust server. gio.config.ts is read by the Node worker only.
  • Plugins see what the worker sees. Requests Rust answers itself - cache hits, static files, rule redirects, guards - never reach them.
  • Pools run every plugin in every worker. Guard one-time jobs with GIO_WORKER_INDEX, which is "0" in one worker per server.
  • Tests load it too. renderPage and callRoute run your plugins, including onStartup, and resetTestApp runs onShutdown.
  • Changes to gio.config.ts change the derived deployment id (unless GIO_DEPLOYMENT_ID pins it), so pages cached by the previous build are dropped.

Version history

VersionChanges
v0.1.0-beta.8Introduced defineConfig and the GioConfig type; unknown keys and unnamed plugins stop the worker at boot.