Routing Precedence
When the route of two pages match the same URL, there is a routing conflict: Vike has to decide which one to render for that URL.
Upon Route String conflicts, Vike chooses the first route from most specific to least specific. For example:
/about/team(most specific: it matches only a single URL)/about/@path(less specific: it also matches/about/company,/about/vision, ...)/about/*(less specific: it also matches/about/some/nested/path)/*(least specific: it matches all URLs)
You can find more examples at
resolvePrecedence_route-strings.spec.ts.
Upon conflicts between Filesystem Routing, Route Strings and Route Functions, Vike chooses the first route in following order:
- Route Function, returned high positive
precedencenumber (e.g.99) - Route Function, returned low positive
precedencenumber (e.g.1) - Filesystem Routing
- Route String, static (i.e. without
@/*parameter segment, e.g./about/company) - Route Function, returned no
precedencenumber (or0) - Route String, parameterized (i.e. with
@/*parameter segment, e.g./product/@productIdor/product/*) - Route Function, returned low negative
precedencenumber (e.g.-1) - Route Function, returned high negative
precedencenumber (e.g.-99)
Example (4) + (6) + (7):
// product/list/+route.js
export default '/product'// product/list/+route.ts
export default '/product'// product/item/+route.js
export default '/product/@productId'// product/item/+route.ts
export default '/product/@productId'// product/catch-all/+route.js
export default (pageContext) => {
if (!pageContext.urlPathname.startsWith('/product/')) return false
return {
precedence: -1,
pageContext: {
// E.g. redirect `/product/wrong/url` to `/product`
redirectTo: '/product'
}
}
}// product/catch-all/+route.ts
import type { PageContext } from 'vike/types'
export default (pageContext: PageContext) => {
if (!pageContext.urlPathname.startsWith('/product/')) return false
return {
precedence: -1,
pageContext: {
// E.g. redirect `/product/wrong/url` to `/product`
redirectTo: '/product'
}
}
}URL MATCHES WINNER
================== =============================== ======
/product/42 product/item/+route.js (6) ⬅️
product/catch-all/+route.js (7)
URL MATCHES WINNER
================== =============================== ======
/product product/list/+route.js (4) ⬅️
product/catch-all/+route.js (7)
URL MATCHES WINNER
================== =============================== ======
/product/wrong/url product/catch-all/+route.js (7) ⬅️
4: Route String, static (without @param segment, e.g. /about/company)
6: Route String, parameterized (with @param segments, e.g. /product/@productId or /product/*)
7: Route Function, returned low negative precedence number (e.g. -1)
Example (1) + (4):
// admin/+route.js
export default '/admin'// admin/+route.ts
export default '/admin'// login/+route.js
export default (pageContext) => {
if (pageContext.user === null) {
return {
precedence: 99
}
}
return false
}// login/+route.ts
import type { PageContext } from 'vike/types'
export default (pageContext: PageContext) => {
if( pageContext.user === null ) {
return {
precedence: 99
}
}
return false
}URL pageContext.user MATCHES WINNER
====== ================ =================== ======
/admin null login/+route.js (1) ⬅️
admin/+route.js (4)
URL pageContext.user MATCHES WINNER
====== ================ =================== ======
/admin 'brillout' admin/+route.js (4) ⬅️
1: Route Function, returned high positive precedence number
4: Route String, static (without @param segment, e.g. /about/company)
More examples at
resolvePrecedence_overall.spec.ts.