Dynamic Routes
Dynamic route segments, catch-all routes, optional segments, and advanced routing patterns in Manic.
Dynamic Routes
TL;DR
Dynamic routes use [param] syntax to capture URL segments at runtime. Manic supports single segments [id], nested segments [userId]/[postId], and catch-all segments [...slug].
What It Is
Dynamic routes allow your application to handle variable URL segments without creating individual files for each possible value:
| Pattern | Syntax | Matches | Captures |
|---|---|---|---|
| Single | [id] | /posts/123 | { id: "123" } |
| Multiple | [userId]/[postId] | /users/1/posts/99 | { userId: "1", postId: "99" } |
| Catch-all | [...slug] | /docs/a/b/c | { slug: "a/b/c" } |
Prerequisites
- Routing Guide - Basic routing concepts
- API Routes - For REST endpoints
Quick Start
Create a Dynamic Route
// app/routes/posts/[id].tsx
import React from 'react';
import { } from 'manicjs';
export default function () {
const { } = ();
return (
<>
<>Post #{.}</>
<>Reading post data for ID: {.}</>
</>
);
}Single Dynamic Segment
Use [param] to capture a single URL segment:
// app/routes/users/[id].tsx
import React from 'react';
import { } from 'manicjs';
export default function () {
const { } = ();
return <>User ID: {.}</>;
}Matches:
/users/123→{ id: "123" }/users/hello-world→{ id: "hello-world" }- ❌
/users/123/comments(too many segments)
Multiple Dynamic Segments
Nest folders to capture multiple params:
// app/routes/users/[userId]/posts/[postId].tsx
import React from 'react';
import { } from 'manicjs';
export default function () {
const { } = ();
return <>User {.}, Post {.}</>;
}Matches:
/users/42/posts/99→{ userId: "42", postId: "99" }
Catch-All Routes
Use [...param] to match any number of segments:
// app/routes/docs/[...slug].tsx
import React from 'react';
import { } from 'manicjs';
export default function () {
const { } = (); // slug = "guides/installation"
return <>Doc: {.}</>;
}Matches:
/docs/guides→{ slug: "guides" }/docs/guides/installation→{ slug: "guides/installation" }/docs/api/v2/endpoints/users→{ slug: "api/v2/endpoints/users" }
Combining Catch-All with a Folder Index
To match both /docs and /docs/anything/below, pair a folder index.tsx with a sibling catch-all file:
The static index.tsx wins for /docs (score 200) and [...slug].tsx handles every deeper URL (score 101).
API Routes
Dynamic routes work the same way in app/api/:
// app/api/users/[id]/index.ts
import { } from 'hono';
const = new ();
.('/', () => {
const = ..('id');
return .({ });
});
export default ;See Also
- Routing Guide - Basic routing concepts
- API Routes - Backend endpoints
- Router API - Complete router documentation