Deploying Next.js on Cloudflare pages

deploying nextjs on cloudflare pages

You can deploy a static next.js easily to a cloudflare pages, either using the wrangler cli or with git integration.

The problem arises when your using cloudflare bindings to D1 or KV or any other service.

But cloudflare have recently created a package next-on-pages which allows you run a nextjs app locally while still being able to hot reload and access local versions of cloudflare services.

// file: next.config.mjs

// we import the utility from the next-dev submodule
import { setupDevPlatform } from '@cloudflare/next-on-pages/next-dev';

/** @type {import('next').NextConfig} */
const nextConfig = {};

export default nextConfig;

// we only need to use the utility during development so we can check NODE_ENV
// (note: this check is recommended but completely optional)
if (process.env.NODE_ENV === 'development') {
	// `await`ing the call is not necessary but it helps making sure that the setup has succeeded.
	//  If you cannot use top level awaits you could use the following to avoid an unhandled rejection:
	//  `setupDevPlatform().catch(e => console.error(e));`
	await setupDevPlatform();
}

Calling setupDevPlatform in development loads cloudflare local services.

Bindings

If you are using typescript you can add your binding definitions

// file: env.d.ts

interface CloudflareEnv {
	MY_KV_1: KVNamespace;
	MY_KV_2: KVNamespace;
	MY_R2: R2Bucket;
	MY_DO: DurableObjectNamespace;
}

then you can access your cloudflare services in code:

import {getRequestContext} from "@cloudflare/next-on-pages";

const {env} = getRequestContext()

Build

Build using the next-on-pages package.

npx @cloudflare/next-on-pages@1

You can run a production build locally before deploying

wrangler pages dev .vercel/output/static --compatibility-flag nodejs_compat

Local dev

Running cloudflare locally, it creates local copies of your D1 database and R2 files in the .wrangler file.

If you have a mono repo or another worker your app has a service binding or RPC call too you can share these files across workers

wrangler dev --persist-to='../web/.wrangler/state/'

This worker shares the state with the web app.

© 2024 Timney.