Next.js App RouterをCloudflare Pagesへ

Next.jsのApp Routerで構築したサイトをCloudflare Pagesにデプロイするために必要な作業をまとめました。package.jsonにビルドコマンドを登録し、ページやAPIのランタイムをedgeに変更する必要があります。また、Font(next/font/google)の読み込みも調整する必要があります。これらの作業を行えば、エラーを回避できるはずです。ただし、CMSやライブラリとの連携やデプロイ設定の変更が必要な場合もあるので、参考リンクもご覧ください。

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

目次

    Next.jsのApp Routerで構築したサイトをCloudflare Pagesにデプロイしてみた時の、「この辺対応しないとエラーが出たぞ」の覚書です。

    Cloudflare Pages(2023/08時点)でNext.jsを動かすための追加作業

    Cloudflare PagesにNext.jsをデプロイし、動作させるには、いくつかの作業が必要です。

    [便利小技] package.jsonに作業用コマンドを登録

    Cloudflareで動かす場合、ビルドコマンドもローカルでの起動コマンドもCloudflare向けのものを使います。

    忘れる自信しかないので、npm-scriptとして登録しておきました。

    
        "build": "next build",
        "build:cf": "npx @cloudflare/next-on-pages@1",
        "start:cf": "npx wrangler pages dev ./.vercel/output/static --compatibility-flags nodejs_compat",
        "start": "next start",

    ちなみに、ビルド時は.env.productionを見ますが、start:cfコマンドでは.dev.varsファイルを参照しますのでご注意ください。

    多分もうちょっといい方法がある気はします。

    [設定変更] page.ts / route.tsのランタイムをedgeに変更

    Functionsを利用するページやAPIは、すべてexport const runtime = 'edge'を追加します。

    import { NextRequest, NextResponse } from 'next/server'
    export const runtime = 'edge'
    export async function POST(request: NextRequest) {
      if (request.headers.get('content-type') !== 'application/json') {
        return NextResponse.json(
          {
            message: 'Bad request.',
          },
          {
            status: 400,
          },
        )
      }

    静的に出力してしまいたいものは、省いても大丈夫だったと思います。async functionなコンポーネントやAPIなどにはこの作業をいれましょう。

    [Error対応] Font(next/font/google)を外す

    create-next-appで立ち上げた状態だと、Google Fontsを読み込みます。

    import './globals.css'
    import type { Metadata } from 'next'
    import { Inter } from 'next/font/google'
    import Link from 'next/link'
    
    const inter = Inter({ subsets: ['latin'] })
    
    export const metadata: Metadata = {
      title: 'Create Next App',
      description: 'Generated by create next app',
    }
    
    export default async function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang='ja'>
          <body className={inter.className}>

    エラーログをメモし忘れたのですが、どうもこのあたりでエラーが起きている様子でしたので、外しました。

    import './globals.css'
    import type { Metadata } from 'next'
    import Link from 'next/link'
    
    export const metadata: Metadata = {
      title: 'Create Next App',
      description: 'Generated by create next app',
    }
    
    export default async function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang='ja'>
          <body

    おわりに

    連携するCMSやライブラリ絡みで追加作業が発生したり、デプロイの設定変更が必要なケースはまだあると思います。

    が、とりあえず立ち上げた直後のアプリを動かすだけならこの辺りの作業を済ませれば、エラーになることは回避できる・・・はずです。

    参考

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark