HTML на JSX
Кроме JSON, Hono умеет отдавать HTML-страницы. Писать разметку строками неудобно и опасно, поэтому в Hono встроен JSX — синтаксис, в котором HTML-теги пишутся прямо в коде TypeScript. Это не React: JSX Hono просто превращает разметку в строку HTML на сервере, без кода в браузере.
Настройка
Файлы с JSX должны иметь расширение .tsx. В tsconfig.json проекта уже есть нужные строки, проверьте их:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx"
}
}Вторая строка говорит TypeScript брать JSX из Hono, а не из React. Устанавливать ничего не нужно.
Первая страница
Создайте src/routes/pages.tsx:
// src/routes/pages.tsx
import { Hono } from 'hono'
const pages = new Hono()
pages.get('/', (c) => {
return c.html(<h1>Блог о программировании</h1>)
})
export default pagesПодключите группу в src/index.ts строкой app.route('/', pages) с импортом import pages from './routes/pages.js'. Откройте http://localhost:3000/ — появится заголовок. c.html() принимает JSX и сам ставит заголовок Content-Type: text/html.
Компонент
Компонент — функция, которая возвращает разметку. Её имя пишут с большой буквы и используют как тег:
// src/components/PostCard.tsx
import type { FC } from 'hono/jsx'
type Props = {
title: string
body: string
}
export const PostCard: FC<Props> = ({ title, body }) => {
return (
<article>
<h2>{title}</h2>
<p>{body}</p>
</article>
)
}Данные приходят в компонент через props — объект с атрибутами, указанными при использовании тега. Значения в фигурных скобках экранируются: если в заголовке окажется тег script, он выведется как текст и не выполнится.
Использование компонента и список
Выведите все статьи на странице /posts:
// src/routes/pages.tsx
import { PostCard } from '../components/PostCard.js'
const posts = [
{ id: 1, title: 'Первая статья', body: 'Привет, мир!' },
{ id: 2, title: 'Вторая статья', body: 'Учим Hono.' },
]
pages.get('/posts', (c) => {
return c.html(
<main>
<h1>Статьи</h1>
{posts.map((post) => (
<PostCard title={post.title} body={post.body} />
))}
</main>,
)
})Страница http://localhost:3000/posts покажет заголовок и две карточки статей. Список строится обычным map(). Ключи key, как в React, здесь не нужны: страница собирается один раз на сервере.
Отличия от HTML
| HTML | JSX |
|---|---|
class="post" | class="post" — в Hono можно писать как в HTML |
<input> | <input /> — одиночный тег закрывается |
| текст с данными | выражение в фигурных скобках |
onclick="..." | обработчики событий на сервере не работают |
Частая ошибка
Код с JSX пишут в файле .ts. TypeScript не разбирает разметку в таких файлах и выдаёт множество непонятных ошибок. Переименуйте файл в .tsx, а в импортах по-прежнему указывайте .js: ../components/PostCard.js.