> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/honojs/hono/llms.txt
> Use this file to discover all available pages before exploring further.

# Routing

> Routing patterns and configuration in Hono

# Routing

Hono provides a flexible and powerful routing system that supports various path patterns, parameters, and multiple router implementations.

## Route Patterns

### Basic Routes

Define routes using simple string paths.

```typescript theme={null}
app.get('/', (c) => c.text('Home'))
app.get('/about', (c) => c.text('About'))
app.get('/contact', (c) => c.text('Contact'))
```

### Path Parameters

Capture dynamic segments in the URL path.

```typescript theme={null}
// Single parameter
app.get('/users/:id', (c) => {
  const id = c.req.param('id')
  return c.json({ userId: id })
})

// Multiple parameters
app.get('/posts/:postId/comments/:commentId', (c) => {
  const { postId, commentId } = c.req.param()
  return c.json({ postId, commentId })
})

// Optional parameters
app.get('/users/:id?', (c) => {
  const id = c.req.param('id') // string | undefined
  return c.json({ id })
})
```

### Wildcard Routes

Match multiple path segments.

```typescript theme={null}
// Match any path
app.get('*', (c) => c.text('Catch all'))

// Match paths starting with /api/
app.get('/api/*', (c) => c.text('API route'))

// Match with prefix
app.get('/files/*', (c) => {
  const path = c.req.path // e.g., '/files/documents/report.pdf'
  return c.text(`File: ${path}`)
})
```

### Regular Expressions

Use regex patterns in routes.

```typescript theme={null}
// Match numeric IDs only
app.get('/users/:id{[0-9]+}', (c) => {
  const id = c.req.param('id') // guaranteed to be numeric string
  return c.json({ userId: id })
})

// Match specific patterns
app.get('/posts/:slug{[a-z-]+}', (c) => {
  const slug = c.req.param('slug')
  return c.json({ slug })
})
```

### Multiple Paths

Register the same handler for multiple paths using `app.on()`.

```typescript theme={null}
app.on('GET', ['/v1/users', '/v2/users'], (c) => {
  return c.json({ users: [] })
})
```

## Route Methods

### HTTP Methods

Hono supports all standard HTTP methods.

```typescript theme={null}
app.get('/resource', (c) => c.text('GET'))
app.post('/resource', (c) => c.text('POST'))
app.put('/resource', (c) => c.text('PUT'))
app.patch('/resource', (c) => c.text('PATCH'))
app.delete('/resource', (c) => c.text('DELETE'))
app.options('/resource', (c) => c.text('OPTIONS'))
```

### All Methods

Match all HTTP methods for a route.

```typescript theme={null}
app.all('/api/status', (c) => {
  return c.json({ status: 'ok', method: c.req.method })
})
```

### Custom Methods

Handle custom HTTP methods.

```typescript theme={null}
app.on('PURGE', '/cache', (c) => {
  return c.text('Cache purged')
})

app.on(['LINK', 'UNLINK'], '/resource', (c) => {
  return c.text(`Method: ${c.req.method}`)
})
```

## Route Grouping

### Using basePath

Create a Hono instance with a base path prefix.

```typescript theme={null}
const api = new Hono().basePath('/api/v1')

api.get('/users', (c) => c.json({ users: [] }))       // GET /api/v1/users
api.get('/posts', (c) => c.json({ posts: [] }))       // GET /api/v1/posts
api.get('/comments', (c) => c.json({ comments: [] })) // GET /api/v1/comments

const app = new Hono()
app.route('/', api)
```

### Using route

Mount sub-applications to group related routes.

```typescript theme={null}
const app = new Hono()

// User routes
const users = new Hono()
users.get('/', (c) => c.json({ users: [] }))
users.get('/:id', (c) => c.json({ user: {} }))
users.post('/', (c) => c.json({ created: true }))

// Post routes
const posts = new Hono()
posts.get('/', (c) => c.json({ posts: [] }))
posts.get('/:id', (c) => c.json({ post: {} }))
posts.post('/', (c) => c.json({ created: true }))

// Mount sub-apps
app.route('/users', users)
app.route('/posts', posts)

// Routes available:
// GET  /users
// GET  /users/:id
// POST /users
// GET  /posts
// GET  /posts/:id
// POST /posts
```

## Router Configuration

### Router Options

Configure the router when creating a Hono instance.

```typescript theme={null}
import { Hono } from 'hono'
import { RegExpRouter } from 'hono/router/reg-exp-router'
import { TrieRouter } from 'hono/router/trie-router'
import { SmartRouter } from 'hono/router/smart-router'

// Use a specific router
const app = new Hono({ router: new RegExpRouter() })

// Use SmartRouter with custom routers
const app2 = new Hono({
  router: new SmartRouter({
    routers: [new RegExpRouter(), new TrieRouter()]
  })
})
```

### Available Routers

Hono includes several router implementations:

<CardGroup cols={2}>
  <Card title="RegExpRouter" icon="bolt">
    Fast regex-based router. Good for most use cases. Default in SmartRouter.
  </Card>

  <Card title="TrieRouter" icon="tree">
    Trie-based router. Excellent for apps with many routes. Default in SmartRouter.
  </Card>

  <Card title="SmartRouter" icon="brain">
    Combines multiple routers for optimal performance. Default router in Hono.
  </Card>

  <Card title="LinearRouter" icon="list">
    Simple linear search router. Good for simple apps with few routes.
  </Card>

  <Card title="PatternRouter" icon="pattern">
    URLPattern-based router. Uses the web standard URLPattern API.
  </Card>
</CardGroup>

See the [Router API Reference](/api/routers) for detailed information about each router.

### Strict Mode

Control whether trailing slashes matter in route matching.

```typescript theme={null}
// Strict mode enabled (default)
const app = new Hono({ strict: true })
app.get('/about', handler)   // Matches /about only
app.get('/contact/', handler) // Matches /contact/ only

// Strict mode disabled
const app2 = new Hono({ strict: false })
app2.get('/about', handler) // Matches both /about and /about/
```

### Custom Path Function

Customize how paths are extracted from requests.

```typescript theme={null}
const app = new Hono({
  getPath: (req) => {
    // Include host header in routing
    const host = req.headers.get('host')
    const path = new URL(req.url).pathname
    return `/${host}${path}`
  }
})

// Route based on host and path
app.get('/api.example.com/users', handler1)
app.get('/admin.example.com/users', handler2)
```

## Route Priority

### Matching Order

Routes are matched in the order they are registered.

```typescript theme={null}
app.get('/users/me', (c) => c.text('Current user'))
app.get('/users/:id', (c) => c.text('User by ID'))

// GET /users/me → matches first route
// GET /users/123 → matches second route
```

<Warning>
  The order of route registration matters! More specific routes should be registered before generic ones.
</Warning>

### Wildcard Priority

Wildcard routes have the lowest priority.

```typescript theme={null}
app.get('/api/users', (c) => c.text('Users'))
app.get('/api/*', (c) => c.text('API catch-all'))
app.get('*', (c) => c.text('Global catch-all'))

// GET /api/users → first route
// GET /api/posts → second route
// GET /other → third route
```

## Route Metadata

### RouterRoute Interface

Each route is represented by a `RouterRoute` object.

```typescript theme={null}
interface RouterRoute {
  basePath: string
  path: string
  method: string
  handler: H
}
```

### Accessing Routes

Get all registered routes from the app.

```typescript theme={null}
const app = new Hono()
app.get('/users', handler)
app.post('/users', handler)

console.log(app.routes)
// [
//   { basePath: '/', path: '/users', method: 'GET', handler: [Function] },
//   { basePath: '/', path: '/users', method: 'POST', handler: [Function] }
// ]
```

## Route Matching

### Match Results

The router returns match results containing handlers and parameters.

```typescript theme={null}
type Result<T> = 
  | [[T, ParamIndexMap][], ParamStash] 
  | [[T, Params][]]
```

### Parameter Extraction

Parameters are extracted and decoded automatically.

```typescript theme={null}
app.get('/users/:id', (c) => {
  // URL: /users/john%20doe
  const id = c.req.param('id') // 'john doe' (decoded)
  return c.json({ id })
})
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use specific routes before wildcards">
    Register more specific routes before generic wildcard routes to ensure correct matching.

    ```typescript theme={null}
    app.get('/users/me', handler1)  // Specific
    app.get('/users/:id', handler2) // Less specific
    app.get('/users/*', handler3)   // Least specific
    ```
  </Accordion>

  <Accordion title="Group related routes">
    Use `basePath()` or `route()` to organize related routes together.

    ```typescript theme={null}
    const api = new Hono().basePath('/api/v1')
    api.get('/users', handler)
    api.get('/posts', handler)

    app.route('/', api)
    ```
  </Accordion>

  <Accordion title="Use regex patterns for validation">
    Add regex patterns to route parameters to validate input at the routing level.

    ```typescript theme={null}
    app.get('/users/:id{[0-9]+}', handler) // Only numeric IDs
    ```
  </Accordion>

  <Accordion title="Choose the right router">
    For most applications, the default SmartRouter is optimal. Consider specific routers for specialized needs:

    * LinearRouter for very simple apps
    * RegExpRouter for regex-heavy patterns
    * TrieRouter for apps with many routes
  </Accordion>
</AccordionGroup>

## Type Safety

### Typed Routes

Use TypeScript for type-safe routing.

```typescript theme={null}
import { Hono } from 'hono'

type Env = {
  Variables: {
    user: { id: string; name: string }
  }
}

const app = new Hono<Env>()

app.get('/users/:id', (c) => {
  const id = c.req.param('id') // Type-safe string
  const user = c.get('user')   // Type-safe user object
  return c.json(user)
})
```

### Schema Definition

Define API schemas for type-safe client generation.

```typescript theme={null}
import { Hono } from 'hono'
import type { Schema } from 'hono'

type AppSchema = {
  '/api/users': {
    GET: {
      response: { users: User[] }
    }
  }
}

const app = new Hono<{}, AppSchema>()
```
