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.
const req = new HonoRequest ( request , path ? , matchResult ? )
Properties
raw
The underlying Web API Request object.
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.
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.
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.
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.
Parameter name. If omitted, returns all parameters as an object.
return
string | Record<string, string> | undefined
The parameter value(s)
// 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.
Query parameter name. If omitted, returns all parameters as an object.
return
string | Record<string, string> | undefined
The query parameter value(s)
// 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).
Query parameter name. If omitted, returns all parameters as arrays.
return
string[] | Record<string, string[]> | undefined
The query parameter value(s) as arrays
// 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 )
})
Get request header value(s).
Header name. If omitted, returns all headers as an object.
return
string | Record<string, string> | undefined
The header value(s)
// 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.
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.
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.
Request body as an ArrayBuffer
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.
app . post ( '/upload' , async ( c ) => {
const blob = await c . req . blob ()
return c . text ( `Received blob of type: ${ blob . type } ` )
})
Parse the request body as FormData.
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.
req . parseBody < T = BodyData > ( options ? )
Parsing options If true, parse all multiple values as arrays
Parsed body data as an object
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.
target
keyof ValidationTargets
required
Validation target: ‘json’, ‘form’, ‘query’, ‘param’, ‘header’, or ‘cookie’
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).
req . addValidatedData ( target , data )
target
keyof ValidationTargets
required
Validation target
Deprecated Methods
matchedRoutes
Deprecated. Use the matchedRoutes helper from hono/route instead.
Get matched routes for the current request.
req . matchedRoutes : RouterRoute []
routePath
Deprecated. Use the routePath helper from hono/route instead.
Get the path of the matched route.
Utility Functions
cloneRawRequest
Clone a HonoRequest’s underlying raw Request object, handling both consumed and unconsumed bodies.
A new Request object with the same properties
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 )
})
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
Type Parameters
The HonoRequest class accepts generic type parameters:
Path parameter type for type-safe param access
Input type for validated data
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 })
})