アイコン
スキル

Next.js + SWR + Vercel で「Failed to parse URL」が出る原因と対処法

アイキャッチ

こんにちは、さかです。

今回、Next.jsでアプリ開発をしている際に遭遇した、少しハマったエラーとその解決方法について紹介します。

はじめに

Next.js で構成されたアプリを Vercel にデプロイした際、以下のエラーが発生しました。

TypeError: Failed to parse URL from /api/info

ローカル環境では正常に動作していてビルドも成功していたにもかかわらず、Vercel 上でのみ、このエラーが発生しました。そのため、非常に気づきづらい問題でした。

解説を通じて、Next.js(App Router)を使っており、SWR や API Routes を導入している方にとって、参考になれば幸いです。

使用技術と構成

以下の技術を使用しています。

  • Next.js 15.2
  • Firebase Admin SDK
  • SWR
  • API Routes

構成としては、サインイン済みユーザーのセッション情報を元に、Firestore からデータを取得し、クライアントで表示するというものです。

発生したエラーについて

Vercel にデプロイ後、ビルドログに以下のエラーメッセージが出ていました。

TypeError: Failed to parse URL from /api/info

このエラーは、Node.jsが、URL を生成できなかったときに出るものです。通常、以下のように URL オブジェクトを作成しようとした際に発生します。

new URL('/api/info'); // 絶対パスがないので失敗する

このように相対パス指定すると、ビルド時や SSR 実行時には失敗することがあります。

なぜローカルでは問題が起きなかったのか?

しかし、今回はローカル環境ではエラーが起きていませんでした。

その理由として、ローカルの開発環境(npm run dev)では、localhost:3000を基準に処理されます。そのため、相対パスのみの指定しても、開発中には特に問題なく動作することができます。

vercel 上では Next.js のビルド中(または ISR/SSR 実行時)に、明示的な base URL が存在しないため、相対URLは扱えずにエラーとなります。

エラーが出ているのにビルドが「成功」する理由

今回のケースでは/api/info のエラーが出ていたにもかかわらず、Vercel のビルドログは以下のように表示されていました。

Build Completed in /vercel/output
Deployment completed

これは、App Router を使用している Next.jsでは、ページ単位でのビルドと最適化が行われます。つまり、たとえ一部のページでエラーが発生しても、他のページのビルドが正常に終わっていれば、全体としては「成功」と判断されるのです。

最初このことに気づかず、デプロイ後のページを確認して、エラーが出ていることに気づきました。

問題となった箇所

今回のエラーは以下のようなコードに起因していました。

const apiUrl = '/api/info';

// データの事前読み込み
preload(apiUrl, fetcher); // ← これがビルド中に実行されてしまう

preloadは SWR の関数で、指定した URL に対して事前にデータ取得を開始する役割を持ちます。本来クライアントコンポーネント内の処理であるにも関わらず、Next.js の最適化処理の中で ビルド時にも評価されることがあるため、ここで相対パスが使われていると URL 解釈に失敗してしまいます。

対処法

今回のエラーについて、以下の修正を行いました。

const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000';
const apiUrl = `${baseUrl}/api/info`;

if (typeof window !== 'undefined') {
  preload(apiUrl, fetcher); // クライアント側でのみ実行
}

ここではNEXT_PUBLIC_BASE_URLという環境変数を使い、Vercel 本番環境では Vercel のドメイン(例:https://your-app.vercel.app)、ローカルでは http://localhost:3000 をbase URLとして、使用するようにしています。

これにより、開発環境と本番環境の両方で安定して API 通信ができるようになりました。

また、修正にあたり、環境変数 NEXT_PUBLIC_BASE_URL を Vercel の環境設定画面から追加する必要があります。
これを設定しないと、本番環境でundefined/api/infoのような URL になってしまうため注意が必要です。

まとめ

「Failed to parse URL 」エラーが出た際は以下のことを気を付ける必要が学びました。

  • 相対URLは、Vercel ビルド時に失敗の原因になることがある
  • preloadは クライアントコンポーネントでもビルド中に実行される可能性がある
  • エラーが出ていても Vercel 上では ビルド成功扱いになることがあるため、ログの確認は必須
  • fetchなどで API を呼び出す際は、絶対URLを使うのが安全

今回のトラブルは、一見すると「コードの問題ではなさそう」に見えるため、原因特定に苦労しました。しかし、Next.js(App Router)と Vercel のビルドプロセスの挙動を理解することで、しっかりと対処できました。

今後もこのような事象が起きた場合には、この経験から対処できるようにしたいと思います。

参考文献

Suspense and Server-Side Rendering

Error: Failed to parse URL from ~というエラーの対処

記事をシェア

  • X-icon
  • facebook-icon
  • line-icon