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やライブラリ絡みで追加作業が発生したり、デプロイの設定変更が必要なケースはまだあると思います。
が、とりあえず立ち上げた直後のアプリを動かすだけならこの辺りの作業を済ませれば、エラーになることは回避できる・・・はずです。