How to control route priority
Piko orders overlapping routes by category first (static > dynamic > catch-all), then by tiebreakers within a category. For the base priority rules see routing rules reference. This guide covers the tiebreakers and how to verify the order at build time.
Tiebreaker order within a category
When two routes share a category:
- Path depth. More specific paths (more segments) take priority.
- Static segments. Routes with more static segments win.
- Alphabetical. Identical specificity falls back to lexical order.
Resolve a nested-dynamic ambiguity
Given:
pages/
├── {category}/
│ ├── index.pk -> /{category}
│ └── {id}.pk -> /{category}/{id}
└── docs/
└── {id}.pk -> /docs/{id}
A request to /docs/42 could match either /docs/{id} or /{category}/{id}. The router picks /docs/{id} because it carries one static segment (docs), and the other route carries zero. Static beats dynamic at the same depth.
Verify the registration order
The build prints every registered route in priority order. Run a build and grep for the page log lines (logged at Internal level, with the field key routePattern):
Registering page route routePattern=/docs/{id}
Registering page route routePattern=/docs
Registering page route routePattern=/{category}/{id}
Registering page route routePattern=/{category}
If a page is missing or appears in an unexpected position, the file layout, not the router, is wrong. Check that each conflicting page is in the file system path the router would expect.
Disambiguate by adding a static segment
When two dynamic routes collide and the priority rules do not pick the intended winner, the most reliable fix is to add a static segment to one of them. Renaming pages/{category}/{id}.pk to pages/{category}/items/{id}.pk changes the route to /{category}/items/{id}, which sorts above any sibling /{a}/{b} route.
See also
- Routing rules reference for the base rules and pattern syntax.
- About routing for why Piko computes precedence from filename shape.
- How to use catch-all routes for the lowest-priority matcher.
- How to use dynamic routes for parameter binding.