Hono v3.8.0 is out now! Let's take a look at the new features.
JSX Context API
The new feature for JSX. By using useContext()
, you can share data globally across any level of the Component tree without passing values through props.
import type { FC } from 'hono/jsx'
import { createContext, useContext } from 'hono/jsx'
const themes = {
light: {
color: '#000000',
background: '#eeeeee'
},
dark: {
color: '#ffffff',
background: '#222222'
}
}
const ThemeContext = createContext(themes.light)
const Button: FC = () => {
const theme = useContext(ThemeContext)
return <button style={theme}>Push!</button>
}
const Toolbar: FC = () => {
return (
<div>
<Button />
</div>
)
}
app.get('/', (c) => {
return c.html(
<div>
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
</div>
)
})
Thanks @usualoma!
JSX Renderer Middleware
JSX Renderer Middleware allows you to set up the layout when rendering JSX with the c.render()
function, without the need for using c.setRenderer()
. Additionally, it enables access to instances of Context within components through the use of useRequestContext()
.
import { Hono } from 'hono'
import { jsxRenderer, useRequestContext } from 'hono/jsx-renderer'
const app = new Hono()
const RequestUrlBadge: FC = () => {
const c = useRequestContext()
return <b>{c.req.url}</b>
}
app.get(
'/page/*',
jsxRenderer(({ children }) => {
return (
<html>
<body>
<nav>Menu</nav>
<div>{children}</div>
</body>
</html>
)
})
)
app.get('/page/about', (c) => {
return c.render(
<>
<h1>About me!</h1>
<div>
You are accessing: <RequestUrlBadge />
</div>
</>
)
})
Thanks @usualoma!
Streaming Helper
The streaming Helper provides a method to extend c.stream()
. streamSSE()
allows you to stream Server-Sent Events (SSE) seamlessly.
import { Hono } from 'hono'
import { streamSSE } from 'hono/streaming'
const app = new Hono()
app.get('/sse', async (c) => {
return streamSSE(c, async (stream) => {
while (true) {
const message = `It is ${new Date().toISOString()}`
await stream.writeSSE({ data: message })
await stream.sleep(1000)
}
})
})
Thanks @watany-dev!
Factory Helper
The Factory Helper provides useful functions for creating Hono's components such as Middleware. Sometimes it's difficult to set the proper TypeScript types, but this helper facilitates that.
createMiddleware()
that is added this version will create your custom middleware.
import { Hono } from 'hono'
import { createMiddleware } from 'hono/factory'
const messageMiddleware = createMiddleware(async (c, next) => {
await next()
c.res.headers.set('X-Message', 'Good morning!')
})
Thanks @arunavabasu-03 for helping!
parseBody()
supports multi values
Now, c.req.parseBody()
supports multi values.
If the key is foo[]
, it will be (string | File)[]
.
const body = await c.req.parseBody()
body['foo[]']
And, you can use the all
option.
const body = await c.req.parseBody({ all: true })
body['foo']
Thanks @sor4chi!
Improve path matching in the router
Improved the path matching in the router. Previously, for instance, a Duplicate param name
error would be thrown if there were parameters with the same name, type
, url
, as shown below:
app.get('/:type/:url', (c) => {
return c.text(`type: ${c.req.param('type')}, url: ${c.req.param('url')}`)
})
app.get('/foo/:type/:url', (c) => {
return c.text(`foo type: ${c.req.param('type')}, url: ${c.req.param('url')}`)
})
With this improvement, the error is no longer thrown, and the correct parameter values can be obtained in each handler.
Thanks @usualoma!
All Updates
- feat(helper): streaming-sse by @watany-dev in #1504
- feat:
parseBody()
for multi values' field by @sor4chi in #1528 - feat: rename middleware to createMiddleware by @arunavabasu-03 in #1540
- Introduce "Context" API and "renderer" for JSX. by @usualoma in #1496
- feat(reg-exp-router): Improve capture group support. by @usualoma in #1556
- chore: bump up denoify by @yusukebe in #1570
- feat: one
params
per a handler (optimized for RegExpRouter) by @usualoma in #1566 - test: fix the sleep time for SSE by @yusukebe in #1575
- feat(app):
basePath
option for the constructor, deprecateapp.basePath()
by @yusukebe in #1560 - feat(
package.json
): exportstreaming
helper by @yusukebe in #1578 - fix(streaming): fix SSE format by @yusukebe in #1579
- fix(factory): fixed the comment by @yusukebe in #1581
- feat(deno): export the
factory
helper for Deno by @yusukebe in #1582 - Revert "feat(app):
basePath
option for the constructor, deprecateapp.basePath()
(#1560)" by @yusukebe in #1586 - refactor: refactored
hono-base
by @yusukebe in #1588 - Next by @yusukebe in #1589
New Contributors
- @arunavabasu-03 made their first contribution in #1540
Full Changelog: v3.7.6...v3.8.0