HonoX触ってみる
参考
Starter template
npm create hono@latest -> x-basic 選ぶだけ。簡単。
初期コードでは、query parameter name
拾って表示する設定になっている。
export default createRoute((c) => {
const name = c.req.query('name') ?? 'Hono'
return c.render(
<div class={className}>
<h1>Hello, {name}!</h1>
<Counter />
</div>,
{ title: name }
)
})
export default createRoute((c) => {
const name = c.req.query('name') ?? 'Hono'
return c.render(
<div class={className}>
<h1>Hello, {name}!</h1>
<Counter />
</div>,
{ title: name } // ★ここでページ title 指定している
)
})
app/global.d.ts
に型定義ある。
// ★これ
type Head = {
title?: string
}
declare module 'hono' {
interface Env {
Variables: {}
Bindings: {}
}
interface ContextRenderer {
(content: string | Promise<string>, head?: Head): Response | Promise<Response>
}
}
description とか他のメタデータ設定したい場合、ここと _renderer.tsx
(下記)を変更する。
export default jsxRenderer(({ children, title }) => { // ★こんな感じで title 指定している
return (
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title> // ★こんな感じで title 指定している
<link rel="icon" href="/favicon.ico" />
<Script src="/app/client.ts" async />
<Style />
</head>
<body>{children}</body>
</html>
)
})
Islands Architecture
CSS in JS の補完、ハイライト効くようにする
→ https://marketplace.visualstudio.com/items?itemName=styled-components.vscode-styled-components
コンポーネント内で useRequestContext 使って Context 取れる
honoの Getting Started | Basic とかででてくる app.get('/', (c) =>
の c
と同じもの
cx で class を結合して使用できる
共通的なレイアウトコンポーネントとか適用するなら、 _renderer.tsx
に書く。
export default jsxRenderer(({ children, title }) => {
return (
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title>
<link rel="icon" href="/favicon.ico" />
<Script src="/app/client.ts" async />
<Style />
</head>
<body>
<Layout>{children}</Layout> // ★こんな感じ
</body>
</html>
)
})
グローバルCSSは、_renderer.tsx
の <Style>
内に直接書ける
<Style>
{css`
html {
font-size: 16px;
}
`}
</Style>
ルートファイル(routes/ 以下に作成)にて、 export const POST = createRoute()
すると POST リクエストを受け取れるようになる。
await c.req.parseBody()
で Submit された入力値を受け取ることができる。
createRoute には middleware 渡せる。
Response オブジェクトを返せばそのままレンダリングされる
とのこと。
色々書き方はありそうだが、とりあえずは createRoute(middleware1, middleware2, hander)
使っておけば良さそう。
zod は標準で入っていないので、使うなら npm install する
import fs from "fs/promises";
がコンパイルエラーになる。
→ npm install @types/node
で解決
ルートファイルでデータ取得して表示させる場合
const Page: FC<Props> = ({ articles }) => {
return (
<div>
<h1 class={titleClass}>Articles</h1>
<ul class={cards}>
{articles.map((article) => (
<li class={card}>
<a href={`/articles/${article.id}`}>{article.title}</a>
</li>
))}
</ul>
</div>
)
}
export default createRoute(async (c) => {
// ここでデータ取得
const articles = await getArticles()
return c.render(<Page articles={articles} />, { title: 'Articles' })
})
👇も動く。(どっちがいいかはさておき)
const Page: FC = async () => {
const articles = await getArticles()
return (
<div>
<h1 class={titleClass}>Articles</h1>
<ul class={cards}>
{articles.map((article) => (
<li class={card}>
<a href={`/articles/${article.id}`}>{article.title}</a>
</li>
))}
</ul>
</div>
)
}
export default createRoute((c) => {
return c.render(<Page />, { title: 'Articles' })
})
app/route/ 以下に about/[name].tsx
を作成すると、 about/:name
というパスにマッチするルートファイルとなる。( :name はパスパラメータ)
よく見るやつ。
ルートファイルで c.notFound() すると、 _404.tsx でなく、シンプルな 404 ページに飛んでしまう。
export default createRoute((c) => {
return c.notFound()
})
どう対処すればいいのかまだわかってない。
https://github.com/honojs/honox/blob/main/test-integration/apps.test.ts には、存在しないルート指定での _404.tsx テストはあるが、 notFound 実行時の _404.tsx 表示テストはないっぽい?