---
title: "Router Contracts"
description: "Hono defines a generic Router Contracts through the Router<T> interface, standardizing how route registration and execution path resolution behave across multiple routing backends Linear and Patter..."
last_updated: "2026-10-12T08:14:12.747835+00:00"
canonical_url: "https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing/router-contracts"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [src/router.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts)
- [src/router/linear-router/router.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/linear-router/router.ts)
- [src/types.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/types.ts)
- [src/router/pattern-router/router.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/pattern-router/router.ts)
- [src/router/reg-exp-router/router.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/reg-exp-router/router.ts)
- [src/router/reg-exp-router/matcher.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/reg-exp-router/matcher.ts)
- [src/helper/route/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts)
- [src/router/reg-exp-router/prepared-router.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/reg-exp-router/prepared-router.ts)
- [src/router/trie-router/router.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/trie-router/router.ts)
- [src/router/trie-router/node.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/trie-router/node.ts)
- [src/hono-base.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/hono-base.ts)
- [src/context.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/context.ts)
- [src/router/smart-router/router.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/smart-router/router.ts)
- [src/utils/url.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts)
- [src/router/reg-exp-router/trie.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/reg-exp-router/trie.ts)
- [src/router/reg-exp-router/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/reg-exp-router/index.ts)
- [src/router/pattern-router/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/pattern-router/index.ts)
- [src/router/trie-router/index.ts](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/trie-router/index.ts)
</details>

## Overview

Hono defines a generic Router Contracts through the `Router<T>` interface, standardizing how route registration and execution path resolution behave across multiple routing backends [Linear and Pattern Routers](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing/linear-and-pattern-routers), [RegExp Router](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing/regexp-router), and [Trie and Smart Routers](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing/trie-and-smart-routers). By establishing uniform method signatures for adding paths and matching request methods against registered endpoints, the system allows backends like `LinearRouter`, `PatternRouter`, `RegExpRouter`, and `TrieRouter` to be swapped interchangeably inside applications ([Application Core](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/core-engine/application-core)). These contracts establish strict behaviors around immutable matchers and path constraints, such as throwing `UnsupportedPathError` when conflicting route syntaxes occur during compilation or evaluation.

Sources: [src/router.ts:25-52](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L25-L52), [src/router.ts:101-103](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L101-L103), [src/router/linear-router/router.ts:11-143](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/linear-router/router.ts#L11-L143), [src/router/pattern-router/router.ts:8-42](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/pattern-router/router.ts#L8-L42), [src/router/reg-exp-router/router.ts:122-204](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/reg-exp-router/router.ts#L122-L204), [src/router/trie-router/router.ts:5-27](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/trie-router/router.ts#L5-L27), [src/router/smart-router/router.ts:4-61](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/smart-router/router.ts#L4-L61), [src/hono-base.ts:65-65](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/hono-base.ts#L65-L65)

## Unified Router Interface Architecture

### Router Interface Contract

The generic `Router<T>` interface establishes the core contract that every routing backend implements. It defines three primary members: a `name` string property identifying the router implementation, an `add` method for registering paths, and a `match` method for executing lookups.

```typescript
 * Interface representing a router.
 *
 * @template T - The type of the handler.
 */
export interface Router<T> {
  /**
   * The name of the router.
   */
  name: string

  /**
   * Adds a route to the router.
   *
   * @param method - The HTTP method (e.g., 'get', 'post').
   * @param path - The path for the route.
   * @param handler - The handler for the route.
   */
  add(method: string, path: string, handler: T): void

  /**
   * Matches a route based on the given method and path.
   *
   * @param method - The HTTP method (e.g., 'get', 'post').
   * @param path - The path to match.
   * @returns The result of the match.
   */
  match(method: string, path: string): Result<T>
}
```
Sources: [src/router.ts:25-52](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L25-L52)

To support this interface uniformly, the module exports constants defining HTTP methods and error messages utilized during route registration and compilation checks.

```typescript
 * Constant representing all HTTP methods in uppercase.
 */
export const METHOD_NAME_ALL = 'ALL' as const
/**
 * Constant representing all HTTP methods in lowercase.
 */
export const METHOD_NAME_ALL_LOWERCASE = 'all' as const
/**
 * Array of supported HTTP methods.
 */
export const METHODS = ['get', 'post', 'put', 'delete', 'options', 'patch'] as const
/**
 * Error message indicating that a route cannot be added because the matcher is already built.
 */
export const MESSAGE_MATCHER_IS_ALREADY_BUILT =
  'Can not add a route since the matcher is already built.'

```
Sources: [src/router.ts:7-23](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L7-L23)

> [!NOTE]
> The `METHOD_NAME_ALL` and `METHOD_NAME_ALL_LOWERCASE` constants represent wildcard HTTP methods ('ALL' and 'all') used to register handlers matching any incoming request method.

### Interface Implementation Registry

Different routing strategies fulfill the `Router<T>` contract across the codebase, exporting their constructors or helper utilities from respective entrypoints.

| Router Module | Exported Symbols | Description |
| :--- | :--- | :--- |
| `src/router/reg-exp-router/index.ts` | `RegExpRouter`, `PreparedRegExpRouter`, `buildInitParams`, `serializeInitParams` | Compiles route trees into single regular expressions |
| `src/router/pattern-router/index.ts` | `PatternRouter` | Evaluates basic pattern matching for lightweight requirements |
| `src/router/trie-router/index.ts` | `TrieRouter` | Traverses path segments using node trees |

```typescript
/**
 * @module
 * RegExpRouter for Hono.
 */

export { RegExpRouter } from './router'
export { PreparedRegExpRouter, buildInitParams, serializeInitParams } from './prepared-router'
```
Sources: [src/router/reg-exp-router/index.ts:1-7](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/reg-exp-router/index.ts#L1-L7)

```typescript
/**
 * @module
 * PatternRouter for Hono.
 */

```
Sources: [src/router/pattern-router/index.ts:1-5](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/pattern-router/index.ts#L1-L5)

```typescript
/**
 * @module
 * TrieRouter for Hono.
 */

export { TrieRouter } from './router'
```
Sources: [src/router/trie-router/index.ts:1-6](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router/trie-router/index.ts#L1-L6)

## Match Result Representations and Parameter Extraction

### Result Data Tuples and Parameter Formats

Route resolution yields a `Result<T>` tuple that accommodates two distinct structural layouts depending on the underlying router implementation. Each format pairs matched handlers with parameter mappings or value stashes.

```typescript
 * Type representing a map of parameter indices.
 */
export type ParamIndexMap = Record<string, number>
/**
 * Type representing a stash of parameters.
 */
export type ParamStash = string[]
/**
 * Type representing a map of parameters.
 */
export type Params = Record<string, string>
/**
 * Type representing the result of a route match.
 *
 * The result can be in one of two formats:
 * 1. An array of handlers with their corresponding parameter index maps, followed by a parameter stash.
 * 2. An array of handlers with their corresponding parameter maps.
 *
 * Example:
 *
 * [[handler, paramIndexMap][], paramArray]
 * ```typescript
 * [
 *   [
 *     [middlewareA, {}],                     // '*'
 *     [funcA,       {'id': 0}],              // '/user/:id/*'
 *     [funcB,       {'id': 0, 'action': 1}], // '/user/:id/:action'
 *   ],
 *   ['123', 'abc']
 * ]
 * ```
 *
 * [[handler, params][]]
 * ```typescript
 * [
 *   [
 *     [middlewareA, {}],                             // '*'
 *     [funcA,       {'id': '123'}],                  // '/user/:id/*'
 *     [funcB,       {'id': '123', 'action': 'abc'}], // '/user/:id/:action'
 *   ]
 * ]
 * ```
 */
export type Result<T> = [[T, ParamIndexMap][], ParamStash] | [[T, Params][]]

```
Sources: [src/router.ts:55-99](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L55-L99)

> [!NOTE]
> The first format nests a tuple of `[T, ParamIndexMap][]` alongside a separate `ParamStash` array (`string[]`), allowing parameter values to be indexed numerically. The second format directly associates handlers with fully resolved `Params` dictionaries (`Record<string, string>`).

### Parameter Data Structures

Parameter management relies on specific type definitions for maps and value arrays. The module defines three distinct type aliases to support parameter extraction during route resolution.

| Type Name | Definition | Description |
| :--- | :--- | :--- |
| `ParamIndexMap` | `Record<string, number>` | Maps parameter name keys to numeric index positions within the parameter stash array. |
| `ParamStash` | `string[]` | Ordered array of extracted string parameter values referenced by index maps. |
| `Params` | `Record<string, string>` | Key-value dictionary mapping parameter names directly to their resolved string values. |

```typescript
 * Type representing a map of parameter indices.
 */
export type ParamIndexMap = Record<string, number>
/**
 * Type representing a stash of parameters.
 */
export type ParamStash = string[]
/**
 * Type representing a map of parameters.
 */
export type Params = Record<string, string>
```
Sources: [src/router.ts:55-65](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L55-L65)

## Shared Routing Errors and Matcher Constraints

### Matcher State Invariants and Error Messages

During router lifecycle management, route addition is restricted once matching structures have been compiled or initialized. The module defines a specific constant error message to indicate this constraint violation when attempting modifications after compilation.

```typescript
 * Error message indicating that a route cannot be added because the matcher is already built.
 */
export const MESSAGE_MATCHER_IS_ALREADY_BUILT =
  'Can not add a route since the matcher is already built.'

```
Sources: [src/router.ts:19-23](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L19-L23)

> [!WARNING]
> Attempting to invoke `add` after a router implementation has built its matcher triggers the error message defined by `MESSAGE_MATCHER_IS_ALREADY_BUILT`, freezing route registration to ensure thread-safe and deterministic lookups.

### Unsupported Path Error Semantics

When path structures fail validation or fall outside supported syntax patterns during registration or matching, routers throw specialized error types extending standard JavaScript exceptions.

```typescript
/**
 * Error class representing an unsupported path error.
 */
export class UnsupportedPathError extends Error {}
```
Sources: [src/router.ts:100-103](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L100-L103)

| Error Class / Constant | Underlying Value / Base | Purpose |
| :--- | :--- | :--- |
| `UnsupportedPathError` | `Error` | Signals that a given route path contains unsupported tokens or structural formatting incompatible with the router backend. |
| `MESSAGE_MATCHER_IS_ALREADY_BUILT` | `'Can not add a route since the matcher is already built.'` | Prevents post-initialization mutation of router route tables. |

```typescript
export const MESSAGE_MATCHER_IS_ALREADY_BUILT =
  'Can not add a route since the matcher is already built.'
…
*/
```
Sources: [src/router.ts:21-22](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L21-L22), [src/router.ts:102-102](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/router.ts#L102-L102)

## Route Introspection and Base Path Resolution

### Introspection Helpers and Active Route Selection

The routing helper module provides functions to inspect active request contexts and extract matching route metadata. The `matchedRoutes` function accesses the low-level match result stored on the request object using the `GET_MATCH_RESULT` constant symbol, mapping the internal tuple structure to an array of `RouterRoute` definitions.

```typescript
export const matchedRoutes = (c: Context): RouterRoute[] =>
  // @ts-expect-error c.req[GET_MATCH_RESULT] is not typed
  (c.req as unknown)[GET_MATCH_RESULT][0].map(([[, route]]) => route)
```
Sources: [src/helper/route/index.ts:32-34](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L32-L34)

```typescript
export const routePath = (c: Context, index?: number): string =>
  matchedRoutes(c).at(index ?? c.req.routeIndex)?.path ?? ''
```
Sources: [src/helper/route/index.ts:58-59](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L58-L59)

> [!NOTE]
> Both `routePath` and `baseRoutePath` accept an optional index argument. This parameter behaves similarly to `Array.prototype.at()`, allowing negative integers to count backward from the end of the matching root collection while defaulting to `c.req.routeIndex`.

```typescript
export const baseRoutePath = (c: Context, index?: number): string =>
  matchedRoutes(c).at(index ?? c.req.routeIndex)?.basePath ?? ''
```
Sources: [src/helper/route/index.ts:82-83](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L82-L83)

### Base Path Resolution and Caching

The `basePath` function computes the concrete base path with embedded parameters resolved against the active request URL. It utilizes a private `WeakMap` cache named `basePathCacheMap` to store calculated base paths per `Context` instance and index, avoiding redundant substring matching operations during nested application dispatches.

```typescript
const basePathCacheMap: WeakMap<Context, Record<number, string>> = new WeakMap()
export const basePath = (c: Context, index?: number): string => {
  index ??= c.req.routeIndex

  const cache = basePathCacheMap.get(c) || []
  if (typeof cache[index] === 'string') {
    return cache[index]
  }
```
Sources: [src/helper/route/index.ts:106-113](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L106-L113)

When the unparsed base route path contains dynamic parameters or wildcards matching `[:*]`, `basePath` splits the path via `splitRoutingPath` and iterates over each segment. It queries pattern matchers using `getPattern` to extract substring lengths directly from `c.req.path`, assembling the final prefix dynamically.

Sources: [src/helper/route/index.ts:107-141](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L107-L141)

> [!WARNING]
> Bypassing index bounds or passing uninitialized request contexts to route introspection helpers will cause lookup failures against `GET_MATCH_RESULT`. Always invoke these utilities within active request handler flows or middleware layers where routing context has been fully established.

### Execution Walkthroughs

#### Trace Sequence

The resolution of active route paths proceeds through a structured sequence of helper calls.

1. `basePath` checks the `basePathCacheMap` cache using the context and index; on a cache miss, it invokes `baseRoutePath`.
2. `baseRoutePath` calls `matchedRoutes` to retrieve the active route list.
3. `matchedRoutes` reads `(c.req as unknown)[GET_MATCH_RESULT][0]` and maps the internal tuples to return `RouterRoute[]`.

```mermaid
sequenceDiagram
    participant Context as Context (c)
    participant Helper as src/helper/route/index.ts
    participant Request as c.req

    Context->>Helper: basePath(c, index)
    Helper->>Helper: baseRoutePath(c, index)
    Helper->>Helper: matchedRoutes(c)
    Helper->>Request: access GET_MATCH_RESULT symbol
    Request-->>Helper: return internal match result tuples
    Helper-->>Context: return resolved path string
```

Sources: [src/helper/route/index.ts:32-34](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L32-L34), [src/helper/route/index.ts:82-83](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L82-L83), [src/helper/route/index.ts:107-116](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L107-L116)

## Path Tokenization for Route Group Matching

### Path Splitting and Group Extraction

The URL utility module manages route path normalization by tokenizing paths, extracting embedded parameter groups, and restoring them during route matching. The `splitRoutingPath` function coordinates this normalization process by first invoking `extractGroupsFromPath` on the raw route string.

```typescript
export const splitRoutingPath = (routePath: string): string[] => {
  const { groups, path } = extractGroupsFromPath(routePath)

  const paths = splitPath(path)
  return replaceGroupMarks(paths, groups)
}
```
Sources: [src/utils/url.ts:16-21](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts#L16-L21)

The `extractGroupsFromPath` function scans the input path for bracketed expressions matching `/\{[^}]+\}/g`. For every discovered group, it generates a placeholder mark using the pattern `@${index}` and stores the pair in an array before returning the modified path string.

```typescript
const extractGroupsFromPath = (path: string): { groups: [string, string][]; path: string } => {
  const groups: [string, string][] = []

  path = path.replace(/\{[^}]+\}/g, (match, index) => {
    const mark = `@${index}`
    groups.push([mark, match])
    return mark
  })

  return { groups, path }
}
```
Sources: [src/utils/url.ts:23-33](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts#L23-L33)

> [!NOTE]
> Parameter group extraction prevents forward-slash characters contained inside custom regex definitions (such as `{id:[0-9/]+}`) from breaking segment-based path splitting operations.

```typescript
export const splitPath = (path: string): string[] => {
  const paths = path.split('/')
  if (paths[0] === '') {
    paths.shift()
  }
  return paths
}
```
Sources: [src/utils/url.ts:8-14](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts#L8-L14)

### Group Mark Replacement

Once the path is split into individual segments via `splitPath`, the `replaceGroupMarks` function iterates backward through the stored groups to substitute temporary placeholders with their original bracketed definitions.

```typescript
const replaceGroupMarks = (paths: string[], groups: [string, string][]): string[] => {
  for (let i = groups.length - 1; i >= 0; i--) {
    const [mark] = groups[i]

    for (let j = paths.length - 1; j >= 0; j--) {
      if (paths[j].includes(mark)) {
        paths[j] = paths[j].replace(mark, groups[i][1])
        break
      }
    }
  }

  return paths
}
```
Sources: [src/utils/url.ts:35-48](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts#L35-L48)

> [!WARNING]
> Modifying tokenized path arrays directly without running `replaceGroupMarks` will leave orphan `@index` markers intact, corrupting downstream route compilation in [RegExp Router](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing/regexp-router) and [Trie and Smart Routers](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing/trie-and-smart-routers).

### Execution Walkthroughs

#### Trace Sequences

##### Extraction Trace

1. `basePath` calls `splitRoutingPath`.
2. `splitRoutingPath` calls `extractGroupsFromPath`.
3. `extractGroupsFromPath` matches bracketed expressions and populates the groups array.

```mermaid
sequenceDiagram
    participant Helper as basePath
    participant URLUtils as splitRoutingPath
    participant Extractor as extractGroupsFromPath

    Helper->>URLUtils: splitRoutingPath(rp)
    URLUtils->>Extractor: extractGroupsFromPath(routePath)
    Extractor-->>URLUtils: return { groups, path }
```

Sources: [src/helper/route/index.ts:120-120](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L120-L120), [src/utils/url.ts:16-17](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts#L16-L17), [src/utils/url.ts:23-33](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts#L23-L33)

##### Replacement Trace

1. `basePath` calls `splitRoutingPath`.
2. `splitRoutingPath` calls `splitPath` on the cleaned path string.
3. `splitRoutingPath` calls `replaceGroupMarks` to substitute temporary markers.

```mermaid
sequenceDiagram
    participant Helper as basePath
    participant URLUtils as splitRoutingPath
    participant Replacer as replaceGroupMarks

    Helper->>URLUtils: splitRoutingPath(rp)
    URLUtils->>URLUtils: splitPath(path)
    URLUtils->>Replacer: replaceGroupMarks(paths, groups)
    Replacer-->>URLUtils: return normalized paths array
```

Sources: [src/helper/route/index.ts:120-120](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/helper/route/index.ts#L120-L120), [src/utils/url.ts:16-20](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts#L16-L20), [src/utils/url.ts:35-48](https://github.com/blade47/hono/blob/e50df01453e71b071c3e6136b161b160b9fdf916/src/utils/url.ts#L35-L48)

## Related

- [RegExp Router](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing/regexp-router)
- [Trie and Smart Routers](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing/trie-and-smart-routers)
- [Linear and Pattern Routers](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/routing/linear-and-pattern-routers)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/llms.txt) for all pages in this wiki.
