Skip to content

Route Matching

There are several rules Kitbag Router uses to determine which of your routes corresponds to the current URL.

Named

Routes without a name property cannot be a direct match.

Path Matches

Routes path must match the structure of the URL pathname.

ts
const route {
  ...
  path: '/parent/anything/child'
}

✅ parent/anything/child
❌ parent/123/child
❌ parent//child
❌ parent/child

ts
const route {
  ...
  path: '/parent/:myParam/child'
}

✅ parent/anything/child
✅ parent/123/child
❌ parent//child
❌ parent/child

ts
const route {
  ...
  path: '/parent/:?myParam/child'
}

✅ parent/anything/child
✅ parent/123/child
✅ parent//child
❌ parent/child

Query Matches

Routes query must match the structure of the URL search.

ts
const route {
  ...
  query: 'foo=bar'
}

✅ ?foo=bar
✅ ?kitbag=cat&foo=bar
❌ ?foo=123
❌ ?foo

ts
const route {
  ...
  query: 'foo=:bar'
}

✅ ?foo=bar
✅ ?kitbag=cat&foo=bar
✅ ?foo=123
❌ ?foo

ts
const route {
  ...
  query: 'foo=:?bar'
}

✅ ?foo=bar
✅ ?kitbag=cat&foo=bar
✅ ?foo=123
✅ ?foo

TIP

when your query param is optional, the entire property can be missing and the route will still match. For the example above with query foo=:?bar, the url might be /my-route without any query, or it might have an unrelated query /my-route?other=value, and still be a match because the entire foo param is optional.

Params Are Valid

Assuming a route's path and query match the structure of the URL, the last test is to make sure that values provided by the URL pass the Param parsing. By default params are assumed to be strings, so by default if structure matches, parsing will pass as well since the URL is a string. However, if you define your params with Boolean, Number, or a custom Param the value will be need to pass the param's get function.

ts
const route {
  ...
  path: '/parent/:id'
  query: 'tab=:?tab'
}

✅ parent/123
✅ parent/123?tab=true
✅ parent/123?tab=github
✅ parent/ABC?tab=true

ts
const route {
  ...
  path: path('/parent/:id', { id: Number })
  query: 'tab=:?tab'
}

✅ parent/123
✅ parent/123?tab=true
✅ parent/123?tab=github
❌ parent/ABC?tab=true

ts
const route {
  ...
  path: path('/parent/:id', { id: Number })
  query: query('tab=:?tab', { tab: Boolean })
}

✅ parent/123
✅ parent/123?tab=true
❌ parent/123?tab=github
❌ parent/ABC?tab=true

Ranking

If there are more than 1 routes that pass the rules then we sort the results by the following.

  1. Optional Params: prioritize routes that match the greater number of optional path and query params
  2. Route Depth: prioritize routes that are more deeply nested