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

# cache

> API reference for the Cache middleware

## Import

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

## Usage

```typescript theme={null}
app.get(
  '*',
  cache({
    cacheName: 'my-app',
    cacheControl: 'max-age=3600',
  })
)
```

## Options

The `cache` middleware accepts an options object:

<ParamField path="cacheName" type="string | ((c: Context) => string | Promise<string>)" required>
  The name of the cache. Can be used to store multiple caches with different identifiers. Can be a static string or a function that returns the cache name dynamically.
</ParamField>

<ParamField path="wait" type="boolean" default={false}>
  Whether Hono should wait for the Promise of the `cache.put` function to resolve before continuing with the request. Required to be `true` for the Deno environment.
</ParamField>

<ParamField path="cacheControl" type="string">
  A string of directives for the `Cache-Control` header. Will be appended to existing directives.
</ParamField>

<ParamField path="vary" type="string | string[]">
  Sets the `Vary` header in the response. If the original response already contains a `Vary` header, the values are merged, removing duplicates.
</ParamField>

<ParamField path="keyGenerator" type="(c: Context) => string | Promise<string>">
  Generates keys for every request in the `cacheName` store. Useful for caching data based on request parameters or context parameters. Defaults to using the request URL.
</ParamField>

<ParamField path="cacheableStatusCodes" type="number[]" default={[200]}>
  An array of status codes that can be cached. Only responses with these status codes will be stored in the cache.
</ParamField>

## Signature

```typescript theme={null}
cache(options: {
  cacheName: string | ((c: Context) => Promise<string> | string)
  wait?: boolean
  cacheControl?: string
  vary?: string | string[]
  keyGenerator?: (c: Context) => Promise<string> | string
  cacheableStatusCodes?: StatusCode[]
}): MiddlewareHandler
```

## Examples

### Basic caching

```typescript theme={null}
app.get('*', cache({
  cacheName: 'my-app',
  cacheControl: 'max-age=3600',
}))
```

### Custom cache key based on query params

```typescript theme={null}
app.get('/api/posts', cache({
  cacheName: 'posts-cache',
  keyGenerator: (c) => {
    const url = new URL(c.req.url)
    return url.pathname + url.search
  },
  cacheControl: 'max-age=600',
}))
```

### Dynamic cache name

```typescript theme={null}
app.get('/api/:version/*', cache({
  cacheName: (c) => {
    const version = c.req.param('version')
    return `api-cache-${version}`
  },
  cacheControl: 'max-age=3600',
}))
```

### Vary header for conditional caching

```typescript theme={null}
app.get('/api/content', cache({
  cacheName: 'content-cache',
  vary: ['Accept-Language', 'Accept-Encoding'],
  cacheControl: 'max-age=3600',
}))
```

### Cache multiple status codes

```typescript theme={null}
app.get('*', cache({
  cacheName: 'my-app',
  cacheableStatusCodes: [200, 301, 404],
  cacheControl: 'max-age=3600',
}))
```

### For Deno (with wait)

```typescript theme={null}
app.get('*', cache({
  cacheName: 'my-app',
  wait: true,
  cacheControl: 'max-age=3600',
}))
```

## Behavior

* Returns cached response immediately if available
* Only caches responses with status codes in `cacheableStatusCodes` (default: 200)
* Skips caching if response has:
  * `Vary: *` header
  * `Cache-Control` with `private`, `no-store`, or `no-cache`
  * `Set-Cookie` header
* Appends specified `Cache-Control` directives without duplicating existing ones
* Merges `Vary` headers and removes duplicates
* Uses Cache API (`caches.open()`) which must be available in the runtime
* If Cache API is not available, middleware becomes a no-op
