# Context The `Context` object is instantiated for each request and kept until the response is returned. You can put values in it, set headers and a status code you want to return, and access HonoRequest and Response objects. ## req `req` is an instance of HonoRequest. For more details, see [HonoRequest](/docs/api/request). ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/hello', (c) => { const userAgent = c.req.header('User-Agent') // ... // ---cut-start--- return c.text(`Hello, ${userAgent}`) // ---cut-end--- }) ``` ## status() You can set an HTTP status code with `c.status()`. The default is `200`. You don't have to use `c.status()` if the code is `200`. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.post('/posts', (c) => { // Set HTTP status code c.status(201) return c.text('Your post is created!') }) ``` ## header() You can set HTTP Headers for the response. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/', (c) => { // Set headers c.header('X-Message', 'My custom message') return c.text('HellO!') }) ``` ## body() Return an HTTP response. ::: info **Note**: When returning text or HTML, it is recommended to use `c.text()` or `c.html()`. ::: ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/welcome', (c) => { c.header('Content-Type', 'text/plain') // Return the response body return c.body('Thank you for coming') }) ``` You can also write the following. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/welcome', (c) => { return c.body('Thank you for coming', 201, { 'X-Message': 'Hello!', 'Content-Type': 'text/plain', }) }) ``` The response is the same `Response` object as below. ```ts twoslash new Response('Thank you for coming', { status: 201, headers: { 'X-Message': 'Hello!', 'Content-Type': 'text/plain', }, }) ``` ## text() Render text as `Content-Type:text/plain`. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/say', (c) => { return c.text('Hello!') }) ``` ## json() Render JSON as `Content-Type:application/json`. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/api', (c) => { return c.json({ message: 'Hello!' }) }) ``` ## html() Render HTML as `Content-Type:text/html`. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/', (c) => { return c.html('

Hello! Hono!

') }) ``` ## notFound() Return a `Not Found` Response. You can customize it with [`app.notFound()`](/docs/api/hono#not-found). ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/notfound', (c) => { return c.notFound() }) ``` ## redirect() Redirect, default status code is `302`. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/redirect', (c) => { return c.redirect('/') }) app.get('/redirect-permanently', (c) => { return c.redirect('/', 301) }) ``` ## res You can access the [Response] object that will be returned. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- // Response object app.use('/', async (c, next) => { await next() c.res.headers.append('X-Debug', 'Debug message') }) ``` [Response]: https://developer.mozilla.org/en-US/docs/Web/API/Response ## set() / get() Get and set arbitrary key-value pairs, with a lifetime of the current request. This allows passing specific values between middleware or from middleware to route handlers. ```ts twoslash import { Hono } from 'hono' const app = new Hono<{ Variables: { message: string } }>() // ---cut--- 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}"`) }) ``` Pass the `Variables` as Generics to the constructor of `Hono` to make it type-safe. ```ts twoslash import { Hono } from 'hono' // ---cut--- type Variables = { message: string } const app = new Hono<{ Variables: Variables }>() ``` The value of `c.set` / `c.get` are retained only within the same request. They cannot be shared or persisted across different requests. ## var You can also access the value of a variable with `c.var`. ```ts twoslash import type { Context } from 'hono' declare const c: Context // ---cut--- const result = c.var.client.oneMethod() ``` If you want to create the middleware which provides a custom method, write like the following: ```ts twoslash import { Hono } from 'hono' import { createMiddleware } from 'hono/factory' // ---cut--- type Env = { Variables: { echo: (str: string) => string } } const app = new Hono() const echoMiddleware = createMiddleware(async (c, next) => { c.set('echo', (str) => str) await next() }) app.get('/echo', echoMiddleware, (c) => { return c.text(c.var.echo('Hello!')) }) ``` If you want to use the middleware in multiple handlers, you can use `app.use()`. Then, you have to pass the `Env` as Generics to the constructor of `Hono` to make it type-safe. ```ts twoslash import { Hono } from 'hono' import type { MiddlewareHandler } from 'hono/types' declare const echoMiddleware: MiddlewareHandler type Env = { Variables: { echo: (str: string) => string } } // ---cut--- const app = new Hono() app.use(echoMiddleware) app.get('/echo', (c) => { return c.text(c.var.echo('Hello!')) }) ``` ## render() / setRenderer() You can set a layout using `c.setRenderer()` within a custom middleware. ```tsx twoslash /** @jsx jsx */ /** @jsxImportSource hono/jsx */ import { Hono } from 'hono' const app = new Hono() // ---cut--- app.use(async (c, next) => { c.setRenderer((content) => { return c.html(

{content}

) }) await next() }) ``` Then, you can utilize `c.render()` to create responses within this layout. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.get('/', (c) => { return c.render('Hello!') }) ``` The output of which will be: ```html

Hello!

``` Additionally, this feature offers the flexibility to customize arguments. To ensure type safety, types can be defined as: ```ts declare module 'hono' { interface ContextRenderer { ( content: string | Promise, head: { title: string } ): Response | Promise } } ``` Here's an example of how you can use this: ```ts app.use('/pages/*', async (c, next) => { c.setRenderer((content, head) => { return c.html( {head.title}
{head.title}

{content}

) }) await next() }) app.get('/pages/my-favorite', (c) => { return c.render(

Ramen and Sushi

, { title: 'My favorite', }) }) app.get('/pages/my-hobbies', (c) => { return c.render(

Watching baseball

, { title: 'My hobbies', }) }) ``` ## executionCtx You can access Cloudflare Workers' specific [ExecutionContext](https://developers.cloudflare.com/workers/runtime-apis/context/). ```ts twoslash import { Hono } from 'hono' const app = new Hono<{ Bindings: { KV: any } }>() declare const key: string declare const data: string // ---cut--- // ExecutionContext object app.get('/foo', async (c) => { c.executionCtx.waitUntil(c.env.KV.put(key, data)) // ... }) ``` The `ExecutionContext` also has an [`exports`](https://developers.cloudflare.com/workers/runtime-apis/context/#exports) field. To get autocomplete with Wrangler's generated types, you can use module augmentation: ```ts import 'hono' declare module 'hono' { interface ExecutionContext { readonly exports: Cloudflare.Exports } } ``` ## event You can access Cloudflare Workers' specific `FetchEvent`. This was used in "Service Worker" syntax. But, it is not recommended now. ```ts twoslash import { Hono } from 'hono' declare const key: string declare const data: string type KVNamespace = any // ---cut--- // Type definition to make type inference type Bindings = { MY_KV: KVNamespace } const app = new Hono<{ Bindings: Bindings }>() // FetchEvent object (only set when using Service Worker syntax) app.get('/foo', async (c) => { c.event.waitUntil(c.env.MY_KV.put(key, data)) // ... }) ``` ## env In Cloudflare Workers Environment variables, secrets, KV namespaces, D1 database, R2 bucket etc. that are bound to a worker are known as bindings. Regardless of type, bindings are always available as global variables and can be accessed via the context `c.env.BINDING_KEY`. ```ts twoslash import { Hono } from 'hono' type KVNamespace = any // ---cut--- // Type definition to make type inference type Bindings = { MY_KV: KVNamespace } const app = new Hono<{ Bindings: Bindings }>() // Environment object for Cloudflare Workers app.get('/', async (c) => { c.env.MY_KV.get('my-key') // ... }) ``` ## error If the Handler throws an error, the error object is placed in `c.error`. You can access it in your middleware. ```ts twoslash import { Hono } from 'hono' const app = new Hono() // ---cut--- app.use(async (c, next) => { await next() if (c.error) { // do something... } }) ``` ## ContextVariableMap For instance, if you wish to add type definitions to variables when a specific middleware is used, you can extend `ContextVariableMap`. For example: ```ts declare module 'hono' { interface ContextVariableMap { result: string } } ``` You can then utilize this in your middleware: ```ts twoslash import { createMiddleware } from 'hono/factory' // ---cut--- const mw = createMiddleware(async (c, next) => { c.set('result', 'some values') // result is a string await next() }) ``` In a handler, the variable is inferred as the proper type: ```ts twoslash import { Hono } from 'hono' const app = new Hono<{ Variables: { result: string } }>() // ---cut--- app.get('/', (c) => { const val = c.get('result') // val is a string // ... return c.json({ result: val }) }) ```