未分類

Next.js (App Router) で、同一ドメインのAPIにfetchする際の覚書

Next.jsのApp Routerでのアプリ構築中に、Page Routerとfetchの挙動・仕様の違いに遭遇しました。以前のNext.jsとは異なり、相対パスでのAPIリクエストがエラーになります。next/headersを使用して現在のサイトのドメインを取得し、fetchのURLに渡すことで解決できます。App Routerでは、next/headersのheaders()からプロトコルやホストを取得できるため、app/api/route.tsなどで作成したAPIをapp/page.tsなどからfetchすることができます。参考になる記事やGithubの情報もあります。

広告ここから
広告ここまで

Next.jsのApp Routerでアプリを構築中、Page Routerとfetchの挙動・仕様が異なる様子でしたので、ざっとまとめました。

これまでのNext.jsとの違い

fetch('/api/xxx')のように、相対パスでAPIリクエストを投げることがありました。

これがApp Routerではエラーになります。

Unhandled Runtime Error
Error: Failed to parse URL from /api/prices

サーバーサイドでfetchしようとしてエラーになっている・・・と思われます。

next/headersで今いるサイトのドメインを取得する

相対パスが使えないので、今動かしているNext.jsアプリのドメインを、fetchのurlに渡すようにしてみました。

import { Metadata } from 'next'
import { headers } from 'next/headers'
export const metadata: Metadata = {
  title: 'Products',
}
export default async function Page() {
    const headersData = headers()
    const host = headersData.get('host')
    const protocol = headersData.get('x-forwarded-proto') ?? host.startWith('localhost') ? 'http' : 'https'
    const apiBase = `${protocol}://${host}`
    const res = await fetch(`${apiBase}/api/prices`, {
        next: {
            revalidate: 10 * 60 // 10 minutes
        }
    }).then(data => data.json())
...

localhostではhttpになるので、プロトコルもヘッダー情報から取得します。

Next.js App Routerでは、next/headersheaders()からプロトコルやホストが取得できました。

この方法で、app/api/route.tsなどに作成したAPIを、app/page.tsなどからfetchできる様子です。

参考

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts