v4.7.0

honojs/honov4.7.0Feb 7, 2025by yusukebe

AI Summary

Hono v4.7.0 introduces a Proxy Helper for proper reverse proxy handling (solving Accept-Encoding and Transfer-Encoding header issues), a Language Middleware for i18n with detection from query params/cookies/headers/URL path, and JWK Auth Middleware for JSON Web Key authentication. Additionally, Standard Schema Validator provides a unified interface for Zod, Valibot, and ArkType validators.

Key Highlights

  • Proxy Helper - solves header issues when using Hono as a reverse proxy by properly handling Accept-Encoding and Transfer-Encoding
  • Language Middleware - provides i18n functions with language detection from query params, cookies, Accept-Language header, or URL path
  • JWK Auth Middleware - authenticates requests using JSON Web Keys fetched from a specified JWKS URL
  • Standard Schema Validator - unified validator interface supporting Zod, Valibot, and ArkType with the same code
  • Logger now includes query parameters in output

New Features

  • Proxy Helper - handles reverse proxy requests with proper header management
  • Language Middleware - i18n support with languageDetector function
  • JWK Auth Middleware - JWT authentication using JSON Web Keys
  • Standard Schema Validator - unified validation interface for multiple validator libraries
  • Logger includes query params in output
  • Context buffer returns support
  • ETag allows custom hashing methods
  • Router supports greedy matches with subsequent static components
  • Factory allows HonoOptions<E> configuration

Full Release Notes

# Release Notes

Hono v4.7.0 is now available!

This release introduces one helper and two middleware.

- Proxy Helper
- Language Middleware
- JWK Auth Middleware

Plus, Standard Schema Validator has been born.

Let's look at each of these.

## Proxy Helper

We sometimes use the Hono application as a reverse proxy. In that case, it accesses the backend using `fetch`. However, it sends an unintended headers.

```ts
app.all('/proxy/:path', (c) => {
  // Send unintended header values to the origin server
  return fetch(`http://${originServer}/${c.req.param('path')}`)
})
```

For example, `fetch` may send `Accept-Encoding`, causing the origin server to return a compressed response. Some runtimes automatically decode it, leading to a `Content-Length` mismatch and potential client-side errors.

Also, you should probably remove some of the headers sent from the origin server, such as `Transfer-Encoding`.

[Proxy Helper](https://hono.dev/docs/helpers/proxy) will send requests to the origin and handle responses properly. The above headers problem is solved simply by writing as follows.

```ts
import { Hono } from 'hono'
import { proxy } from 'hono/proxy'

app.get('/proxy/:path', (c) => {
  return proxy(`http://${originServer}/${c.req.param('path')}`)
})
```

You can also use it in more complex ways.

```ts
app.get('/proxy/:path', async (c) => {
  const res = await proxy(
    `http://${originServer}/${c.req.param('path')}`,
    {
      headers: {
        ...c.req.header(),
        'X-Forwarded-For': '127.0.0.1',
        'X-Forwarded-Host': c.req.header('host'),
        Authorization: undefined,
      },
    }
  )
  res.headers.delete('Set-Cookie')
  return res
})
```

Thanks @usualoma!

## Language Middleware

[Language Middleware](https://hono.dev/docs/middleware/builtin/language) provides 18n functions to Hono applications. By using the `languageDetector` function, you can get the language that your application should support.

```ts
import { Hono } from 'hono'
import { languageDetector } from 'hono/language'

const app = new Hono()

app.use(
  languageDetector({
    supportedLanguages: ['en', 'ar', 'ja'], // Must include fallback
    fallbackLanguage: 'en', // Required
  })
)

app.get('/', (c) => {
  const lang = c.get('language')
  return c.text(`Hello! Your language is ${lang}`)
})
```

You can get the target language in various ways, not just by using `Accept-Language`.

- Query parameters
- Cookies
- `Accept-Language` header
- URL path

Thanks @lord007tn!

## JWK Auth Middleware

Finally, middleware that supports JWK (JSON Web Key) has landed. Using [JWK Auth Middleware](https://hono.dev/docs/middleware/builtin/jwk), you can authenticate by verifying JWK tokens. It can access keys fetched from the specified URL.

```ts
import { Hono } from 'hono'
import { jwk } from 'hono/jwk'

app.use(
  '/auth/*',
  jwk({
    jwks_uri: `https://${backendServer}/.well-known/jwks.json`,
  })
)

app.get('/auth/page', (c) => {
  return c.text('You are authorized')
})
```

Thanks @Beyondo!

## Standard Schema Validator

[Standard Schema](https://standardschema.dev/) provides a common interface for TypeScript validator libraries. [Standard Schema Validator](https://github.com/honojs/middleware/tree/main/packages/standard-validator) is a validator that uses it. This means that Standard Schema Validator can handle several validators, such as Zod, Valibot, and ArkType, with the same interface.

The code below really works!

```ts
import { Hono } from 'hono'
import { sValidator } from '@hono/standard-validator'
import { type } from 'arktype'
import * as v from 'valibot'
import { z } from 'zod'

const aSchema = type({
  agent: 'string',
})

const vSchema = v.object({
  slag: v.string(),
})

const zSchema = z.object({
  name: z.string(),
})

const app = new Hono()

app.get(
  '/:slag',
  sValidator('header', aSchema),
  sValidator('param', vSchema),
  sValidator('query', zSchema),
  (c) => {
    const headerValue = c.req.valid('header')
    const paramValue = c.req.valid('param')
    const queryValue = c.req.valid('query')
    return c.json({ headerValue, paramValue, queryValue })
  }
)

const res = await app.request('/foo?name=foo', {
  headers: {
    agent: 'foo',
  },
})

console.log(await res.json())
```

Thanks @muningis!

## New features

- feat(helper/proxy): introduce proxy helper https://github.com/honojs/hono/pull/3589
- feat(logger): include query params https://github.com/honojs/hono/pull/3702
- feat: add language detector middleware and helpers https://github.com/honojs/hono/pull/3787
- feat(hono/context): add buffer returns https://github.com/honojs/hono/pull/3813
- feat(hono/jwk): JWK Auth Middleware https://github.com/honojs/hono/pull/3826
- feat(etag): allow for custom hashing methods to be used to etag https://github.com/honojs/hono/pull/3832
- feat(router): support greedy matches with subsequent static components https://github.com/honojs/hono/pull/3888

## All changes

- docs(CONTRIBUTING): remove text about `yarn` by @EdamAme-x in https://github.com/honojs/hono/pull/3878
- refactor(request): `toLowerCase()` is unnecessary for `req.header()` by @yusukebe in https://github.com/honojs/hono/pull/3880
- fix(helper/adapter): correct `env` type by @yusukebe in https://github.com/honojs/hono/pull/3885
- chore(test): update to vitest 3 by @yasuaki640 in https://github.com/honojs/hono/pull/3861
- fix(router/trie-router): fix label with trailing wildcard pattern by @usualoma in https://github.com/honojs/hono/pull/3892
- feat(helper/proxy): introduce proxy helper by @usualoma in https://github.com/honojs/hono/pull/3589
- feat(logger): include query params by @ryuapp in https://github.com/honojs/hono/pull/3702
- feat(factory): Allow HonoOptions<E> with factory by @miyaji255 in https://github.com/honojs/hono/pull/3786
- feat: add language detector middleware and helpers by @lord007tn in https://github.com/honojs/hono/pull/3787
- feat(hono/context): add buffer returns by @askorupskyy in https://github.com/honojs/hono/pull/3813
- feat(hono/jwk): JWK Auth Middleware by @Beyondo in https://github.com/honojs/hono/pull/3826
- feat(etag): allow for custom hashing methods to be used to etag by @EdamAme-x in https://github.com/honojs/hono/pull/3832
- feat(router): support greedy matches with subsequent static components. by @usualoma in https://github.com/honojs/hono/pull/3888
- fix(client): correct inferring empty object from`c.json({})` by @yusukebe in https://github.com/honojs/hono/pull/3873
- Next by @yusukebe in https://github.com/honojs/hono/pull/3896
- chore(runtime-tests): add `deno.lock` by @yusukebe in https://github.com/honojs/hono/pull/3897

## New Contributors

- @lord007tn made their first contribution in https://github.com/honojs/hono/pull/3787

**Full Changelog**: https://github.com/honojs/hono/compare/v4.6.20...v4.7.0