v3.6.0
Hono v3.6.0 is now available! Let's take a look at the new features.
Introduce c.render()
We introduce c.render()
and c.setRenderer()
functions.
These functions enhance Hono's response handling, allowing for more flexible and modular response structures, especially useful for defining common parts of responses, like HTML layouts.
You can set a layout using c.setRenderer()
within a custom middleware, as shown below:
app.use('*', async (c, next) => {
c.setRenderer((content) => {
return c.html(
<html>
<body>
<p>{content}</p>
</body>
</html>
)
})
await next()
})
Then, you can utilize c.render()
to create responses within this layout:
app.get('/', (c) => {
return c.render('Hello!')
})
The output of which will be:
<html><body><p>Hello!</p></body></html>
Additionally, this feature offers the flexibility to customize arguments. To ensure type safety, types can be defined as:
declare module 'hono' {
interface ContextRenderer {
(content: string, head: { title: string }): Response
}
}
Here's an example of how you can use this:
app.use('/pages/*', async (c, next) => {
c.setRenderer((content, head) => {
return c.html(
<html>
<head>
<title>{head.title}</title>
</head>
<body>
<header>{head.title}</header>
<p>{content}</p>
</body>
</html>
)
})
await next()
})
app.get('/pages/my-favorite', (c) => {
return c.render(<p>Ramen and Sushi</p>, {
title: 'My favorite',
})
})
app.get('/pages/my-hobbies', (c) => {
return c.render(<p>Watching baseball</p>, {
title: 'My hobbies',
})
})
Using c.render()
with JSX and html middleware, you can create HTML pages more easily!
Introduce c.var
The next feature we're introducing is c.var
.
Before this release, to access the actual value of a variable, you had to use c.get()
:
const client = c.get('client')
Now, with c.var
, a more intuitive syntax is available:
const result = c.var.client.oneMethod()
For instance, you can set an instance of the client for accessing an API with a middleware and then retrieve it using c.var.client
:
const app = new Hono<{
Variables: {
client: Client
}
}>()
app.use('*', async (c, next) => {
c.set('client', new ApiClient())
await next()
})
app.get('/', (c) => {
const books = c.var.client.getBooks()
//...
})
FC
for JSX
The type FC
is exported from hono/jsx
. You can use it to specify types for your function components.
import type { FC } from 'hono/jsx'
const Layout: FC<{ title: string }> = (props) => {
return (
<html>
<head>
<title>{props.title}</title>
</head>
<body>{props.children}</body>
</html>
)
}
const Top = (
<Layout title='Home page'>
<h1>Hono</h1>
<p>Hono is great</p>
</Layout>
)
$url()
in Hono Client
You can get a URL
object for accessing the the endpoint by using $url()
.
const route = app.get('/api/foo/bar', (c) => c.jsonT({ foo: 'bar' }))
const client = hc<typeof route>('http://localhost:8787/')
const url = client.api.foo.bar.$url()
console.log(url.pathname) // `/api/foo/bar`
Thanks @renzor-fist !
Factory helper
Now, Hono offers a middleware
factory method to create a middleware handler.
import { middleware } from 'hono/factory'
const mw = (message: string) =>
middleware(async (c, next) => {
await next()
c.header('X-Message', message)
})
By defining your middleware with middleware
, the appropriate types will be added.
Vite dev-server for Hono
Now, we introduce a new Vite Plugin to enhance developing your Hono application.
@hono/vite-dev-server
is a Vite Plugin that provides a custom dev-server for fetch
-based web applications like those using Hono.
You can develop your application with Vite. It's fast.
Features
- Support any
fetch
-based applications. - Hono applications run on.
- Fast by Vite.
- HMR.
- Supporting Cloudflare Bindings.
- Also runs on Bun.
Demo
Screen.Recording.2023-09-07.at.15.05.25.mov
Usage
Installation
You can install vite
and @hono/vite-dev-server
via npm.
npm i -D vite @hono/vite-dev-server
Or you can install them with Bun.
bun add vite @hono/vite-dev-server
Settings
Add "type": "module"
to your package.json
. Then, create vite.config.ts
and edit it.
import { defineConfig } from 'vite'
import devServer from '@hono/vite-dev-server'
export default defineConfig({
plugins: [
devServer({
entry: 'src/index.ts', // The file path of your application.
}),
],
})
Development
Just run vite
.
npm exec vite
Or
bunx --bun vite
See more details
Visit the GitHub project: https://github.com/honojs/vite-plugins/tree/main/packages/dev-server
Deprecate some properties in HonoRequest
These properties in the HonoRequest
have been deprecated.
headers()
body()
bodyUsed()
integrity()
keepalive()
referrer()
signal()
For instance, if you want to use headers
, please use c.req.raw.headers()
.
Replaced Jest with Vitest
This might not be a new feature, but it's a significant change.
We've switched the test framework used in Hono's core project from Jest to Vitest! It's fast!
Thanks @ThatOneBro for the great work!
All Updates
- Add $url method to hono client to extract an endpoint's url by @renzor-fist in #1384
- feat(context): add
status
toTypedResponse
by @ThatOneBro in #1403 - feat(context): introduce
c.render()
by @yusukebe in #1397 - feat(req): deprecate
c.req.headers
(notc.req.header
) and others by @yusukebe in #1410 - feat(vercel): pass
RequestContext
by @yusukebe in #1421 - test(vitest): replace
jest
withvitest
by @ThatOneBro in #1404 - test: ignore
sandbox
dir by @yusukebe in #1424 - ci: add
--no-warnings
option formain
by @yusukebe in #1425 - fix(types): fix
MergeSchemaPath
correct by @yusukebe in #1426 - test:
tsc
beforevitest
by @yusukebe in #1427 - fix(client): remove async from
$url()
by @yusukebe in #1430 - cookie parsing improvements by @jkeys089 in #1428
- feat(context): introduce
c.var
by @yusukebe in #1406 - feat(jsx): export
FC
by @yusukebe in #1420 - feat(helper): introduce
factory
helper by @yusukebe in #1434 - Next by @yusukebe in #1436
New Contributors
- @renzor-fist made their first contribution in #1384
Full Changelog: v3.5.8...v3.6.0