Overview
Introduction
Hono provides a built-in JSX rendering system that allows developers to build server-side rendered (SSR) web pages and static HTML components using familiar JSX syntax. By combining the jsxRenderer middleware with Hono's Context, you can easily define reusable site layouts, pass down request information to nested components, and output fully rendered HTML responses or readable streams.
Step-by-Step Instructions
- Configure your JSX settings: Ensure your runtime environment or compiler options are configured to use Hono as your JSX import source (for example, setting
"jsxImportSource": "hono/jsx"in your project configuration). - Apply the
jsxRenderermiddleware: ImportjsxRendererfromhono/jsx-rendererand add it as middleware to your Hono application. Define your root layout template inside the middleware callback. - Render content using
c.render(): Inside your route handlers, callc.render()with your page content or child elements. The layout wrapper defined in the middleware will automatically wrap your content.
Key Concepts
- JSX Renderer Middleware (
jsxRenderer): A Hono middleware that sets up a common page wrapper or layout for your routes and attaches a.render()method to the request context. - Request Context Hook (
useRequestContext): A helper function that allows deeply nested JSX components to access the current Hono requestContextwithout manually passing props down the component tree. - Document Type (
docType): A configuration option that automatically prefixes your rendered HTML output with a document type declaration (such as<!DOCTYPE html>). - Streaming Responses (
stream): An option in the renderer that enables chunked transfer encoding, allowing your server to send parts of the HTML document down to the client as they finish rendering.
Examples
The following example demonstrates how to set up server-side JSX rendering with a shared layout and a nested component that retrieves request information:
import { Hono } from 'hono'
import { jsxRenderer, useRequestContext } from 'hono/jsx-renderer'
const app = new Hono()
// 1. Create a component that reads the request context
const RequestUrlBadge = () => {
const c = useRequestContext()
return <span>Current URL: {c.req.url}</span>
}
// 2. Register the jsxRenderer middleware with a global layout
app.use(
'/page/*',
jsxRenderer(({ children }) => {
return (
<html>
<head>
<title>My Hono App</title>
</head>
<body>
<header>
<RequestUrlBadge />
</header>
<main>{children}</main>
</body>
</html>
)
})
)
// 3. Render content inside your routes using c.render()
app.get('/page/about', (c) => {
return c.render(
<div>
<h1>About Us</h1>
<p>Welcome to our server-side rendered Hono application!</p>
</div>
)
})
export default appTips and Warnings
Tip
Use useRequestContext() inside deeply nested components when you need access to request parameters, headers, or environment variables without prop-drilling.
Warning
Do not attempt to use asynchronous components inside renderToString() when utilizing the DOM compatibility server module, as async components are only supported during stream or buffer rendering passes.
Configuration Options
The jsxRenderer middleware accepts the configuration properties detailed in the table below:
| Option | Type | Default | Description |
|---|---|---|---|
docType | boolean | string | true | Adds a DOCTYPE string at the beginning of the HTML output. Set to false to omit. |
stream | boolean | Record<string, string> | false | Enables streaming responses using chunked transfer encoding. Pass a record of custom headers if needed. |