GioJSdocs
On this page

gio.config.ts

The optional project-root file for what only JavaScript can express: Node plugins that run around every request the worker handles.

gio.config.ts
import { defineConfig } from '@gio.js/core';
import { requestTimer } from './lib/request-timer';

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

Reference

File name and location

gio.config.ts or gio.config.js (.ts first) in the project root, next to app/. Without one, GioJS runs with no plugins.

Its default export is a GioConfig; plugins is currently its only key. Every key, the plugin interface and its hooks are documented on gio.config.ts reference.

gio.config.ts or gio.toml?

SettingFile
Node plugins (onRequest, onResponse, onStartup, onShutdown)gio.config.ts
Server, cache, security, images, fonts, rate limits, rules and every other settinggio.toml
Redirects, rewrites, headers and guards computed in codemiddleware.ts

Behavior

  • Loaded by the Node worker when it starts, by every worker of a pool, and again whenever a worker restarts. In development, saving the file restarts the worker.
  • Strict. The default export is checked when the worker starts. A mistake makes the worker exit with one of these errors in the log, and the server does not start (it reports that it could not connect to the worker):
text
gio.config.ts: unknown key "plugin" - did you mean "plugins"? (gio.config takes plugins; server settings belong in gio.toml)
gio.config.ts: plugins must be an array of plugins
gio.config.ts: plugins[0] must be a plugin object with a name
gio.config.ts: the default export must be an object - export default defineConfig({ ... })
  • Server-only. The file never reaches a browser bundle, so plugins may use secrets and Node APIs.

Examples

A plugin that times renders

lib/request-timer.ts
import type { GioNodePlugin } from '@gio.js/core';

const started = new Map<string, number>();

export const requestTimer: GioNodePlugin = {
  name: 'request-timer',
  version: '1.0.0',
  async onRequest(req) {
    started.set(req.id, performance.now());
    return req;
  },
  async onResponse(req, res) {
    const start = started.get(req.id);
    started.delete(req.id);
    if (start === undefined) return res;
    return { ...res, headers: { ...res.headers, 'server-timing': `render;dur=${(performance.now() - start).toFixed(1)}` } };
  },
};

An onResponse hook needs the whole body, so while one is registered pages are rendered completely instead of streamed.

Good to know

  • Unlike next.config.js, this file holds no server settings: ports, caching, headers, images and the rest are in gio.toml, which the Rust server reads. An unknown key here is an error, not a no-op.
  • Plugins run in the order of the array. An onRequest that returns a response answers the request without rendering.
  • An onRequest hook that throws answers that request with 500 and the body Internal Server Error (plugin: <name>). An onResponse hook that throws is logged and skipped: the response goes out as it was before that hook. Neither takes the worker down.

Version history

VersionChanges
v0.1.0-beta.8Validated at startup: unknown keys and plugins without a name are errors. defineConfig and the GioConfig type.
v0.1.0-beta.1Introduced, as gio.config.ts or gio.config.js, with Node plugins.