Closed15

HonoX触ってみる

TigRigTigRig

参考

https://github.com/honojs/honox

https://zenn.dev/yusukebe/articles/724940fa3f2450
https://azukiazusa.dev/blog/full-stack-web-framework-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 }
  )
})

TigRigTigRig
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 (下記)を変更する。

_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>
  )
})
TigRigTigRig

共通的なレイアウトコンポーネントとか適用するなら、 _renderer.tsx に書く。

_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>
  )
})

https://hono.dev/docs/middleware/builtin/jsx-renderer

TigRigTigRig

グローバルCSSは、_renderer.tsx<Style> 内に直接書ける

<Style>
  {css`
    html {
      font-size: 16px;
    }
  `}
</Style>
TigRigTigRig

import fs from "fs/promises";

がコンパイルエラーになる。

npm install @types/node で解決

TigRigTigRig

ルートファイルでデータ取得して表示させる場合

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' })
})
TigRigTigRig

app/route/ 以下に about/[name].tsx を作成すると、 about/:name というパスにマッチするルートファイルとなる。( :name はパスパラメータ)

よく見るやつ。

TigRigTigRig

ルートファイルで 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 表示テストはないっぽい?

このスクラップは5ヶ月前にクローズされました