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)
Open up your terminal and run the following command to create a new Next.js site. Your Next.js site is configured for Cloudflare Pages using the create-cloudflare
CLI (C3).
$ npm create cloudflare@latest my-next-app -- --framework=next
C3 will install necessary dependencies, including the Wrangler CLI and the @cloudflare/next-on-pages
adapter. C3 will also ask you a series of setup questions.
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.
To (re)deploy your application after having made changes, run the deployment command that C3 generates for you:
$ 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.
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 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 setupDevPlatform
function provided by @cloudflare/next-on-pages/next-dev
. This function, tries to read the project’s wrangler.toml
file and based on it sets up a platform emulation 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.mjsimport { setupDevPlatform } from '@cloudflare/next-on-pages/next-dev'
// note: the if statement is because we only need to use the function
// during development (the check is recommended but completely optional)
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 because we only need to use the function
// during development (the check is recommended but completely optional)
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
Also 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.tomlname = "my-next-app"
compatibility_flags = ["nodejs_compat"]
[[kv_namespaces]]
binding = "MY_KV"
id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
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 that 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.tsinterface 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.jsimport { 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.tsimport { 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.
Git integration
In addition to Direct Upload deployments, you can make use of the Pages Git integration, which allows you to connect a GitHub repository to your Pages application and have the application automatically built and deployed after each new commit is pushed to it.
This 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, prepare and push your local application to GitHub by running the following commands in your terminal:
# Skip the following 3 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
- Log in to the Cloudflare dashboard and select your account.
- 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.
- Select the new GitHub repository that you created and, in the Set up builds and deployments section, provide the following information:
Configuration option | Value |
---|---|
Production branch | main |
Build command | npx @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.
- After completing configuration, click the Save and Deploy button.
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 them to production.
Recommended development workflow
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.