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 routespnpm exec gio routesyarn gio routesbunx gio routesgio routes [--json]Reference
| Option | Type | Default | Description |
|---|---|---|---|
--json | boolean | false | Print { "routes": [...] } instead of the table (see JSON output). |
-h, --help | boolean | - | 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.
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)| Type | What it is |
|---|---|
page | A page.tsx. Wrapped by lists its layouts, outermost first, and the nearest loading, error and not-found file, by folder. |
route GET,POST | A 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. |
websocket | A route.ts that exports wsHandler. One that also exports methods gets a route row too. |
metadata | app/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:
| Field | Type | Default | Description |
|---|---|---|---|
pattern | string | - | The URL pattern, /posts/:id. |
kind | string | - | page, route, websocket or metadata. |
methods | string[] | - | ["GET"] for pages and metadata routes, the exported methods for a route, [] for a WebSocket handler or a route that failed to load. |
file | string | - | Project-relative path, with / separators. |
params | object[] | - | The dynamic segments, in order: { name, catchAll, optional }. |
layouts | string[] | - | Pages: the layout files, outermost first. Empty otherwise. |
loading | string | null | - | Pages: the nearest loading file. |
error | string | null | - | Pages: the nearest error file. |
notFound | string | null | - | Pages: the nearest not-found file. |
loadError | string | - | Only on a route.ts that failed to import: the error message. |
{
"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
$ 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
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 with1and says to run from the project root or setGIO_APP_DIR. - A
route.tsthat fails to import is listed, not fatal: the exit code stays0. - Rewrites, redirects and guards from
gio.tomlormiddleware.tsare not routes and are not listed.
Related
gio typegen- the same discovery, written as types- Layouts & Pages and Route Handlers
- Project Structure
Version history
| Version | Changes |
|---|---|
v0.1.0-beta.8 | Introduced. |