Routing
Dinou uses a file-system based router. Your file structure defines your URL paths.
Overview
Any file named page.jsx, page.tsx, page.js, or page.ts inside the src directory automatically becomes a public route.
Basic & Dynamic Routes
Dinou supports various pattern matching strategies for dynamic routing:
| Pattern | File Path | URL Example | Params (params) |
|---|---|---|---|
| Static | src/page.jsx | / | {} |
| Dynamic | src/blog/[slug]/page.jsx | /blog/hello | { slug: 'hello' } |
| Optional | src/blog/[[slug]]/page.jsx | /blog | { slug: undefined } |
| Catch-all | src/blog/[...slug]/page.jsx | /blog/a/b/c | { slug: ['a','b','c'] } |
| Optional Catch-all | src/blog/[[...slug]]/page.jsx | /blog | { slug: [] } |
Note
params prop to page, layout, error,not_found, and slot pages. Query parameters (e.g., ?q=hello) are NOT passed as props; use the useSearchParams() hook instead.Optional Segments Rules
Dinou enforces a strict No-Gap Rule when using deep nested optional segments like [[warehouse]]/[[aisle]].
You can omit optional segments only if they are at the end of the URL.
/inventory/main ✅
/inventory ✅
You cannot skip an earlier segment and define a later one.
❌ Impossible to represent in URL
Catch-all Constraints
Because Catch-all segments ([...slug]) consume the rest of the URL, they must always be the terminal (last) segment of a route definition. You cannot place other static or dynamic folders inside a Catch-all folder.
Advanced Routing
Route Groups (folder)
Folders wrapped in parentheses are omitted from the URL path.
- src/(auth)/login/page.jsx → /login
- src/(marketing)/about/page.jsx → /about
- src/(marketing)/(nested)/about/page.jsx → /about
Why use them?
Route Groups allow you to keep your project structure logical (e.g., grouping all authentication-related routes together) without affecting the public URL structure.
Parallel Routes @slot
You can define slots (e.g., @sidebar, @header) to render multiple pages in the same layout simultaneously.
- src/dashboard/@sidebar/page.jsx
- src/dashboard/(group-a)/@bottom/page.jsx
- src/dashboard/layout.jsx
The layout.jsx receives the slots as props alongside children:
function Layout({ children, sidebar, bottom })Requirement
Why use them?
Parallel routes allow independent UI sections and, crucially, Error Containment. If one section fails, it doesn't have to break the entire page.
