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

# HonoRequest

> Request object for accessing request data

# HonoRequest

The `HonoRequest` class wraps the standard Web API Request object and provides convenient methods for accessing request data. It's available through `c.req` in handlers and middleware.

## Constructor

You typically don't create HonoRequest instances directly. They're created by Hono for each request.

```typescript theme={null}
const req = new HonoRequest(request, path?, matchResult?)
```

## Properties

### raw

The underlying Web API Request object.

```typescript theme={null}
req.raw: Request
```

```typescript theme={null}
app.post('/', async (c) => {
  // Access raw request
  const contentType = c.req.raw.headers.get('content-type')
  return c.text(`Content-Type: ${contentType}`)
})
```

### path

The pathname of the request URL.

```typescript theme={null}
req.path: string
```

```typescript theme={null}
app.get('/about/me', (c) => {
  const pathname = c.req.path // '/about/me'
  return c.text(`Current path: ${pathname}`)
})
```

### url

The full URL of the request.

```typescript theme={null}
req.url: string
```

```typescript theme={null}
app.get('/about/me', (c) => {
  const url = c.req.url // 'http://localhost:8787/about/me'
  return c.text(`URL: ${url}`)
})
```

### method

The HTTP method of the request.

```typescript theme={null}
req.method: string
```

```typescript theme={null}
app.all('*', (c) => {
  const method = c.req.method // 'GET', 'POST', etc.
  return c.text(`Method: ${method}`)
})
```

## Path Parameters

### param

Get path parameters from the route.

```typescript theme={null}
req.param(key?)
```

<ParamField path="key" type="string" optional>
  Parameter name. If omitted, returns all parameters as an object.
</ParamField>

<ResponseField name="return" type="string | Record<string, string> | undefined">
  The parameter value(s)
</ResponseField>

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

// All 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 })
})
```

## Query Parameters

### query

Get a query string parameter.

```typescript theme={null}
req.query(key?)
```

<ParamField path="key" type="string" optional>
  Query parameter name. If omitted, returns all parameters as an object.
</ParamField>

<ResponseField name="return" type="string | Record<string, string> | undefined">
  The query parameter value(s)
</ResponseField>

```typescript theme={null}
// Single query parameter
// GET /search?q=hono
app.get('/search', (c) => {
  const query = c.req.query('q') // 'hono'
  return c.json({ query })
})

// All query parameters
// GET /search?q=hono&limit=10&offset=0
app.get('/search', (c) => {
  const { q, limit, offset } = c.req.query()
  return c.json({ q, limit, offset })
})
```

### queries

Get multiple values for a query parameter (e.g., array values).

```typescript theme={null}
req.queries(key?)
```

<ParamField path="key" type="string" optional>
  Query parameter name. If omitted, returns all parameters as arrays.
</ParamField>

<ResponseField name="return" type="string[] | Record<string, string[]> | undefined">
  The query parameter value(s) as arrays
</ResponseField>

```typescript theme={null}
// Multiple values for same parameter
// GET /search?tags=typescript&tags=javascript&tags=hono
app.get('/search', (c) => {
  const tags = c.req.queries('tags') // ['typescript', 'javascript', 'hono']
  return c.json({ tags })
})

// All parameters as arrays
app.get('/search', (c) => {
  const params = c.req.queries()
  // { tags: ['typescript', 'javascript'], q: ['hono'] }
  return c.json(params)
})
```

## Headers

### header

Get request header value(s).

```typescript theme={null}
req.header(name?)
```

<ParamField path="name" type="string" optional>
  Header name. If omitted, returns all headers as an object.
</ParamField>

<ResponseField name="return" type="string | Record<string, string> | undefined">
  The header value(s)
</ResponseField>

```typescript theme={null}
// Single header
app.get('/', (c) => {
  const userAgent = c.req.header('User-Agent')
  return c.text(`User-Agent: ${userAgent}`)
})

// All headers
app.get('/headers', (c) => {
  const headers = c.req.header()
  return c.json(headers)
})
```

## Request Body

### json

Parse the request body as JSON.

```typescript theme={null}
req.json<T = any>()
```

<ResponseField name="return" type="Promise<T>">
  Parsed JSON object
</ResponseField>

```typescript theme={null}
app.post('/api/users', async (c) => {
  const body = await c.req.json()
  return c.json({ received: body })
})

// With type annotation
type CreateUser = {
  name: string
  email: string
}

app.post('/api/users', async (c) => {
  const body = await c.req.json<CreateUser>()
  // body.name and body.email are typed
  return c.json({ created: body })
})
```

### text

Parse the request body as plain text.

```typescript theme={null}
req.text()
```

<ResponseField name="return" type="Promise<string>">
  Request body as a string
</ResponseField>

```typescript theme={null}
app.post('/webhook', async (c) => {
  const body = await c.req.text()
  console.log('Received:', body)
  return c.text('OK')
})
```

### arrayBuffer

Parse the request body as an ArrayBuffer.

```typescript theme={null}
req.arrayBuffer()
```

<ResponseField name="return" type="Promise<ArrayBuffer>">
  Request body as an ArrayBuffer
</ResponseField>

```typescript theme={null}
app.post('/upload', async (c) => {
  const buffer = await c.req.arrayBuffer()
  // Process binary data
  return c.text(`Received ${buffer.byteLength} bytes`)
})
```

### blob

Parse the request body as a Blob.

```typescript theme={null}
req.blob()
```

<ResponseField name="return" type="Promise<Blob>">
  Request body as a Blob
</ResponseField>

```typescript theme={null}
app.post('/upload', async (c) => {
  const blob = await c.req.blob()
  return c.text(`Received blob of type: ${blob.type}`)
})
```

### formData

Parse the request body as FormData.

```typescript theme={null}
req.formData()
```

<ResponseField name="return" type="Promise<FormData>">
  Request body as FormData
</ResponseField>

```typescript theme={null}
app.post('/submit', async (c) => {
  const formData = await c.req.formData()
  const name = formData.get('name')
  const file = formData.get('file') as File
  return c.json({ name, fileName: file?.name })
})
```

### parseBody

Parse `multipart/form-data` or `application/x-www-form-urlencoded` bodies.

```typescript theme={null}
req.parseBody<T = BodyData>(options?)
```

<ParamField path="options" type="ParseBodyOptions" optional>
  Parsing options

  <Expandable title="properties">
    <ParamField path="all" type="boolean" default="false">
      If true, parse all multiple values as arrays
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="return" type="Promise<T>">
  Parsed body data as an object
</ResponseField>

```typescript theme={null}
app.post('/form', async (c) => {
  const body = await c.req.parseBody()
  // { name: 'John', email: 'john@example.com' }
  return c.json(body)
})

// Handle multiple values
app.post('/tags', async (c) => {
  const body = await c.req.parseBody({ all: true })
  // { tag: ['typescript', 'javascript', 'hono'] }
  return c.json(body)
})

// Handle file uploads
app.post('/upload', async (c) => {
  const body = await c.req.parseBody()
  const file = body.file as File
  return c.text(`Uploaded: ${file.name}`)
})
```

## Validated Data

### valid

Get validated data from validators.

```typescript theme={null}
req.valid(target)
```

<ParamField path="target" type="keyof ValidationTargets" required>
  Validation target: 'json', 'form', 'query', 'param', 'header', or 'cookie'
</ParamField>

<ResponseField name="return" type="T">
  The validated data
</ResponseField>

```typescript theme={null}
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'

const schema = z.object({
  name: z.string(),
  age: z.number()
})

app.post(
  '/users',
  zValidator('json', schema),
  async (c) => {
    const validated = c.req.valid('json')
    // validated.name and validated.age are typed and validated
    return c.json(validated)
  }
)
```

### addValidatedData

Add validated data to the request (used internally by validators).

```typescript theme={null}
req.addValidatedData(target, data)
```

<ParamField path="target" type="keyof ValidationTargets" required>
  Validation target
</ParamField>

<ParamField path="data" type="object" required>
  Validated data to store
</ParamField>

## Deprecated Methods

### matchedRoutes

<Warning>
  Deprecated. Use the `matchedRoutes` helper from `hono/route` instead.
</Warning>

Get matched routes for the current request.

```typescript theme={null}
req.matchedRoutes: RouterRoute[]
```

### routePath

<Warning>
  Deprecated. Use the `routePath` helper from `hono/route` instead.
</Warning>

Get the path of the matched route.

```typescript theme={null}
req.routePath: string
```

## Utility Functions

### cloneRawRequest

Clone a HonoRequest's underlying raw Request object, handling both consumed and unconsumed bodies.

```typescript theme={null}
cloneRawRequest(req)
```

<ParamField path="req" type="HonoRequest" required>
  The HonoRequest to clone
</ParamField>

<ResponseField name="return" type="Promise<Request>">
  A new Request object with the same properties
</ResponseField>

```typescript theme={null}
import { cloneRawRequest } from 'hono/request'

app.post('/forward', async (c) => {
  const body = await c.req.json()
  // Body has been consumed, but we can still clone
  const clonedReq = await cloneRawRequest(c.req)
  // Forward to another service
  return fetch('http://backend.example.com', clonedReq)
})
```

<Note>
  This is particularly useful when you need to:

  * Process the same request body multiple times
  * Pass requests to external services after validation
  * Forward requests after consuming the body
</Note>

## Type Parameters

The HonoRequest class accepts generic type parameters:

<ParamField path="P" type="string" default="'/'">
  Path parameter type for type-safe param access
</ParamField>

<ParamField path="I" type="Input['out']" default="{}">
  Input type for validated data
</ParamField>

```typescript theme={null}
type Params = '/users/:id'

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