Nuxt 3とGemini APIを組み合わせて、Vercel Edge Runtime上でAIチャット機能を実装しようとしたところ、ストリーミングレスポンスの処理でハマったので備忘録として残します。
この記事でわかること
- Vercel Edge環境でReadableStreamエラーが出る原因
- Nuxt 3のAPIルートにおけるランタイム設定の変更方法
- Gemini API(Google AI SDK)を正常に動作させるための解決策
[現象] generateContentStream実行時にエラーが発生
Nuxt 3の server/api/chat.ts 内でGemini APIのストリーミング機能を呼び出すと、実行時に以下のエラーがスローされます。
TypeError: response.body.getReader is not a function at GoogleGenerativeAI.generateContentStream[環境] 使用しているスタック
| Framework | Nuxt 3 (Nitro) |
| Platform | Vercel (Edge Runtime) |
| Library | @google/generative-ai |
| API | Gemini Pro / Flash |
[原因] Edge RuntimeにおけるReadableStreamの不整合
このエラーの根本的な原因は、Vercel Edge Runtime(Nitroエンジン)において、標準のWeb Streams APIとNode.js互換レイヤーの挙動が混在していることにあります。Google AI SDKは内部的に response.body.getReader() を利用してストリームを読み取ろうとしますが、エッジ環境独自のfetch実装が返すストリームオブジェクトが、SDKの期待するWeb標準のインターフェースと完全には一致しない(または型定義上の乖離がある)ため、関数として認識されず失敗します。
[解決策] Node.jsランタイムへの切り替え
現状、このエラーを回避する最もシンプルかつ確実な方法は、当該のAPIルートを Edge Runtime から Node.js ランタイム へ変更することです。
修正コード (server/api/chat.ts)
// 1. エッジランタイムではなくNode.jsランタイムを明示的に指定
export const config = {
runtime: 'nodejs'
};
import { GoogleGenerativeAI } from "@google/generative-ai";
export default defineEventHandler(async (event) => {
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
const { prompt } = await readBody(event);
// runtime: 'nodejs' に設定することで、SDK内部のストリーム処理が正しく動作します
const result = await model.generateContentStream(prompt);
return sendStream(event, result.stream);
});このように、export const config = { runtime: 'nodejs' }; を追加することで、NitroがVercel上でNode.js環境としてデプロイされ、SDKが必要とする環境が整います。
まとめ
Nuxt 3 + Gemini APIの組み合わせで getReader is not a function エラーが発生した場合、多くはVercel Edge Runtimeとの互換性問題です。AIチャットのように ReadableStream を多用する機能では、無理にエッジで動かそうとせず、Node.jsランタイムに切り替えるのが現時点でのベストプラクティスといえます。同様の問題で詰まっている方はぜひ試してみてください。


