Skip to Content
core-conceptsContext Request

Last Updated: 3/11/2026


Context & Request

The Context object (c) is created for each request and provides methods to handle requests and build responses.

Request Object (c.req)

c.req is a HonoRequest instance that provides methods to access request data.

Headers

app.get('/hello', (c) => { const userAgent = c.req.header('User-Agent') return c.text(`Your UA: ${userAgent}`) })

Path Parameters

app.get('/user/:name', (c) => { const name = c.req.param('name') return c.text(`Hello, ${name}!`) }) // Get all parameters app.get('/posts/:id/comment/:comment_id', (c) => { const { id, comment_id } = c.req.param() return c.json({ id, comment_id }) })

Query Parameters

app.get('/search', (c) => { const query = c.req.query('q') const page = c.req.query('page') || '1' return c.json({ query, page }) })

Request Body

// JSON body app.post('/api/data', async (c) => { const body = await c.req.json() return c.json({ received: body }) }) // Form data app.post('/submit', async (c) => { const body = await c.req.parseBody() return c.json({ received: body }) }) // Text body app.post('/text', async (c) => { const text = await c.req.text() return c.text(`You sent: ${text}`) })

Response Methods

Text Response

Return plain text with Content-Type: text/plain:

app.get('/say', (c) => { return c.text('Hello!') })

JSON Response

Return JSON with Content-Type: application/json:

app.get('/api', (c) => { return c.json({ message: 'Hello!' }) })

HTML Response

Return HTML with Content-Type: text/html:

app.get('/', (c) => { return c.html('<h1>Hello! Hono!</h1>') })

Raw Body

Return a raw response body:

app.get('/welcome', (c) => { return c.body('Thank you for coming') }) // With status and headers app.get('/welcome', (c) => { return c.body('Thank you', 201, { 'X-Message': 'Hello!', 'Content-Type': 'text/plain', }) })

Setting Status and Headers

Status Code

app.post('/posts', (c) => { c.status(201) return c.text('Your post is created!') })

Headers

app.get('/', (c) => { c.header('X-Message', 'My custom message') c.header('X-Response-Time', '42ms') return c.text('Hello!') })

Redirects

Redirect to another URL (default status: 302):

app.get('/redirect', (c) => { return c.redirect('/') }) app.get('/redirect-permanently', (c) => { return c.redirect('/', 301) })

Not Found

Return a 404 response:

app.get('/notfound', (c) => { return c.notFound() })

Variables (c.set / c.get)

Pass values between middleware and handlers:

type Variables = { message: string } const app = new Hono<{ Variables: Variables }>() app.use(async (c, next) => { c.set('message', 'Hono is cool!!') await next() }) app.get('/', (c) => { const message = c.get('message') return c.text(`The message is "${message}"`) })

Access variables with c.var:

app.get('/', (c) => { const message = c.var.message return c.text(message) })

Rendering (c.setRenderer / c.render)

Set a layout in middleware:

app.use(async (c, next) => { c.setRenderer((content) => { return c.html( <html> <body> <p>{content}</p> </body> </html> ) }) await next() })

Render content using the layout:

app.get('/', (c) => { return c.render('Hello!') })

Platform-Specific Features

Cloudflare Workers

Access bindings via c.env:

type Bindings = { MY_KV: KVNamespace USERNAME: string } const app = new Hono<{ Bindings: Bindings }>() app.get('/', async (c) => { const value = await c.env.MY_KV.get('my-key') return c.json({ value }) })

Access ExecutionContext:

app.get('/foo', async (c) => { c.executionCtx.waitUntil( c.env.MY_KV.put('key', 'value') ) return c.text('Done') })

Node.js

Access raw Node.js APIs:

import { serve, type HttpBindings } from '@hono/node-server' type Bindings = HttpBindings const app = new Hono<{ Bindings: Bindings }>() app.get('/', (c) => { return c.json({ remoteAddress: c.env.incoming.socket.remoteAddress, }) })

Error Handling

Access errors in middleware:

app.use(async (c, next) => { await next() if (c.error) { console.error('Error occurred:', c.error) } })

Next Steps

Learn about Middleware to add functionality across your routes.