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)

The create-cloudflare CLI (C3) will configure your Next.js site for Cloudflare Pages. Run the following command in your terminal to create a new Next.js site:

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

C3 will ask you a series of setup questions. C3 will also install necessary dependencies, including the Wrangler CLI and the @cloudflare/next-on-pages adapter.

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

When creating your new project, C3 will give you the option of deploying an initial version of your application via Direct Upload. You can redeploy your application at any time by running following command inside your project directory:

$ npm run deploy

​​ 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, Cloudflare recommends 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.

​​ Git integration

In addition to Direct Upload deployments, you can deploy projects via Git integration. Git integration allows you to connect a GitHub or GitLab repository to your Pages application and have your Pages application automatically built and deployed after each new commit is pushed to it.

Setup requires a basic understanding of Git. If you are new to Git, refer to GitHub’s summarized Git handbook on how to set up Git on your local machine.

​​ Create a new GitHub repository

Create a new GitHub repository by visiting repo.new. After creating a new repository, go to your newly created project directory to prepare and push your local application to GitHub by running the following commands in your terminal:

# Skip the following three commands if you have built your application
# using C3 or already committed your changes
$ git init
$ git add .
$ git commit -m "Initial commit"
$ git branch -M main
$ git remote add origin https://github.com/<your-gh-username>/<repository-name>
$ git push -u origin main

​​ Connect your application to the GitHub repository via the Cloudflare dashboard

  1. Log in to the Cloudflare dashboard and select your account.
  2. In Account Home, select Workers & Pages > Create application > Pages > Connect to Git.

You will be asked to authorize access to your GitHub account if you have not already done so. Cloudflare needs this so that it can monitor and deploy your projects from the source. You may narrow access to specific repositories if you prefer. However, you will have to manually update this list within your GitHub settings when you want to add more repositories to Cloudflare Pages.

  1. Select the new GitHub repository that you created and, in the Set up builds and deployments section, provide the following information:
Configuration optionValue
Production branchmain
Build commandnpx @cloudflare/next-on-pages@1
Build directory.vercel/output/static

Optionally, you can customize the Project name field. It defaults to the GitHub repository’s name, but it does not need to match. The Project name value is assigned as your *.pages.dev subdomain.

  1. After completing configuration, select Save and Deploy.

You will be able to review your first deploy pipeline in progress. Pages installs all dependencies and builds the project as specified. Cloudflare Pages will automatically rebuild your project and deploy it on every new pushed commit.

Additionally, you will have access to preview deployments, which repeat the build-and-deploy process for pull requests. With these, you can preview changes to your project with a real URL before deploying your changes to production.

​​ Use bindings in your Next.js application

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

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

​​ Set up bindings for local development

To set up bindings for use in local development, you will use the setupDevPlatform function provided by @cloudflare/next-on-pages/next-dev. setupDevPlatform sets up a platform emulation based on your project’s wrangler.toml file that your Next.js application can make use of locally.

For example, to work with a KV binding locally, open the Next.js configuration file and add:

next.config.mjs
import { setupDevPlatform } from '@cloudflare/next-on-pages/next-dev'
// note: the if statement is present because you
// only need to use the function during development
if (process.env.NODE_ENV === 'development') {
await setupDevPlatform()
}
/** @type {import('next').NextConfig} */
const nextConfig = {}
export default nextConfig
next.config.js / next.config.cjs
// note: the if statement is present because you
// only need to use the function during development
if (process.env.NODE_ENV === "development") {
const { setupDevPlatform } = require("@cloudflare/next-on-pages/next-dev")
setupDevPlatform()
}
/** @type {import('next').NextConfig} */
const nextConfig = {}
module.exports = nextConfig

Make sure to have a wrangler.toml file at the root of your project with a declaration for a KV binding named MY_KV:

wrangler.toml
name = "my-next-app"
compatibility_flags = ["nodejs_compat"]
[[kv_namespaces]]
binding = "MY_KV"
id = "<YOUR_KV_NAMESPACE_ID>"

​​ Set up bindings for a deployed application

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.

​​ Add bindings to Typescript projects

If your project is using TypeScript, you will want to set up proper type support so you can access your bindings in a type-safe and convenient manner.

To get proper type support, you need to create a new env.d.ts file in your project and extend the CloudflareEnv (used by getRequestContext) interface with your bindings.

The following is an example of how to add a KVNamespace binding:

env.d.ts
interface CloudflareEnv {
// The KV Namespace binding type used here comes
// from `@cloudflare/workers-types`. To use it in such
// a way 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
}

​​ Access bindings in the application

Local and remote bindings can be accessed using the getRequestContext function exposed by @cloudflare/next-on-pages. The following code example shows how to access them in a hello API route of an App Router application.

app/api/hello/route.js
import { getRequestContext } from '@cloudflare/next-on-pages'
// ...
export async function GET(request) {
// this is the KV binding you defined in the wrangler.toml file
const myKv = getRequestContext().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
import { getRequestContext } from '@cloudflare/next-on-pages'
// ...
export async function GET(request: NextRequest) {
// this is the KV binding you defined in the wrangler.toml file
const myKv = getRequestContext().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}`)
}

​​ 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.

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

​​ 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) makes it possible to use Next.js’ standard development server while still having access to your Cloudflare bindings.

​​ Build and preview your application locally

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

If you have created your project with C3, do this by running:

$ npm run preview

If you have created your project without C3, run:

$ npx @cloudflare/next-on-pages@1

And preview your project by running:

$ npx wrangler pages dev .vercel/output/static

​​ Deploy your application and iterate

After you have previewed your application locally, you can deploy it to Cloudflare Pages (both via Direct Uploads or Git integration) and iterate over the process to make new changes.

​​ 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.