Deploying Next.js 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.