Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hono x Inertia.js x Cloudflare_Workers

Hono x Inertia.js x Cloudflare_Workers

2026-07-08 Cloudflare Workers Tech Talks in Kyoto #2
https://workers-tech.connpass.com/event/397441/

Avatar for Takafumi ONAKA

Takafumi ONAKA PRO

July 08, 2026

More Decks by Takafumi ONAKA

Other Decks in Technology

Transcript

  1. 自己紹介 • 大仲 能史 a.k.a. id:onk • 株式会社はてな • 芸歴21年

    • サーバサイドが主戦場 ◦ 2006年からRailsを使っています 2
  2. 9

  3. 10

  4. 11

  5. 13

  6. Inertia.js • Build frontend experiences with the backend you love

    ◦ 自認バックエンドのためのフロントエンド環境 • Elevate your application with the modern monolith ◦ 「the modern monolith」 14
  7. 書くのはこれだけ // src/index.tsx import { Hono } from 'hono' import

    { inertia } from '@hono/inertia' import { rootView } from './root-view' const app = new Hono() app.use(inertia({ rootView })) const routes = app.get('/', (c) => c.render('Home', { message: 'Hello from Hono!' }) ) export type AppType = typeof routes export default routes 17
  8. 書くのはこれだけ // src/pages/Home.tsx import { type PageProps } from '@hono/inertia'

    export default function Home({ message }: PageProps<'Home'>) { return ( <main> <h1>{message}</h1> </main> ) } 18
  9. これがこうなる // src/root-view.tsx <body> <div id="app"></div> <script type="application/json" data-page="app"> {

    "component":"Home", "props":{"message":"Hello from Hono!"}, ... } </script> <script type="module" src="/src/client.tsx"></script> </body> 19
  10. ページ間遷移はSPA // src/pages/About.tsx import { Link } from '@inertiajs/react' export

    default function About() { return ( <main> <h1>About</h1> <Link href="/">← Home</Link> </main> ) } 26
  11. 28

  12. UserのCRUD // src/index.tsx app .get('/users', (c) => c.render('Users/Index', { users

    })) .get('/users/new', (c) => c.render('Users/New', {})) .post('/users', async (c) => { const { name } = await c.req.json<{ name: string }>() users.push({ id: nextId++, name }) return c.redirect('/users', 303) }) 29
  13. UserのCRUD // src/pages/Users/New.tsx import { router, useForm } from '@inertiajs/react'

    export default function New() { const { data, setData } = useForm({ name: '' }) function handleSubmit(e: React.FormEvent<HTMLFormElement>) { e.preventDefault() router.post('/users', data) } 30
  14. UserのCRUD // src/pages/Users/New.tsx ... return ( <form onSubmit={handleSubmit}> <input value={data.name}

    onChange={(e) => setData('name', e.target.value)} /> <button type="submit">Create</button> </form> ) } 31
  15. UserのCRUD (validation) // src/index.tsx import * as v from 'valibot'

    function userSchema(exclude?: number) { return v.object({ name: v.pipe( v.string(), v.trim(), v.minLength(1, 'Name is required'), ), }) } 34
  16. UserのCRUD (validation) // src/index.tsx import { vValidator } from '@hono/valibot-validator'

    ... .post('/users', vValidator('json', userSchema(), (result, c) => { if (!result.success) { c.status(422) return c.render('Users/New', { errors: parseErrors(result.issues) }) } }), ... 35
  17. UserのCRUD (validation) // src/pages/Users/New.tsx return ( <form onSubmit={handleSubmit}> <input value={data.name}

    onChange={(e) => setData('name', e.target.value)} /> {errors.name && <p>{errors.name}</p>} <button type="submit">Create</button> </form> ) 36
  18. ユーザのCRUD (validation) • サーバでvalidationを書く ◦ errors propsに詰めて 422 で返す •

    propsでerrorsを受け取る ◦ Formのstateはそこにあり、マージされる ◦ errorsを追加でrenderする 38
  19. Inertia.jsの強み • 色々無くなる ◦ データのfetch。useEffect loading fetch useState を使う場面はかなり減る ▪

    クライアントサイドで「API」を意識することはない ◦ stateを意識することも減る ▪ サーバ (session) が正。紙芝居的な考え方になる ◦ クライアントサイドのRouting。サーバに飛ばす 42
  20. Hono x Inertia.js x Cloudflare Workers • こういうのでいいんだよ • サーバ脳のまま、モダンなフロントエンド体

    験を提供できる ◦ the modern monolith ◦ 認証、ルーティング、SSR、全部いつものやつ。 「ページ」という概念で整理できる 54
  21. Hono x Inertia.js x Cloudflare Workers • propsに渡すだけで型が貫通する ◦ OpenAPI

    Specなんて書かなくても良かったんや ◦ さすがにDBのレコードをそのまま見せるわけにはい かないので、valibotは通す • inertia-hono-jsxでさらに軽量に ◦ バイナリサイズへの影響が減り、Workersで複雑なこ とをやりやすくなる 55
  22. Hono x Inertia.js x Cloudflare Workers • Inertia.jsは自認バックエンドエンジニアにと てもオススメな選択肢 ◦

    フロントエンドはViewであると割り切れるチームに ちょうどいい • 管理画面辺りで使ってみてはどうですか ◦ データ絡むところはだいたいバックエンドエンジニア が作るが、管理画面こそモダンフロントエンドが必要 56