File conventions
File conventions in the Routing and data guide.
A file's path below src/routes is its URL. Folders are URL segments. The grammar is parseRouteFile from
@shadow-js/router/vite; the table below shows the URL each convention produces.
| File or folder | Meaning | Pattern |
|---|---|---|
index.tsx |
The index of its folder | /, /posts for posts/index.tsx |
about.tsx |
A static segment | /about |
posts/[id].tsx |
A required param | /posts/:id |
[[lang]]/about.tsx, [[lang]].tsx |
An optional param | /:lang?/about, /:lang? |
docs/[...rest].tsx |
A splat: the rest of the path, at least one segment. It is not the folder itself: /docs is not matched. It must be the last segment, as a file name |
/docs/*rest |
docs/[[...rest]].tsx |
An optional catch-all: the rest of the path, or nothing. It matches the folder too | /docs/*rest? |
(marketing)/pricing.tsx |
A group: a folder that adds no URL segment | /pricing |
_layout.tsx |
The layout of its folder; it wraps the folder's pages and every folder below | the folder's pattern |
_template.tsx |
The template of its folder: wraps like a layout, but starts over on every navigation (see Templates) | the folder's pattern |
-components/card.tsx, -notes.ts |
Ignored: a name that starts with - (colocated helpers) |
none |
.draft.tsx, .git/ |
Ignored: a name that starts with . |
none |
x.d.ts, routeTree.gen.ts |
Ignored: declarations and the generated route tree | none |
[.]well-known/security.ts |
[x] around one punctuation character makes it literal |
/.well-known/security |
api/posts/[id].ts with GET/POST exports and no default export |
An API route | /api/posts/:id |
Extensions that count: .tsx, .ts, .jsx, .js, .mts, .mjs. A param name must be a JavaScript-like
identifier ([user_id] is valid, [user-id] is not).
The scanner turns the folder into a tree and rejects ambiguity at build time instead of picking a winner. Every
problem is a RouteScanError that lists the files involved, and each conflict message ends with a fix: line:
| Code | Cause |
|---|---|
ROUTE_DUPLICATE |
Two files give the same URL pattern (about.tsx and about/index.tsx, or (a)/x.tsx and (b)/x.tsx) |
ROUTE_AMBIGUOUS |
Two patterns can match the same URL ([id].tsx and [slug].tsx in one folder) |
ROUTE_PAGE_API_CONFLICT |
A page and an API route with a GET or HEAD export answer the same path |
ROUTE_MIXED_EXPORTS |
A file has HTTP-method exports (or a default apiRoute(...)) and also a default component, or both kinds of API export, or _layout.tsx or _template.tsx has method exports |
ROUTE_API_NOT_READABLE |
A default apiRoute(...) whose argument is not an object literal with plain method names (a variable, a spread, a computed key), or that names no HTTP method |
ROUTE_NO_EXPORTS |
A script under routes exports nothing a route can use, or a _template.tsx has no default export |
ROUTE_DYNAMIC_PARAMS_INVALID |
An export const dynamicParams whose value is not the literal true or false, that sits in a layout, a template, an API route or a stream route, that is false on a path without params, or that is false without a prerender export |
ROUTE_RESERVED_PREFIX |
A route under /_dusk (the server function endpoint and health check live there) |
ROUTE_FILE_NAME_INVALID, ROUTE_PARAM_INVALID, ROUTE_BRACKET_UNMATCHED, ROUTE_SPLAT_NOT_LAST, ROUTE_GROUP_INVALID, ROUTE_PATTERN_INVALID |
A file or folder name the grammar rejects |
ROUTE_PARSE_ERROR, ROUTE_LIMIT, ROUTE_OPTION_INVALID |
A syntax error in a route file, more than 10 000 files or 32 folders deep, an invalid plugin option |
A build error names the conflicting files and suggests a fix. For ROUTE_DUPLICATE, remove one page or give it a different URL; changing the component name does not change its route.