GioJSdocs
On this page

gio routes

List every URL a GioJS app serves - pages, route handlers, WebSockets and metadata routes - discovered exactly as the server does, without starting it.

npx gio routes
bash
gio routes [--json]

Reference

OptionTypeDefaultDescription
--jsonbooleanfalsePrint { "routes": [...] } instead of the table (see JSON output).
-h, --helpboolean-Print the help and exit with 0.

Behavior

gio routes runs the route discovery of @gio.js/core through tsx, so it needs no server binary. It loads the project's .env files first (development files when NODE_ENV=development, production otherwise), then imports every route.ts to read its exports, as the server does at startup. Page modules are not imported.

text
Route            Type            File                            Wrapped by
/                page            app/(site)/page.tsx             layout app/ > app/(site)/  error app/  not-found app/
/about           page            app/(site)/about/page.tsx       layout app/ > app/(site)/  error app/  not-found app/
/api/notes       route GET,POST  app/api/notes/route.ts
/posts/:id       page            app/(site)/posts/[id]/page.tsx  layout app/ > app/(site)/  loading app/(site)/posts/[id]/  error app/  not-found app/
/robots.txt      metadata        app/robots.ts
/ws/rooms/:room  websocket       app/ws/rooms/[room]/route.ts

6 routes, 2 dynamic   (:param one segment, *param catch-all, *param? optional catch-all)
TypeWhat it is
pageA page.tsx. Wrapped by lists its layouts, outermost first, and the nearest loading, error and not-found file, by folder.
route GET,POSTA route.ts with the HTTP methods it exports.
route (failed to load)A route.ts that threw when imported. The reason is printed below the table.
websocketA route.ts that exports wsHandler. One that also exports methods gets a route row too.
metadataapp/sitemap.*, app/robots.* or app/manifest.*, at /sitemap.xml, /robots.txt and /manifest.webmanifest.

Patterns use the router's syntax: :id for a [id] folder, *slug for [...slug] and *slug? for [[...slug]]. Route groups ((site)) do not appear in the URL. Static segments sort before dynamic ones, the way matching prefers them.

JSON output

Each entry of routes:

FieldTypeDefaultDescription
patternstring-The URL pattern, /posts/:id.
kindstring-page, route, websocket or metadata.
methodsstring[]-["GET"] for pages and metadata routes, the exported methods for a route, [] for a WebSocket handler or a route that failed to load.
filestring-Project-relative path, with / separators.
paramsobject[]-The dynamic segments, in order: { name, catchAll, optional }.
layoutsstring[]-Pages: the layout files, outermost first. Empty otherwise.
loadingstring | null-Pages: the nearest loading file.
errorstring | null-Pages: the nearest error file.
notFoundstring | null-Pages: the nearest not-found file.
loadErrorstring-Only on a route.ts that failed to import: the error message.
json
{
  "routes": [
    {
      "pattern": "/posts/:id",
      "kind": "page",
      "methods": ["GET"],
      "file": "app/(site)/posts/[id]/page.tsx",
      "params": [{ "name": "id", "catchAll": false, "optional": false }],
      "layouts": ["app/layout.tsx", "app/(site)/layout.tsx"],
      "loading": "app/(site)/posts/[id]/loading.tsx",
      "error": "app/error.tsx",
      "notFound": "app/not-found.tsx"
    }
  ]
}

Anything a route.ts prints while it is imported goes to stderr, so the JSON on stdout stays parseable.

Examples

A route that fails to load

text
$ npx gio routes
Route       Type                    File                            Wrapped by
/           page                    app/(site)/page.tsx             layout app/ > app/(site)/  error app/  not-found app/
/logout     route (failed to load)  app/logout/route.ts
...

5 routes, 1 dynamic   (:param one segment, *param catch-all, *param? optional catch-all)
! app/logout/route.ts failed to load - the server answers 500 for its URL (and closes WebSocket connections with 1011) until it is fixed: GIO_SESSION_SECRET is not set. Sessions need a secret of at least 32 bytes in production. ...

The server starts anyway and answers that URL with 500. Here the module creates its session storage at import time and production needs a secret: NODE_ENV=development npx gio routes lists it with the development .env files.

List the API routes in a script

bash
npx gio routes --json | node -e '
  const { routes } = JSON.parse(require("fs").readFileSync(0, "utf8"));
  for (const r of routes) if (r.kind === "route") console.log(r.methods.join(","), r.pattern);
'

Good to know

  • Route conflicts (two files claiming one URL) fail the command with the same error the server would stop with, and exit code 1.
  • There must be an app/ directory: without one it exits with 1 and says to run from the project root or set GIO_APP_DIR.
  • A route.ts that fails to import is listed, not fatal: the exit code stays 0.
  • Rewrites, redirects and guards from gio.toml or middleware.ts are not routes and are not listed.

Version history

VersionChanges
v0.1.0-beta.8Introduced.