🚢

React Router SPA+HonoをCloudflare Workersで公開する

に公開

React RouterはSPAとし、APIにHonoを使い、Cloudflare Workersで公開できるサンプルを作った。

コードは以下にある。

https://github.com/ofk/example-react-router-hono

React Router SPAを作成

公式サンプルはHono+ViteReact Router SSRであり、ここから改造するよりはこれを参考にして、React Router SPAにCloudflareの設定をする方が簡単だと判断した。

React Router SPAの部分は別記事で作成したものをそのまま持ってきた。

https://zenn.dev/ofk/articles/562098fdab1888#react-routerを設定する

hono-react-router-adapterを導入

https://github.com/yusukebe/hono-react-router-adapter

どう連携するのかREADMEを読んだ段階ではわからなかったが、ちょっと試した結果、

  • 開発環境は、React Routerが動いているところにviteプラグインの追加でHonoが動く
  • 本番環境は、wranglerにReact Router serverとHonoを混ぜたサーバーを定義する

と理解した。

開発環境の設定

hono-react-router-adapterの使い方通りにserverAdapterを追加する。これによってnpm run devで起動する開発サーバーからHonoも見えるようになる。

https://github.com/ofk/react-router-hono/commit/84979c5eec02a8badc0ad57056251f8422086aea

本番環境のデプロイ設定

まず、npm i -D wrangler @hono/vite-dev-serverをする(おそらくHonoに慣れているユーザーには自明すぎるため、hono-react-router-adapterのREADMEには書かれていない)。

hono-react-router-adapterのCloudflare Workersの手順に従って、vite.config.tsadapterを追加をする。追加することでCloudflare仕様の環境変数定義.dev.varsが利用できる。

worker.ts作成しない。React RouterはSPAモードであり、build/server以下にコードを生成しないためだ。サーバーはHonoを直接指定することになる(後述)。

最後にwrangler.jsoncを作成する。公式はtoml推しっぽく見えるが、npm create cloudflareで確認したHonoやReact Routerのサンプルはjsoncであったため、jsoncを採用した。

wrangler.jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "react-router-hono",
  "compatibility_date": "2025-04-04",
  "main": "./server/index.ts",
  "assets": {
    "directory": "./build/client/",
    "not_found_handling": "single-page-application",
  },
}

重要なのは以下の三点。

  • mainの起動するサーバーにHonoのパスを指定する
  • assetsdirectoryにReact Routerのclient生成先のパスを指定する
  • assetsnot_found_handlingをindex.htmlがfallbackされるSPA仕様にする

これでnpm run build && wrangler deployでデプロイできる。Cloudflareのサンプルにあるwrangler devを使うとローカルでも動作を確認できる。

あとがき

公式にあるサンプルは(多分)全てSSRが有効なため作った。SPAを置きたいというのはレアケースなのかもしれない。

Discussion