TanStack StartでSuspenseのfallbackが本番環境で表示されない問題の修正

に公開

症状

TanStack Startで useSuspenseQuery を使ったページを実装していたところ、開発環境では問題なく fallback が表示されるのに、本番環境ではデータ取得が終わるまでページが表示されないという問題に遭遇しました。

同様の問題で困っている方の参考になれば幸いです。

原因

今回の問題は、Nginxのレスポンスバッファリングが原因でした。

以下の項目をNginxの設定に追加することで、この問題は解決しました。

location /hoge/ {
  proxy_buffering off;                      # レスポンスバッファリングを無効化
  proxy_http_version 1.1;                   # チャンク転送にHTTP/1.1が必要
  add_header X-Accel-Buffering "no" always; # レスポンスヘッダーでもバッファ無効を指示
  # その他の設定...
}

該当箇所のコード例

今回はコード側には原因はありませんでしたが、問題が発生したページの処理例を載せておきます。

// /routes/hoge/$id/index.tsx(例)
export const Route = createFileRoute('/hoge/$id/')({
  loader: ({ params: { id }, context }) => {
    // データのプリフェッチを開始
    context.queryClient.prefetchQuery(hogeQueryOptions({ id }));
  },
  pendingComponent: FallbackComponent, // fallback用のコンポーネント
  component: HogePage,
});

function HogePage() {
  const { id } = Route.useParams();
  const { data } = useSuspenseQuery(hogeQueryOptions({ id }));

余談 - Tanstackが超便利

上記のコード例を見てもらっても分かる通り、TanStack Start x Tanstack Query でデータ取得の処理が驚くほど簡単に実装できました。

Server Functions を使えば、DBの操作なども可能です。

サーバーコンポーネントに取得処理を集めるために、propsのバケツリレーになりがちだったNext.jsに嫌気がさしていたので、これには凄い感動しました。
(設計が悪いと言われれば、それはそうなんですが...)

現在はまだRC版なので、商用利用にはもう少し様子を見た方が良さそうですが、趣味レベルのプロダクトには十分使えそうな印象でした。
(この記事の問題が唯一つまづいたポイントです)

機会があればぜひ試してみてください!

Discussion