Cloudflare Docs
Pages
Edit this page on GitHub
Set theme to dark (⇧+D)

Deploy a Next.js site

Next.js is an open-source React framework for creating websites and applications. In this guide, you will create a new Next.js application and deploy it using Cloudflare Pages.

This guide will instruct you how to deploy a full-stack Next.js project which uses the Edge Runtime.

​​ Create a new project using the create-cloudflare CLI (C3)

To create a new Next.js site, open up your terminal and run:

$ npm create cloudflare@latest my-next-app -- --framework=next

create-cloudflare will:

  • install necessary dependencies, including the Wrangler CLI and the @cloudflare/next-on-pages adapter
  • ask you a series of setup questions
  • allow you to setup a new git repo
  • allow you to deploy your new project

After creating your project, a new my-next-app directory will be generated using the default Next.js template, updated to be fully compatible with Cloudflare Pages.

Change to this directory to continue development.

$ cd my-next-app

If you chose to deploy, you will receive a unique subdomain for your project on *.pages.dev, and you can access it almost immediately.

​​ Configure and deploy a project without C3

If you already have a Next.js project or wish to manually create and deploy one without using c3, we recommend that you use @cloudflare/next-on-pages and refer to its README for instructions and additional information to help you develop and deploy your project.

​​ Preview your site (git-connected projects)

After deploying your site, you will receive a unique subdomain for your project on *.pages.dev. Every time you commit new code to your git repository, Cloudflare Pages will automatically rebuild your project and deploy it. You will also get access to preview deployments on new pull requests, so you can preview how changes look to your site before deploying them to production.

​​ Use bindings in your Next.js application

A binding allows your application to interact with Cloudflare developer products, such as KV, Durable Object, R2, and D1.

If you intend to use bindings in your project, you must set them up for local and remote development.

​​ Set up bindings for local development

To set up bindings for use in local development, you will use the setupDevBindings function provided by @cloudflare/next-on-pages/next-dev. This function allows you to specify bindings that work locally, and are accessed the same way remote bindings are.

For example to work with a KV binding locally, you need to open next.config.js and add:

next.config.js
// 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") {
// import the utility from the next-dev submodule
const { setupDevBindings } = require("@cloudflare/next-on-pages/next-dev");
// call the utility with the bindings you want to have access to
setupDevBindings({
bindings: {
MY_KV: {
type: "kv",
id: "MY_KV",
},
},
});
}

​​ Set up bindings for a deployed application

In orer to access bindings in a deployed application, you will need to configure any necessary bindings and connect them to your project via your project’s settings page in the Cloudflare Dashboard.

​​ Access bindings in the application

Local and remote bindings can be accessed directly from process.env:

app/api/hello/route.js
export async function GET(request) {
// this is the KV binding you defined in next.config.js
const myKv = process.env.MY_KV;
// get a value from the namespace
const kvValue = await myKv.get(`kvTest`) || false;
return new Response(`The value of kvTest in MY_KV is: ${kvValue}`)
}
app/api/hello/route.ts
export async function GET(request: NextRequest) {
// this is the KV binding you defined in next.config.js
const myKv = process.env.MY_KV;
// get a value from the namespace
const kvValue = await myKv.get(`kvTest`) || false;
return new Response(`The value of kvTest in MY_KV is: ${kvValue}`)
}

​​ Add bindings to Typescript projects

In order to get proper type support, you’ll need to create a new env.d.ts file in your project and declare a binding.

The following is an example of adding a KVNamespace binding:

env.d.ts
declare global {
namespace NodeJS {
interface ProcessEnv {
// The KV Namespace binding type used here comes
// from `@cloudflare/workers-types`, in order to
// use it like so, make sure that you have installed
// the package as a dev dependency and you have added
// it to your `tsconfig.json` file under
// `compilerOptions.types`.
MY_KV: KVNamespace;
}
}
}
export {};

When developing a next-on-pages application, this is the development workflow that we recommend:

​​ Develop using the standard Next.js dev server

The standard development server provided by Next.js is the best available option for a fast and polished development experience. The next-dev submodule (as described in the local bindings section above makes it possible to use Next.js’ standard development server while still having access to your Cloudflare bindings.

​​ Build and preview your application locally

In order to make sure that your application is being built in a manner that is fully compatible with Cloudflare Pages, before deploying it, or whenever you’re comfortable checking the correctness of the application during your development process you’ll want to build and preview it locally using Cloudflare’s workerd JavaScript runtime.

If you have created your project with C3, you can do this by running npm run pages:build && npm run pages:dev.

If you have created your project manually, you will need to run npx @cloudflare/next-on-pages --watch and preview it by running wrangler pages dev .vercel/output/static --compatibility-flag=nodejs_compat.

By doing this, you can run your application locally to make sure everything is working as you expect it to.

​​ Deploy your app and iterate

Once you’ve previewed your application locally then you can deploy it to Cloudflare Pages (both via direct uploads or git integration) and iterate over the process to make new changes.

​​ Image component

The Cloudflare network does not provide the same image optimization support as the Vercel network does, because of this the Next.js’ <Image /> component behaves differently from how it would in the Vercel network.

  • If you build your application as a static site, the <Image /> component will not serve any images.

  • If you build your application using @cloudflare/next-on-pages, the component will work but it will not perform any image optimization (regardless of the props you pass to it).

Both cases can be improved by setting up proper loaders for the <Image /> component, which allow you to use any image optimization service you want. To use Cloudflare Images, refer to resize with Cloudflare Workers.

​​ Learn more

By completing this guide, you have successfully deployed your Next.js site to Cloudflare Pages. To get started with other frameworks, refer to the list of Framework guides.