Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Pages] Simplify Next.js docs (and port over content from next-on-pages repo) #15995

Merged
merged 30 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4991f95
Simplify Next.js docs
irvinebroque Aug 4, 2024
8c07788
Fix sh command linter warning
irvinebroque Aug 4, 2024
62ca11f
Make step-by-step headings bold
irvinebroque Aug 4, 2024
7b15836
Prettier
irvinebroque Aug 4, 2024
9d94fa4
Update deploy-a-nextjs-site.md
irvinebroque Aug 5, 2024
405bd4d
Merge branch 'production' into simplify-next-js
kodster28 Aug 5, 2024
3851c5d
[Pages] Middle approach for next.js
kodster28 Aug 5, 2024
49a890e
fix broken links
kodster28 Aug 5, 2024
fe790ae
Add TypeScript section
irvinebroque Aug 6, 2024
333f496
Add step for converting routes to edge runtime
irvinebroque Aug 6, 2024
c7e573e
Add section on cf, ctx APIs
irvinebroque Aug 6, 2024
1faf4c5
Add two more pages
kodster28 Aug 6, 2024
974a7fe
Remove custom worker entrypoint
kodster28 Aug 6, 2024
58ac6d0
Simplify Next.js caching docs
irvinebroque Aug 9, 2024
18f9879
Clarify static assets section
irvinebroque Aug 9, 2024
70b8b73
Move over supported features page
irvinebroque Aug 9, 2024
abff8a2
Fix URLs
irvinebroque Aug 9, 2024
270a2ef
Apply suggestions from code review
irvinebroque Aug 9, 2024
d38808c
Update content/pages/framework-guides/nextjs/ssr/get-started.md
irvinebroque Aug 9, 2024
0257fe5
Create advanced.md
irvinebroque Aug 9, 2024
b76d6ca
Update content/pages/framework-guides/nextjs/ssr/advanced.md
irvinebroque Aug 9, 2024
d50ce03
fixed broken links
kodster28 Aug 9, 2024
bc7528f
Small content edits
kodster28 Aug 9, 2024
d16e29c
finalize links
kodster28 Aug 9, 2024
ca4062d
Update content/pages/framework-guides/nextjs/ssr/supported-features.md
irvinebroque Aug 9, 2024
5be4b72
Update content/pages/framework-guides/nextjs/ssr/supported-features.md
irvinebroque Aug 9, 2024
323bce8
Update content/pages/framework-guides/nextjs/ssr/supported-features.md
irvinebroque Aug 9, 2024
52a3fa9
Update content/pages/framework-guides/nextjs/ssr/supported-features.md
irvinebroque Aug 9, 2024
2f3459d
Reframe ISR section
kodster28 Aug 9, 2024
6f59bb8
remove extra sentence
kodster28 Aug 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion content/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@
/pages/how-to/deploy-a-jekyll-site/ /pages/framework-guides/deploy-a-jekyll-site/ 301
/pages/how-to/deploy-a-nextjs-site/ /pages/framework-guides/nextjs/ 301
/pages/framework-guides/deploy-a-nextjs-site/ /pages/framework-guides/nextjs/ 301
/pages/framework-guides/nextjs/deploy-a-nextjs-site/ /pages/framework-guides/nextjs/ssr/get-started/ 301
/pages/how-to/deploy-anything/ /pages/framework-guides/deploy-anything/ 301
/pages/how-to/deploy-a-react-application/ /pages/framework-guides/deploy-a-react-site/ 301
/pages/framework-guides/deploy-a-react-application/ /pages/framework-guides/deploy-a-react-site/ 301
Expand Down Expand Up @@ -1123,7 +1124,7 @@
/r2/buckets/data-location/ /r2/reference/data-location/ 301
/r2/reference/audit-logs/ /r2/platform/audit-logs/ 301
/r2/reference/changelog/ /r2/platform/changelog/ 301
/r2/reference/changelog/index.xml /r2/platform/changelog/index.xml 301
/r2/reference/changelog/index.xml /r2/platform/changelog/index.xml 301
/r2/reference/limits/ /r2/platform/limits/ 301
/r2/reference/metrics-analytics/ /r2/platform/metrics-analytics/ 301

Expand Down
440 changes: 0 additions & 440 deletions content/pages/framework-guides/nextjs/deploy-a-nextjs-site.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
---
pcx_content_type: how-to
title: Static deployment
title: Static site
meta:
description: Deploy a static Next.js site with static exports.
title: Get started | Static site | Next.js apps
description: Deploy a static site built using Next.js to Cloudflare Pages
---

# Deploy a static Next.js site

{{<Aside type="note">}}

Do not use this guide unless you have a specific use case for static exports. Cloudflare recommends using the [Deploy a Next.js site](/pages/framework-guides/nextjs/deploy-a-nextjs-site/) guide.
Do not use this guide unless you have a specific use case for static exports. Cloudflare recommends using the [Deploy a Next.js site](/pages/framework-guides/nextjs/ssr/get-started/) guide.

{{</Aside>}}

Expand Down
11 changes: 11 additions & 0 deletions content/pages/framework-guides/nextjs/ssr/_index.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add back the advanced usage section you're removing in next-on-pages too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
type: overview
pcx_content_type: navigation
title: Full-stack (SSR)
---

# Next.js

[Next.js](https://nextjs.org) is an open-source React.js framework for building full-stack applications. This section helps you deploy a full-stack Next.js project to Cloudflare Pages using [`@cloudflare/next-on-pages`](https://github.com/cloudflare/next-on-pages/tree/main/packages/next-on-pages/docs).

{{<directory-listing>}}
45 changes: 45 additions & 0 deletions content/pages/framework-guides/nextjs/ssr/advanced.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
pcx_content_type: reference
title: Advanced Usage
weight: 8
meta:
title: Advanced Usage
---

# Advanced Usage

## Custom Worker Entrypoint

If you need to run code before or after your Next.js application, create your own Worker entrypoint and forward requests to your Next.js application.

This can help you intercept logs from your app, catch and handle uncaught exceptions, or add additional context to incoming requests or outgoing responses.

1. Create a new file in your Next.js project, with a [`fetch()` handler](/workers/runtime-apis/handlers/fetch/), that looks like this:

```ts
---
filename: ./custom-entrypoint.ts
---
import nextOnPagesHandler from '@cloudflare/next-on-pages/fetch-handler';

export default {
async fetch(request, env, ctx) {
// do something before running the next-on-pages handler

const response = await nextOnPagesHandler.fetch(request, env, ctx);

// do something after running the next-on-pages handler

return response;
},
} as ExportedHandler<{ ASSETS: Fetcher }>;
```

This looks like a Worker — but it does not need its own `wrangler.toml` file. You can think of it purely as code that `@cloudflare/next-on-pages` will then use to wrap the output of the build that is deployed to your Cloudflare Pages project.


2. Pass the entrypoint argument to the next-on-pages CLI with the path to your handler.

```sh
irvinebroque marked this conversation as resolved.
Show resolved Hide resolved
$ npx @cloudflare/next-on-pages --custom-entrypoint=./custom-entrypoint.ts
```
80 changes: 80 additions & 0 deletions content/pages/framework-guides/nextjs/ssr/bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
pcx_content_type: reference
title: Bindings
weight: 2
meta:
title: Using bindings in your Next.js app
---

# Using bindings in your Next.js app

Once you have [set up next-on-pages](/pages/framework-guides/nextjs/ssr/get-started/), you can access [bindings](/workers/runtime-apis/bindings/) from any route of your Next.js app via `getRequestContext`:

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

export const runtime = "edge";

export async function GET(request) {
let responseText = "Hello World";

const myKv = getRequestContext().env.MY_KV_NAMESPACE;
await myKv.put("foo", "bar");
const foo = await myKv.get("foo");

return new Response(foo);
}
```

Add bindings to your Pages project by [adding them to your `wrangler.toml` configuration file](/pages/functions/wrangler-configuration/).

## TypeScript type declarations for bindings

To ensure that the `env` object from `getRequestContext().env` above has accurate TypeScript types, install [`@cloudflare/workers-types`](https://www.npmjs.com/package/@cloudflare/workers-types) and create a [TypeScript declaration file](https://www.typescriptlang.org/docs/handbook/2/type-declarations.html).

Install Workers Types:

```sh
$ npm install --save-dev @cloudflare/workers-types
```

Add Workers Types to your `tsconfig.json` file, replacing the date below with your project's [compatibility date](/workers/configuration/compatibility-dates/):

```diff
---
header: tsconfig.json
---
"types": [
+ "@cloudflare/workers-types/2024-07-29"
]
```

Create an `env.d.ts` file in the root directory of your Next.js app, and explicitly declare the type of each binding:

```ts
---
header: env.d.ts
---
interface CloudflareEnv {
MY_KV_1: KVNamespace;
MY_KV_2: KVNamespace;
MY_R2: R2Bucket;
MY_DO: DurableObjectNamespace;
}
```

## Other Cloudflare APIs (`cf`, `ctx`)

Access context about the incoming request from the [`cf` object](/workers/runtime-apis/request/#incomingrequestcfproperties), as well as [lifecycle methods from the `ctx` object](/workers/runtime-apis/handlers/fetch/#lifecycle-methods) from the return value of [`getRequestContext()`](https://github.com/cloudflare/next-on-pages/blob/main/packages/next-on-pages/src/api/getRequestContext.ts):

```js
import { getRequestContext } from '@cloudflare/next-on-pages';

export const runtime = "edge";

export async function GET(request) {
const { env, cf, ctx } = getRequestContext();

// ...
}
```
38 changes: 38 additions & 0 deletions content/pages/framework-guides/nextjs/ssr/caching.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
pcx_content_type: reference
title: Caching
meta:
title: Caching and data revalidation in your Next.js app
---

# Caching and data revalidation
kodster28 marked this conversation as resolved.
Show resolved Hide resolved

[`@cloudflare/next-on-pages`](https://github.com/cloudflare/next-on-pages) supports [caching](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data) and [revalidating](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data) data returned by subrequests you make in your app by calling [`fetch()`](/workers/runtime-apis/fetch/).

By default, all `fetch()` subrequests made in your Next.js app are cached. Refer to the [Next.js documentation](https://nextjs.org/docs/app/building-your-application/caching#opting-out-1) for information about how to disable caching for an individual subrequest, or for an entire route.

[The cache persists across deployments](https://nextjs.org/docs/app/building-your-application/caching#data-cache). You are responsible for revalidating/purging this cache.

## Storage options

You can configure your Next.js app to write cache entries to and read from either [Workers KV](/kv/) or the [Cache API](/workers/runtime-apis/cache/).

### Workers KV (recommended)

It takes an extra step to enable, but Cloudflare recommends caching data using [Workers KV](/kv/).

When you write cached data to Workers KV, you write to storage that can be read by any Cloudflare location. This means your app can fetch data, cache it in KV, and then subsequent requests anywhere around the world can read from this cache.

<Aside type="note">

Workers KV is eventually consistent, which means that it can take up to 60 seconds for updates to be reflected globally.

</Aside>

To use Workers KV as the cache for your Next.js app, [add a KV binding](/pages/functions/bindings/#kv-namespaces) to your Pages project, and set the name of the binding to `__NEXT_ON_PAGES__KV_SUSPENSE_CACHE`.

### Cache API (default)

The [Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/) is the default option for caching data in your Next.js app. You do not need to take any action to enable the Cache API.
irvinebroque marked this conversation as resolved.
Show resolved Hide resolved

In contrast with Workers KV, when you write data using the Cache API, data is only cached in the Cloudflare location that you are writing data from.
137 changes: 137 additions & 0 deletions content/pages/framework-guides/nextjs/ssr/get-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
pcx_content_type: get-started
title: Get started
weight: 1
meta:
title: Get started | Full-stack (SSR) | Next.js apps
description: Deploy a full-stack Next.js app to Cloudflare Pages
---

# Next.js

Learn how to deploy full-stack (SSR) Next.js apps to Cloudflare Pages.

## New apps

To create a new Next.js app, pre-configured to run on Cloudflare, run:

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

For more guidance on developing your app, refer to [Bindings](/pages/framework-guides/nextjs/ssr/bindings/) or the [Next.js documentation](https://nextjs.org).

---

## Existing apps


### 1. Install next-on-pages

First, install [@cloudflare/next-on-pages](https://github.com/cloudflare/next-on-pages):

```sh
$ npm install --save-dev @cloudflare/next-on-pages
```

### 2. Add `wrangler.toml` file

Then, add a [`wrangler.toml`](/pages/functions/wrangler-configuration/) file to the root directory of your Next.js app:

```toml
name = "my-app"
compatibility_date = "2024-07-29"
compatibility_flags = ["nodejs_compat"]
pages_build_output_dir = ".vercel/output/static"
```

This is where you configure your Pages project and define what resources it can access via [bindings](/workers/runtime-apis/bindings/).

### 3. Update `next.config.mjs`

Next, update the content in your `next.config.mjs` file.

```diff
---
header: next.config.mjs
---
+ import { setupDevPlatform } from '@cloudflare/next-on-pages/next-dev';

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

+ if (process.env.NODE_ENV === 'development') {
+ await setupDevPlatform();
+ }

export default nextConfig;
```

These changes allows you to access [bindings](/pages/framework-guides/nextjs/ssr/bindings/) in local development.

### 4. Ensure all server-rendered routes use the Edge Runtime

Next.js has [two "runtimes"](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) — "Edge" and "Node.js". When you run your Next.js app on Cloudflare, you [can use available Node.js APIs](/workers/runtime-apis/nodejs/) — but you currently can only use Next.js' "Edge" runtime.

This means that for each server-rendered route — ex: an API route or one that uses `getServerSideProps` — you must configure it to use the "Edge" runtime:

```js
export const runtime = "edge";
```

### 5. Update `package.json`

Add the following to the scripts field of your `package.json` file:

```json
---
header: package.json
---
"pages:build": "npx @cloudflare/next-on-pages",
"preview": "npm run pages:build && wrangler pages dev",
"deploy": "npm run pages:build && wrangler pages deploy"
```

- `npm run pages:build`: Runs `next build`, and then transforms its output to be compatible with Cloudflare Pages.
- `npm run preview`: Builds your app, and runs it locally in [workerd](https://github.com/cloudflare/workerd), the open-source Workers Runtime. (`next dev` will only run your app in Node.js)
- `npm run deploy`: Builds your app, and then deploys it to Cloudflare

### 6. Deploy to Cloudflare Pages

Either deploy via the command line:

```sh
$ npm run deploy
```

Or [connect a Github or Gitlab repository](/pages/get-started/git-integration/), and Cloudflare will automatically build and deploy each pull request you merge to your production branch.

### 7. (Optional) Add `eslint-plugin-next-on-pages`

Optionally, you might want to add `eslint-plugin-next-on-pages`, which lints your Next.js app to ensure it is configured correctly to run on Cloudflare Pages.

```sh
$ npm install --save-dev eslint-plugin-next-on-pages
```

Once it is installed, add the following to `.eslintrc.json`:

```diff
---
header: .eslintrc.json
---
{
"extends": [
"next/core-web-vitals",
+ "plugin:eslint-plugin-next-on-pages/recommended"
],
"plugins": [
+ "eslint-plugin-next-on-pages"
]
}
```

## Related resources

- [Bindings](/pages/framework-guides/nextjs/ssr/bindings/)
- [Troubleshooting](/pages/framework-guides/nextjs/ssr/troubleshooting/)
28 changes: 28 additions & 0 deletions content/pages/framework-guides/nextjs/ssr/static-assets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
pcx_content_type: reference
title: Routing static assets
meta:
title: Routing static assets | Full-stack (SSR) | Next.js apps
---

# Routing static assets

When you use a JavaScript framework like Next.js on Cloudflare Pages, the framework adapter (ex: `@cloudflare/next-on-pages`) automatically generates a [`_routes.json` file](/pages/functions/routing/#create-a-_routesjson-file), which defines specific paths of your app's static assets. This file tells Cloudflare, `for these paths, don't run the Worker, you can just serve the static asset on this path` (an image, a chunk of client-side JavaScript, etc.)

The framework adapter handles this for you — you typically shouldn't need to create your own `_routes.json` file.

If you need to, you can define your own `_routes.json` file in the root directory of your project. For example, you might want to declare the `/favicon.ico` path as a static asset where the Worker should not be invoked.

You would add it to the `excludes` filed of your `_routes.json` file:

```json
---
header: _routes.json
---
{
"version": 1,
"exclude": ["/favicon.ico"]
}
```

During the build process, `@cloudflare/next-on-pages` will automatically generate its own `_routes.json` file in the output directory. Any entries that are provided in your own `_routes.json` file (in the project's root directory) will be merged with the generated file.
Loading
Loading