Dynamic API Routes
Learn how to create dynamic API endpoints with path parameters, catch-all routes, and optional segments.
Dynamic API routes allow you to create endpoints that match patterns rather than exact paths. Use square brackets in your file names to define dynamic segments — the file path determines the route.
/ API routes — the filename becomes the route segment. Write your Hono routes without the /api prefix.File Structure
Dynamic segments are created using square brackets in file or folder names:
| Pattern | File/Folder Name | Matches |
|---|---|---|
| [id] | Single dynamic segment | /api/posts/123, /api/posts/abc |
| [category]/[slug] | Multiple dynamic segments | /api/posts/tech/hello-world |
| [...path] | Catch-all (required) | /api/files/a, /api/files/a/b/c |
| [[...slug]] | Catch-all (optional) | /api/docs, /api/docs/a/b |
Single Dynamic Parameter
Use [name] in the filename for a single dynamic segment:
With Hono
With Plain Function
Multiple Dynamic Parameters
Combine multiple dynamic segments in a single route:
| URL | params |
|---|---|
| /api/posts/tech/hello-world | { category: "tech", slug: "hello-world" } |
| /api/posts/lifestyle/tips | { category: "lifestyle", slug: "tips" } |
Catch-all Routes
Use [...name] in the filename to match any number of segments:
| URL | path value |
|---|---|
| /api/files | |
| /api/files/images | images |
| /api/files/images/2024 | images/2024 |
| /api/files/docs/api/reference | docs/api/reference |
Global Catch-all
Optional Catch-all
Use [[...name]] to make the catch-all optional:
| URL | slug value |
|---|---|
| /api/docs | undefined (home page) |
| /api/docs/getting-started | getting-started |
| /api/docs/api/reference | api/reference |
Nested Dynamic Routes
Combine static and dynamic segments for complex routing:
Query Parameters
Combine dynamic path parameters with query parameters:
Route Priority
When multiple routes could match a URL, Bini.js resolves them in this order:
- Static routes — exact matches
- Dynamic single segments —
[id] - Catch-all segments —
[...slug] - Optional catch-all —
[[...slug]]
Complete Example
A full-featured store API with dynamic routing: