diff --git a/public/__redirects b/public/__redirects index c314a81faff85e7..f100909a59d8778 100644 --- a/public/__redirects +++ b/public/__redirects @@ -1132,10 +1132,10 @@ /pages/how-to/deploy-a-gatsby-site/ /pages/framework-guides/deploy-a-gatsby-site/ 301 /pages/how-to/deploy-a-hugo-site/ /pages/framework-guides/deploy-a-hugo-site/ 301 /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/how-to/deploy-a-nextjs-site/ /workers/framework-guides/web-apps/nextjs 301 +/pages/framework-guides/nextjs/resources/* /workers/framework-guides/web-apps/nextjs 301 +/pages/framework-guides/nextjs/ssr/* /workers/framework-guides/web-apps/nextjs 301 /pages/framework-guides/deploy-a-svelte-site/ /pages/framework-guides/deploy-a-svelte-kit-site/ 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 diff --git a/src/content/docs/pages/framework-guides/nextjs/deploy-a-static-nextjs-site.mdx b/src/content/docs/pages/framework-guides/nextjs/deploy-a-static-nextjs-site.mdx index 5d99ac288006ae1..4a3498b34a9c1d0 100644 --- a/src/content/docs/pages/framework-guides/nextjs/deploy-a-static-nextjs-site.mdx +++ b/src/content/docs/pages/framework-guides/nextjs/deploy-a-static-nextjs-site.mdx @@ -13,7 +13,7 @@ import { PagesBuildPreset, Render } from "~/components"; :::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/ssr/get-started/) guide. +Do not use this guide unless you have a specific use case for static exports. Cloudflare recommends using Workers to deploy your Next.js site, for more instructions refer the [Next.js Workers guide](/workers/framework-guides/web-apps/nextjs). ::: diff --git a/src/content/docs/pages/framework-guides/nextjs/index.mdx b/src/content/docs/pages/framework-guides/nextjs/index.mdx index 436e97c7f83b13e..c07ab8f27bb67ad 100644 --- a/src/content/docs/pages/framework-guides/nextjs/index.mdx +++ b/src/content/docs/pages/framework-guides/nextjs/index.mdx @@ -1,17 +1,12 @@ --- - pcx_content_type: navigation title: Next.js head: [] description: React framework for building full-stack web applications. --- -import { DirectoryListing, YouTube } from "~/components"; - [Next.js](https://nextjs.org) is an open-source React framework for creating websites and applications. -### Video Tutorial - - +If you want to deploy a full stack Server Side Rendered Next.js application please refer to the [Next.js Workers guide](/workers/framework-guides/web-apps/nextjs). - +To instead deploy a static Next.js site using Pages see the [static Next.js Pages guide](/pages/framework-guides/nextjs/deploy-a-static-nextjs-site). diff --git a/src/content/docs/pages/framework-guides/nextjs/resources.mdx b/src/content/docs/pages/framework-guides/nextjs/resources.mdx deleted file mode 100644 index b0059623b916450..000000000000000 --- a/src/content/docs/pages/framework-guides/nextjs/resources.mdx +++ /dev/null @@ -1,18 +0,0 @@ ---- -pcx_content_type: reference -title: Resources -description: Explore tutorials and demo apps using Next.js -sidebar: - order: 15 -head: - - tag: title - content: Additional resources | Next.js ---- - -import { ResourcesBySelector, ExternalResources } from "~/components"; - -## Demo apps - -For demo applications using Next.js, refer to the following resources: - - diff --git a/src/content/docs/pages/framework-guides/nextjs/ssr/advanced.mdx b/src/content/docs/pages/framework-guides/nextjs/ssr/advanced.mdx deleted file mode 100644 index c43dced68f8795e..000000000000000 --- a/src/content/docs/pages/framework-guides/nextjs/ssr/advanced.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -pcx_content_type: reference -title: Advanced Usage -sidebar: - order: 8 -head: - - tag: title - content: 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 -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 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 -npx @cloudflare/next-on-pages --custom-entrypoint=./custom-entrypoint.ts -``` diff --git a/src/content/docs/pages/framework-guides/nextjs/ssr/bindings.mdx b/src/content/docs/pages/framework-guides/nextjs/ssr/bindings.mdx deleted file mode 100644 index 64d21caed74cf8b..000000000000000 --- a/src/content/docs/pages/framework-guides/nextjs/ssr/bindings.mdx +++ /dev/null @@ -1,49 +0,0 @@ ---- -pcx_content_type: reference -title: Bindings -sidebar: - order: 2 -head: - - tag: title - content: 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 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, make sure you have generated types by running [`wrangler types`](/workers/languages/typescript/#generate-types) and followed the setup steps. - -## 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/) 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(); - - // ... -} -``` diff --git a/src/content/docs/pages/framework-guides/nextjs/ssr/caching.mdx b/src/content/docs/pages/framework-guides/nextjs/ssr/caching.mdx deleted file mode 100644 index 02d53092a087e76..000000000000000 --- a/src/content/docs/pages/framework-guides/nextjs/ssr/caching.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -pcx_content_type: reference -title: Caching -head: - - tag: title - content: Caching and data revalidation in your Next.js app ---- - -[`@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. - -:::note - -Workers KV is eventually consistent, which means that it can take up to 60 seconds for updates to be reflected globally. - -::: - -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. - -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. diff --git a/src/content/docs/pages/framework-guides/nextjs/ssr/get-started.mdx b/src/content/docs/pages/framework-guides/nextjs/ssr/get-started.mdx deleted file mode 100644 index 6dbca8079e71f04..000000000000000 --- a/src/content/docs/pages/framework-guides/nextjs/ssr/get-started.mdx +++ /dev/null @@ -1,135 +0,0 @@ ---- -pcx_content_type: get-started -title: Get started -sidebar: - order: 1 -head: - - tag: title - content: Get started | Full-stack (SSR) | Next.js apps -description: Deploy a full-stack Next.js app to Cloudflare Pages ---- - -import { PackageManagers, WranglerConfig } from "~/components"; - -Learn how to deploy full-stack (SSR) Next.js apps to Cloudflare Pages. - -:::note -You can now also [deploy Next.js apps to Cloudflare Workers](/workers/framework-guides/web-apps/nextjs/), including apps that use the Node.js "runtime" from Next.js. This allows you to use the [Node.js APIs that Cloudflare Workers provides](/workers/runtime-apis/nodejs/#built-in-nodejs-runtime-apis), and ensures compatibility with a broader set of Next.js features and rendering modes. - -Refer to the [OpenNext docs for the `@opennextjs/cloudflare` adapter](https://opennext.js.org/cloudflare) to learn how to get started. -::: - -## New apps - -To create a new Next.js app, pre-configured to run on Cloudflare, run: - - - -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): - - - -### 2. Add Wrangler file - -Then, add a [Wrangler configuration file](/pages/functions/wrangler-configuration/) to the root directory of your Next.js app: - - - -```toml -name = "my-app" -compatibility_date = "2024-09-23" -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 title="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 allow 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 title="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: - - - -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. - - - -Once it is installed, add the following to `.eslintrc.json`: - -```diff title=".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/) diff --git a/src/content/docs/pages/framework-guides/nextjs/ssr/index.mdx b/src/content/docs/pages/framework-guides/nextjs/ssr/index.mdx deleted file mode 100644 index 5150ba088f3f2fd..000000000000000 --- a/src/content/docs/pages/framework-guides/nextjs/ssr/index.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- - -pcx_content_type: navigation -title: Full-stack (SSR) -sidebar: - order: 1 ---- - -import { DirectoryListing } from "~/components"; - -[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). - -:::note -You should consider using [`@opennextjs/cloudflare`](https://opennext.js.org/cloudflare), which allows you to build and deploy Next.js apps to [Cloudflare Workers](/workers/static-assets/), use [Node.js APIs](/workers/runtime-apis/nodejs/) that Cloudflare Workers supports, and supports additional Next.js features. - -If you're coming from Vercel, you can easily migrate your Next.js app to Cloudflare by using [Diverce](https://github.com/ygwyg/diverce), which will automatically add OpenNext to your project and create a pull request that makes it deployable to Cloudflare. -::: - - diff --git a/src/content/docs/pages/framework-guides/nextjs/ssr/static-assets.mdx b/src/content/docs/pages/framework-guides/nextjs/ssr/static-assets.mdx deleted file mode 100644 index 2454245a15506b8..000000000000000 --- a/src/content/docs/pages/framework-guides/nextjs/ssr/static-assets.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -pcx_content_type: reference -title: Routing static assets -head: - - tag: title - content: Routing static assets | Full-stack (SSR) | Next.js apps ---- - -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 title="_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. diff --git a/src/content/docs/pages/framework-guides/nextjs/ssr/supported-features.mdx b/src/content/docs/pages/framework-guides/nextjs/ssr/supported-features.mdx deleted file mode 100644 index 7858152f5a29d6b..000000000000000 --- a/src/content/docs/pages/framework-guides/nextjs/ssr/supported-features.mdx +++ /dev/null @@ -1,160 +0,0 @@ ---- -pcx_content_type: reference -title: Supported features -head: - - tag: title - content: Supported features ---- - -import { Details } from "~/components"; - -## Supported Next.js versions - -`@cloudflare/next-on-pages` supports all minor and patch version of Next.js 13 and 14. We regularly run manual and automated tests to ensure compatibility. - -### Node.js API support - -Next.js has [two "runtimes"](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) — "Edge" and "Node.js". - -The `@cloudflare/next-on-pages` adapter supports only the edge "runtime". - -The [`@opennextjs/cloudflare` adapter](https://opennext.js.org/cloudflare), which lets you build and deploy Next.js apps to [Cloudflare Workers](/workers/), supports the Node.js "runtime" from Next.js. When you use it, you can use the [full set of Node.js APIs](/workers/runtime-apis/nodejs/) that Cloudflare Workers provide. - -`@opennextjs/cloudflare` is pre 1.0, and still in active development. As it approaches 1.0, it will become the clearly better choice for most Next.js apps, since Next.js has been engineered to only support its Node.js "runtime" for many newly introduced features. - -Refer to the [OpenNext docs](https://opennext.js.org/cloudflare) and the [Workers vs. Pages compatibility matrix](/workers/static-assets/migration-guides/migrate-from-pages/#compatibility-matrix) for more information to help you decide which to use. - -#### Supported Node.js APIs when using `@cloudflare/next-on-pages` - -When you use `@cloudflare/next-on-pages`, your Next.js app must use the "edge" runtime from Next.js. The Workers runtime [supports a broad set of Node.js APIs](/workers/runtime-apis/nodejs/) — but [the Next.js Edge Runtime code intentionally constrains this](https://github.com/vercel/next.js/blob/canary/packages/next/src/build/webpack/plugins/middleware-plugin.ts#L820). As a result, only the following Node.js APIs will work in your Next.js app: - -- `buffer` -- `events` -- `assert` -- `util` -- `async_hooks` - -If you need to use other APIs from Node.js, you should use [`@opennextjs/cloudflare`](https://opennext.js.org/cloudflare) instead. - -## Supported Features - -### Routers - -Cloudflare recommends using the [App router](https://nextjs.org/docs/app) from Next.js. - -Cloudflare also supports the older [Pages](https://nextjs.org/docs/pages) router from Next.js. - -### next.config.mjs Properties - -[`next.config.js` — app router](https://nextjs.org/docs/app/api-reference/next-config-js) and [\`next.config.js - pages router](https://nextjs.org/docs/pages/api-reference/next-config-js) - -| Option | Next Docs | Support | -| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| appDir | [app](https://nextjs.org/docs/app/api-reference/next-config-js/appDir) | ✅ | -| assetPrefix | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/assetPrefix), [app](https://nextjs.org/docs/app/api-reference/next-config-js/assetPrefix) | 🔄 | -| basePath | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/basePath), [app](https://nextjs.org/docs/app/api-reference/next-config-js/basePath) | ✅ | -| compress | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/compress), [app](https://nextjs.org/docs/app/api-reference/next-config-js/compress) | `N/A`[^1] | -| devIndicators | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/devIndicators), [app](https://nextjs.org/docs/app/api-reference/next-config-js/devIndicators) | `N/A`[^2] | -| distDir | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/distDir), [app](https://nextjs.org/docs/app/api-reference/next-config-js/distDir) | `N/A`[^3] | -| env | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/env), [app](https://nextjs.org/docs/app/api-reference/next-config-js/env) | ✅ | -| eslint | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/eslint), [app](https://nextjs.org/docs/app/api-reference/next-config-js/eslint) | ✅ | -| exportPathMap | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/exportPathMap), [app](https://nextjs.org/docs/app/api-reference/next-config-js/exportPathMap) | `N/A`[^4] | -| generateBuildId | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/generateBuildId), [app](https://nextjs.org/docs/app/api-reference/next-config-js/generateBuildId) | ✅ | -| generateEtags | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/generateEtags), [app](https://nextjs.org/docs/app/api-reference/next-config-js/generateEtags) | 🔄 | -| headers | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/headers), [app](https://nextjs.org/docs/app/api-reference/next-config-js/headers) | ✅ | -| httpAgentOptions | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/httpAgentOptions), [app](https://nextjs.org/docs/app/api-reference/next-config-js/httpAgentOptions) | `N/A` | -| images | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/images), [app](https://nextjs.org/docs/app/api-reference/next-config-js/images) | ✅ | -| incrementalCacheHandlerPath | [app](https://nextjs.org/docs/app/api-reference/next-config-js/incrementalCacheHandlerPath) | 🔄 | -| logging | [app](https://nextjs.org/docs/app/api-reference/next-config-js/logging) | `N/A`[^5] | -| mdxRs | [app](https://nextjs.org/docs/app/api-reference/next-config-js/mdxRs) | ✅ | -| onDemandEntries | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/onDemandEntries), [app](https://nextjs.org/docs/app/api-reference/next-config-js/onDemandEntries) | `N/A`[^6] | -| optimizePackageImports | [app](https://nextjs.org/docs/app/api-reference/next-config-js/optimizePackageImports) | ✅/`N/A`[^7] | -| output | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/output), [app](https://nextjs.org/docs/app/api-reference/next-config-js/output) | `N/A`[^8] | -| pageExtensions | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/pageExtensions), [app](https://nextjs.org/docs/app/api-reference/next-config-js/pageExtensions) | ✅ | -| Partial Prerendering (experimental) | [app](https://nextjs.org/docs/app/api-reference/next-config-js/partial-prerendering) | ❌[^9] | -| poweredByHeader | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/poweredByHeader), [app](https://nextjs.org/docs/app/api-reference/next-config-js/poweredByHeader) | 🔄 | -| productionBrowserSourceMaps | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/productionBrowserSourceMaps), [app](https://nextjs.org/docs/app/api-reference/next-config-js/productionBrowserSourceMaps) | 🔄[^10] | -| reactStrictMode | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/reactStrictMode), [app](https://nextjs.org/docs/app/api-reference/next-config-js/reactStrictMode) | ❌[^11] | -| redirects | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/redirects), [app](https://nextjs.org/docs/app/api-reference/next-config-js/redirects) | ✅ | -| rewrites | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/rewrites), [app](https://nextjs.org/docs/app/api-reference/next-config-js/rewrites) | ✅ | -| Runtime Config | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/runtime-configuration), [app](https://nextjs.org/docs/app/api-reference/next-config-js/runtime-configuration) | ❌[^12] | -| serverActions | [app](https://nextjs.org/docs/app/api-reference/next-config-js/serverActions) | ✅ | -| serverComponentsExternalPackages | [app](https://nextjs.org/docs/app/api-reference/next-config-js/serverComponentsExternalPackages) | `N/A`[^13] | -| trailingSlash | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/trailingSlash), [app](https://nextjs.org/docs/app/api-reference/next-config-js/trailingSlash) | ✅ | -| transpilePackages | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/transpilePackages), [app](https://nextjs.org/docs/app/api-reference/next-config-js/transpilePackages) | ✅ | -| turbo | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/turbo), [app](https://nextjs.org/docs/app/api-reference/next-config-js/turbo) | 🔄 | -| typedRoutes | [app](https://nextjs.org/docs/app/api-reference/next-config-js/typedRoutes) | ✅ | -| typescript | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/typescript), [app](https://nextjs.org/docs/app/api-reference/next-config-js/typescript) | ✅ | -| urlImports | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/urlImports), [app](https://nextjs.org/docs/app/api-reference/next-config-js/urlImports) | ✅ | -| webpack | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/webpack), [app](https://nextjs.org/docs/app/api-reference/next-config-js/webpack) | ✅ | -| webVitalsAttribution | [pages](https://nextjs.org/docs/pages/api-reference/next-config-js/webVitalsAttribution), [app](https://nextjs.org/docs/app/api-reference/next-config-js/webVitalsAttribution) | ✅ | - -``` -- ✅: Supported -- 🔄: Not currently supported -- ❌: Not supported -- N/A: Not applicable -``` - -[^1]: **compression**: [Cloudflare applies Brotli or Gzip compression](/speed/optimization/content/compression/) automatically. When developing locally with Wrangler, no compression is applied. - -[^2]: **dev indicators**: If you're developing using `wrangler pages dev`, it hard refreshes your application the dev indicator doesn't appear. If you run your app locally using `next dev`, this option works fine. - -[^3]: **setting custom build directory**: Applications built using `@cloudflare/next-on-pages` don't rely on the `.next` directory so this option isn't really applicable (the `@cloudflare/next-on-pages` equivalent is to use the `--outdir` flag). - -[^4]: **exportPathMap**: Option used for SSG not applicable for apps built using `@cloudflare/next-on-pages`. - -[^5]: **logging**: If you're developing using `wrangler pages dev`, the extra logging is not applied (since you are effectively running a production build). If you run your app locally using `next dev`, this option works fine. - -[^6]: **onDemandEntries**: Not applicable since it's an option for the Next.js server during development which we don't rely on. - -[^7]: **optimizePackageImports**: `@cloudflare/next-on-pages` performs chunks deduplication and provides an implementation based on modules lazy loading, based on this applying an `optimizePackageImports` doesn't have an impact on the output produced by the CLI. This configuration can still however be used to speed up the build process (both when running `next dev` or when generating a production build). - -[^8]: **output**: `@cloudflare/next-on-pages` works with the standard Next.js output, `standalone` is incompatible with it, `export` is used to generate a static site which doesn't need `@cloudflare/next-on-pages` to run. - -[^9]: **Partial Prerendering (experimental)**: As presented in the official [Next.js documentation](https://nextjs.org/docs/app/api-reference/next-config-js/partial-prerendering): `Partial Prerendering is designed for the Node.js runtime only.`, as such it is fundamentally incompatibly with `@cloudflare/next-on-pages` (which only works on the edge runtime). - -[^10]: **productionBrowserSourceMaps**: The webpack chunks deduplication performed by `@cloudflare/next-on-pages` doesn't currently preserve source maps in any case so this option can't be implemented either. In the future we might try to preserver source maps, in such case it should be simple to also support this option. - -[^11]: **reactStrictMode**: Currently we build the application so react strict mode (being a local dev feature) doesn't work either way. If we can make strict mode work, this option will most likely work straight away. - -[^12]: **runtime configuration**: We could look into implementing the runtime configuration but it is probably not worth it since it is a legacy configuration and environment variables should be used instead. - -[^13]: **serverComponentsExternalPackages**: This option is for applications running on Node.js so it's not relevant to applications running on Cloudflare Pages. - -### Internationalization - -Cloudflare also supports Next.js' [internationalized (`i18n`) routing](https://nextjs.org/docs/pages/building-your-application/routing/internationalization). - -### Rendering and Data Fetching - -#### Incremental Static Regeneration - -If you use Incremental Static Regeneration (ISR)[^14], `@cloudflare/next-on-pages` will use static fallback files that are generated by the build process. - -This means that your application will still correctly serve your ISR/prerendered pages (but without the regeneration aspect). If this causes issues for your application, change your pages to use server side rendering (SSR) instead. - -
- -ISR pages are built by the Vercel CLI to generate Vercel [Prerender Functions](https://vercel.com/docs/build-output-api/v3/primitives#prerender-functions). These are Node.js serverless functions that can be called in the background while serving the page from the cache. - -It is not possible to use these with Cloudflare Pages and they are not compatible with the [edge runtime](https://nextjs.org/docs/app/api-reference/edge) currently. - -
- -[^14]: [Incremental Static Regeneration (ISR)](https://vercel.com/docs/incremental-static-regeneration) is a rendering mode in Next.js that allows you to automatically cache and periodically regenerate pages with fresh data. - -#### Dynamic handling of static routes - -`@cloudflare/next-on-pages` supports standard statically generated routes. - -It does not support dynamic Node.js-based on-demand handling of such routes. - -For more details see: - -- [troubleshooting `generateStaticParams`](/pages/framework-guides/nextjs/ssr/troubleshooting/#generatestaticparams) -- [troubleshooting `getStaticPaths` ](/pages/framework-guides/nextjs/ssr/troubleshooting/#getstaticpaths) - -#### Caching and Data Revalidation - -Revalidation and `next/cache` are supported on Cloudflare Pages and can use various bindings. For more information, see our [caching documentation](/pages/framework-guides/nextjs/ssr/caching/). diff --git a/src/content/docs/pages/framework-guides/nextjs/ssr/troubleshooting.mdx b/src/content/docs/pages/framework-guides/nextjs/ssr/troubleshooting.mdx deleted file mode 100644 index 44163e1b2527ebc..000000000000000 --- a/src/content/docs/pages/framework-guides/nextjs/ssr/troubleshooting.mdx +++ /dev/null @@ -1,115 +0,0 @@ ---- -pcx_content_type: troubleshooting -title: Troubleshooting -head: - - tag: title - content: Troubleshooting | Full-stack (SSR) | Next.js apps ---- - -Learn more about troubleshooting issues with your Full-stack (SSR) Next.js apps using Cloudflare. - -## Edge runtime - -You must configure all server-side routes in your Next.js project as [Edge runtime](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) routes, by adding the following to each route: - -```js -export const runtime = "edge"; -``` - -:::note - -If you are still using the Next.js [Pages router](https://nextjs.org/docs/pages), for page routes, you must use `'experimental-edge'` instead of `'edge'`. -::: - ---- - -## App router - -### Not found - -Next.js generates a `not-found` route for your application under the hood during the build process. In some circumstances, Next.js can detect that the route requires server-side logic (particularly if computation is being performed in the root layout component) and Next.js automatically creates a [Node.js runtime serverless function](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) that is not compatible with Cloudflare Pages. - -To prevent this, you can provide a custom `not-found` route that explicitly uses the edge runtime: - -```ts -export const runtime = 'edge' - -export default async function NotFound() { - // ... - return ( - // ... - ) -} -``` - -### `generateStaticParams` - -When you use [static site generation (SSG)](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation) in the [`/app` directory](https://nextjs.org/docs/getting-started/project-structure) and also use the [`generateStaticParams`](https://nextjs.org/docs/app/api-reference/functions/generate-static-params) function, Next.js tries to handle requests for non statically generated routes automatically, and creates a [Node.js runtime serverless function](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) that is not compatible with Cloudflare Pages. - -You can opt out of this behavior by setting [`dynamicParams`](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams) to `false`: - -```diff -+ export const dynamicParams = false - -// ... -``` - -### Top-level `getRequestContext` - -You must call `getRequestContext` within the function that handles your route — it cannot be called in global scope. - -Don't do this: - -```js null {5} -import { getRequestContext } from "@cloudflare/next-on-pages"; - -export const runtime = "edge"; - -const myVariable = getRequestContext().env.MY_VARIABLE; - -export async function GET(request) { - return new Response(myVariable); -} -``` - -Instead, do this: - -```js null {6} -import { getRequestContext } from "@cloudflare/next-on-pages"; - -export const runtime = "edge"; - -export async function GET(request) { - const myVariable = getRequestContext().env.MY_VARIABLE; - return new Response(myVariable); -} -``` - ---- - -## Pages router - -### `getStaticPaths` - -When you use [static site generation (SSG)](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation) in the [`/pages` directory](https://nextjs.org/docs/getting-started/project-structure) and also use the [`getStaticPaths`](https://nextjs.org/docs/pages/api-reference/functions/get-static-paths) function, Next.js by default tries to handle requests for non statically generated routes automatically, and creates a [Node.js runtime serverless function](https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) that is not compatible with Cloudflare Pages. - -You can opt out of this behavior by specifying a [false `fallback`](https://nextjs.org/docs/pages/api-reference/functions/get-static-paths#fallback-false): - -```diff -// ... - -export async function getStaticPaths() { - // ... - - return { - paths, -+ fallback: false, - } -} -``` - -:::caution - -Note that the `paths` array cannot be empty since an empty `paths` array causes Next.js to ignore the provided `fallback` value. - -:::