Hono v3.11.0 is now available! Let's take a look at the new features.
ErrorBoundary
This release introduces the new JSX component ErrorBoundary
. It allows you to catch errors in child components.
For instance, in the example below, it will display the content specified in fallback
if an error occurs.
import { ErrorBoundary } from 'hono/jsx'
// ...
function SyncComponent() {
throw new Error('Error')
return <div>Hello</div>
}
app.get('/sync', async (c) => {
return c.html(
<html>
<body>
<ErrorBoundary fallback={<div>Out of Service</div>}>
<SyncComponent />
</ErrorBoundary>
</body>
</html>
)
})
ErrorBoundary
can be used with asynchronous components and Suspense
as well.
async function AsyncComponent() {
await new Promise((resolve) => setTimeout(resolve, 2000))
throw new Error('Error')
return <div>Hello</div>
}
app.get('/with-suspense', async (c) => {
return c.html(
<html>
<body>
<ErrorBoundary fallback={<div>Out of Service</div>}>
<Suspense fallback={<div>Loading...</div>}>
<AsyncComponent />
</Suspense>
</ErrorBoundary>
</body>
</html>
)
})
Thanks to @usualoma!
createFactory()
and createHandlers()
The Factory helper now provides createFactory()
, which creates an instance of the Factory class.
import { createFactory } from 'hono/factory'
const factory = createFactory()
createHandlers()
in a Factory class instance assists in defining handlers.
import { createFactory } from 'hono/factory'
import { logger } from 'hono/logger'
// ...
const factory = createFactory<Env>()
const middleware = factory.createMiddleware(async (c, next) => {
c.set('foo', 'bar')
await next()
})
const handlers = factory.createHandlers(logger(), middleware, (c) => {
return c.json(c.var.foo)
})
app.get('/api', ...handlers)
Dev Helper
Dev Helper is now available.
Instead of using app.showRoutes()
, the showRoutes()
function exported from hono/dev
will display the registered routes in your console.
Consider an application like the following:
import { showRoutes } from 'hono/dev'
// ...
const app = new Hono().basePath('/v1')
app.get('/posts', (c) => {
// ...
})
app.get('/posts/:id', (c) => {
// ...
})
app.post('/posts', (c) => {
// ...
})
showRoutes(app)
When this application starts, the routes will be displayed in your console as follows:
GET /v1/posts
GET /v1/posts/:id
POST /v1/posts
Thanks to @usualoma!
app.showRoutes
has been deprecated.
c.json()
supports RPC
c.json()
now supports RPC, meaning you no longer need to use c.jsonT()
for RPC-mode.
c.jsonT()
has been deprecated.
Thanks to @usualoma!
c.req.routePath
You can retrieve the registered path within the handler as shown below:
app.get('/posts/:id', (c) => {
return c.json({ path: c.req.routePath })
})
If you access /posts/123
, it will return /posts/:id
:
{ "path": "/posts/:id" }
Thanks to @usualoma!
Other new features
- feat(adaptor): Enhance AWS Lambda Event Handling and Interface. Thanks to @watany-dev!
- feat(bearerAuth): accept a list of token strings. Thanks to @thanks to @mstibbard!
- feat(types): Support types until 10 handlers. Thanks to @gabrielDonnantuoni!
All Updates
- Introduce
ErrorBoundary
component by @usualoma in #1714 - feat(adaptor): Enhance AWS Lambda Event Handling and Interface by @watany-dev in #1710
- feat(types): Support types until 10 handlers by @gabrielDonnantuoni in #1735
- feat: introduce
createFactory()
andcreateHandlers()
by @yusukebe in #1743 - feat(context): remove
experimental
fromc.render
/c.setRenderer()
by @yusukebe in #1748 - feat/allow
bearerAuth
to accept a list of token strings by @mstibbard in #1749 - Introduce
inspectRoutes()
andshowRoutes()
by @usualoma in #1716 - fix(types): Keep
Env
types with changed routes by @yusukebe in #1757 - refactor(router): remove duplication
MESSAGE_MATCHER_IS_ALREADY_BUILT
by @yusukebe in #1763 - Ensure that calls to
c.json()
have a type equivalent toc.jsonT()
by @usualoma in #1728 - feat(request): Introduce
matchedRoutes
androutePath
forHonoRequest
by @usualoma in #1744 - feat(jsx): mark
ErrorBoundary
asexperimental
by @yusukebe in #1771 - fix(factory): Filter undefined in
createHandlers
by @yusukebe in #1772 - refactor: use
#
for private properties by @yusukebe in #1762 - Next by @yusukebe in #1774
New Contributors
- @gabrielDonnantuoni made their first contribution in #1735
- @mstibbard made their first contribution in #1749
Full Changelog: v3.10.5...v3.11.0