> ## 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.

# Basic Routing

> Learn how to define routes in Hono using HTTP method handlers

## HTTP Method Handlers

Hono provides method-specific handlers for defining routes. Each handler corresponds to an HTTP method:

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

app.get('/hello', (c) => c.text('GET request'))
app.post('/hello', (c) => c.text('POST request'))
app.put('/hello', (c) => c.text('PUT request'))
app.delete('/hello', (c) => c.text('DELETE request'))
app.patch('/hello', (c) => c.text('PATCH request'))
app.options('/hello', (c) => c.text('OPTIONS request'))
```

The available method handlers are defined in `src/router.ts:17`:

```typescript theme={null}
export const METHODS = ['get', 'post', 'put', 'delete', 'options', 'patch'] as const
```

## Method Chaining

You can chain multiple handlers on the same path:

```typescript theme={null}
app.post('/books').get((c) => {
  return c.text('Get books')
})

// This creates a GET handler for /books
```

## Handlers Without a Path

You can define handlers without specifying a path. The path from the previous call will be used:

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

app.get((c) => {
  return c.text('Hello from root')
})
// This handles GET requests to '/'
```

## All Methods Handler

The `all()` method matches any HTTP method:

```typescript theme={null}
app.all('/api/*', (c) => {
  return c.text('Matches all methods')
})
```

## Custom Methods with `on()`

For custom HTTP methods or multiple methods at once, use `on()`:

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

// Multiple methods
app.on(['GET', 'POST'], '/data', (c) => {
  return c.text(`${c.req.method} request`)
})

// Multiple paths
app.on('GET', ['/hello', '/hi'], (c) => {
  return c.text('Hello')
})
```

The implementation in `src/hono-base.ts:144` shows how `on()` works:

```typescript theme={null}
this.on = (method: string | string[], path: string | string[], ...handlers: H[]) => {
  for (const p of [path].flat()) {
    this.#path = p
    for (const m of [method].flat()) {
      handlers.map((handler) => {
        this.#addRoute(m.toUpperCase(), this.#path, handler)
      })
    }
  }
  return this as any
}
```

## Route Order and Matching

Routes are matched in the order they are defined. However, the specific router implementation determines the exact matching behavior:

<Note>
  The default router uses a smart matching algorithm that prioritizes more specific routes over wildcards.
</Note>

```typescript theme={null}
app.get('/posts/featured', (c) => c.text('Featured posts'))
app.get('/posts/:id', (c) => c.text(`Post ${c.req.param('id')}`))

// GET /posts/featured -> "Featured posts"
// GET /posts/123 -> "Post 123"
```

## Wildcard Routes

Use `*` to match any path segment:

```typescript theme={null}
// Match any path under /api
app.get('/api/*', (c) => {
  return c.text('API endpoint')
})

// Match everything
app.get('*', (c) => {
  return c.text('Catch all')
})
```

From `src/router/reg-exp-router/router.ts:149`, wildcards are handled specially:

```typescript theme={null}
if (path === '/*') {
  path = '*'
}
```

## Pattern Matching

Hono supports various path patterns:

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

// With parameters
app.get('/users/:id', (c) => c.text(`User ${c.req.param('id')}`))

// Optional segments (see next page for details)
app.get('/posts/:id/comments?', (c) => c.text('Post with optional comments'))

// Regex patterns
app.get('/date/:date{[0-9]+}', (c) => {
  return c.text(`Date: ${c.req.param('date')}`)
})
```

## Multiple Handlers

You can register multiple handlers for the same route by calling the method multiple times:

```typescript theme={null}
// First handler (middleware-like)
app.get('/hello', async (c, next) => {
  console.log('Before handler')
  await next()
})

// Second handler (final response)
app.get('/hello', (c) => {
  return c.text('Hello!')
})
```

Alternatively, pass multiple handlers in one call:

```typescript theme={null}
app.get('/hello', 
  async (c, next) => {
    console.log('Middleware')
    await next()
  },
  (c) => c.text('Hello!')
)
```

The implementation in `src/hono-base.ts:130` shows this pattern:

```typescript theme={null}
this[method] = (args1: string | H, ...args: H[]) => {
  if (typeof args1 === 'string') {
    this.#path = args1
  } else {
    this.#addRoute(method, this.#path, args1)
  }
  args.forEach((handler) => {
    this.#addRoute(method, this.#path, handler)
  })
  return this as any
}
```

## Strict Mode

By default, Hono uses strict mode which distinguishes between paths with and without trailing slashes:

```typescript theme={null}
// With strict mode (default)
const app = new Hono({ strict: true })
app.get('/hello', (c) => c.text('Hello'))

// GET /hello -> 200
// GET /hello/ -> 404

// Without strict mode
const app2 = new Hono({ strict: false })
app2.get('/hello', (c) => c.text('Hello'))

// GET /hello -> 200
// GET /hello/ -> 200
```

From `src/hono-base.ts:172`, the `strict` option affects the path matching:

```typescript theme={null}
this.getPath = (strict ?? true) ? (options.getPath ?? getPath) : getPathNoStrict
```
