Skip to content

Commit 62528e8

Browse files
ovflowdclaude
andcommitted
refactor(platform): relocate deploy-target apps under platforms/
Move apps/{vercel,cloudflare} to platforms/{vercel,cloudflare} and apps/site/vercel.json to platforms/vercel/vercel.json. Rebase all relative path references across workflows, CODEOWNERS, docs, and configs so tooling resolves from the new locations. vercel.json now declares outputDirectory (../../apps/site/.next) so Vercel can find the Next.js build when its Root Directory is set to platforms/vercel, and uses build.env for NEXT_PUBLIC_DEPLOY_TARGET and NODE_OPTIONS=--conditions=vercel instead of cross-env (which is not in the --prod install tree). Add NEXT_PUBLIC_DEPLOY_TARGET and NODE_OPTIONS=--conditions=cloudflare to the Cloudflare deploy workflow's build and deploy step env blocks so the outer opennextjs-cloudflare process resolves imports under the cloudflare condition (matching the Playwright workflow). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent ecf659d commit 62528e8

27 files changed

Lines changed: 146 additions & 141 deletions

.github/CODEOWNERS

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ turbo.json @nodejs/nodejs-website @nodejs/web-infra
2727
crowdin.yml @nodejs/web-infra
2828
apps/site/redirects.json @nodejs/web-infra
2929
apps/site/site.json @nodejs/web-infra
30-
apps/cloudflare/wrangler.jsonc @nodejs/web-infra
31-
apps/cloudflare/open-next.config.ts @nodejs/web-infra
32-
apps/cloudflare/next.platform.config.mjs @nodejs/web-infra
33-
apps/vercel/next.platform.config.mjs @nodejs/web-infra
30+
platforms/cloudflare/wrangler.jsonc @nodejs/web-infra
31+
platforms/cloudflare/open-next.config.ts @nodejs/web-infra
32+
platforms/cloudflare/next.platform.config.mjs @nodejs/web-infra
33+
platforms/vercel/vercel.json @nodejs/web-infra
34+
platforms/vercel/next.platform.config.mjs @nodejs/web-infra
3435
apps/site/redirects.json @nodejs/web-infra
3536

3637
# Critical Documents

.github/workflows/playwright-cloudflare-open-next.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ jobs:
5151
run: node_modules/.bin/playwright install --with-deps
5252

5353
- name: Build open-next site
54-
working-directory: apps/cloudflare
54+
working-directory: platforms/cloudflare
5555
run: node --run cloudflare:build:worker
5656
env:
5757
NEXT_PUBLIC_DEPLOY_TARGET: cloudflare

.github/workflows/tmp-cloudflare-open-next-deploy.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,18 @@ jobs:
5757
run: node --run build:blog-data
5858

5959
- name: Build open-next site
60-
working-directory: apps/cloudflare
60+
working-directory: platforms/cloudflare
6161
run: node --run cloudflare:build:worker
62+
env:
63+
NEXT_PUBLIC_DEPLOY_TARGET: cloudflare
64+
NODE_OPTIONS: --conditions=cloudflare
6265

6366
- name: Deploy open-next site
64-
working-directory: apps/cloudflare
67+
working-directory: platforms/cloudflare
6568
run: node --run cloudflare:deploy
6669
env:
70+
NEXT_PUBLIC_DEPLOY_TARGET: cloudflare
71+
NODE_OPTIONS: --conditions=cloudflare
6772
CF_WORKERS_SCRIPTS_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
6873
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
6974
CLOUDFLARE_ACCOUNT_ID: fb4a2d0f103c6ff38854ac69eb709272

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ dist/
4343
# Cloudflare Build Output
4444
apps/site/.open-next
4545
apps/site/.wrangler
46-
apps/cloudflare/.wrangler
46+
platforms/cloudflare/.wrangler
4747

4848
## Playwright
4949
test-results

apps/vercel/__tests__/next.platform.config.test.mjs

Lines changed: 0 additions & 13 deletions
This file was deleted.

docs/cloudflare-build-and-deployment.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
The Node.js Website can be built using the [OpenNext Cloudflare adapter](https://opennext.js.org/cloudflare). Such build generates a [Cloudflare Worker](https://www.cloudflare.com/en-gb/developer-platform/products/workers/) that can be deployed on the [Cloudflare](https://www.cloudflare.com) network.
44

5-
The build is gated on the `NEXT_PUBLIC_DEPLOY_TARGET=cloudflare` environment variable (set by the OpenNext `buildCommand`), which makes `apps/site` pull its Next.js, MDX, image-loader, and analytics overrides from [`@node-core/platform-cloudflare`](../apps/cloudflare). See the [Deploy Target Selection](./technologies.md#deploy-target-selection-next_public_deploy_target) section of the Technologies document for the full platform-adapter contract.
5+
The build is gated on the `NEXT_PUBLIC_DEPLOY_TARGET=cloudflare` environment variable (set by the OpenNext `buildCommand`), which makes `apps/site` pull its Next.js, MDX, image-loader, and analytics overrides from [`@node-core/platform-cloudflare`](../platforms/cloudflare). See the [Deploy Target Selection](./technologies.md#deploy-target-selection-next_public_deploy_target) section of the Technologies document for the full platform-adapter contract.
66

77
## Configurations
88

9-
All Cloudflare-specific configuration lives in the [`@node-core/platform-cloudflare`](../apps/cloudflare) package. The two key configuration files are:
9+
All Cloudflare-specific configuration lives in the [`@node-core/platform-cloudflare`](../platforms/cloudflare) package. The two key configuration files are:
1010

11-
- [`apps/cloudflare/wrangler.jsonc`](../apps/cloudflare/wrangler.jsonc) — the Wrangler configuration
12-
- [`apps/cloudflare/open-next.config.ts`](../apps/cloudflare/open-next.config.ts) — the OpenNext adapter configuration
11+
- [`platforms/cloudflare/wrangler.jsonc`](../platforms/cloudflare/wrangler.jsonc) — the Wrangler configuration
12+
- [`platforms/cloudflare/open-next.config.ts`](../platforms/cloudflare/open-next.config.ts) — the OpenNext adapter configuration
1313

1414
### Wrangler Configuration
1515

@@ -19,7 +19,7 @@ For more details, refer to the [Wrangler documentation](https://developers.cloud
1919

2020
Key configurations include:
2121

22-
- `main`: Points to a custom worker entry point ([`apps/cloudflare/src/worker-entrypoint.ts`](../apps/cloudflare/src/worker-entrypoint.ts)) that wraps the OpenNext-generated worker (see [Custom Worker Entry Point](#custom-worker-entry-point) and [Sentry](#sentry) below).
22+
- `main`: Points to a custom worker entry point ([`platforms/cloudflare/src/worker-entrypoint.ts`](../platforms/cloudflare/src/worker-entrypoint.ts)) that wraps the OpenNext-generated worker (see [Custom Worker Entry Point](#custom-worker-entry-point) and [Sentry](#sentry) below).
2323
- `account_id`: Specifies the Cloudflare account ID. This is not required for local previews but is necessary for deployments. You can obtain an account ID for free by signing up at [dash.cloudflare.com](https://dash.cloudflare.com/login).
2424
- This is currently set to `fb4a2d0f103c6ff38854ac69eb709272`, which is the ID of a Cloudflare account controlled by Node.js, and used for testing.
2525
- `build`: Defines the build command to generate the Node.js filesystem polyfills required for the application to run on Cloudflare Workers. This uses the [`@flarelabs/wrangler-build-time-fs-assets-polyfilling`](https://github.com/flarelabs-net/wrangler-build-time-fs-assets-polyfilling) package.
@@ -54,15 +54,15 @@ Additionally, when deploying, an extra `CF_WORKERS_SCRIPTS_API_TOKEN` environmen
5454

5555
### Image loader
5656

57-
When deployed on the Cloudflare network a custom image loader is required. The Cloudflare platform config ([`apps/cloudflare/next.platform.config.mjs`](../apps/cloudflare/next.platform.config.mjs)) contributes it via the `images.loaderFile` field, which is merged into the shared Next.js config when `NEXT_PUBLIC_DEPLOY_TARGET=cloudflare` (the variable is set by the OpenNext `buildCommand` in [`open-next.config.ts`](../apps/cloudflare/open-next.config.ts)).
57+
When deployed on the Cloudflare network a custom image loader is required. The Cloudflare platform config ([`platforms/cloudflare/next.platform.config.mjs`](../platforms/cloudflare/next.platform.config.mjs)) contributes it via the `images.loaderFile` field, which is merged into the shared Next.js config when `NEXT_PUBLIC_DEPLOY_TARGET=cloudflare` (the variable is set by the OpenNext `buildCommand` in [`open-next.config.ts`](../platforms/cloudflare/open-next.config.ts)).
5858

59-
The custom loader can be found at [`apps/cloudflare/src/image-loader.ts`](../apps/cloudflare/src/image-loader.ts).
59+
The custom loader can be found at [`platforms/cloudflare/src/image-loader.ts`](../platforms/cloudflare/src/image-loader.ts).
6060

6161
For more details on this see: https://developers.cloudflare.com/images/transform-images/integrate-with-frameworks/#global-loader
6262

6363
### Custom Worker Entry Point
6464

65-
Instead of directly using the OpenNext-generated worker (`.open-next/worker.js`), the application uses a custom worker entry point at [`apps/cloudflare/src/worker-entrypoint.ts`](../apps/cloudflare/src/worker-entrypoint.ts). This allows customizing the worker's behavior before requests are handled (currently used to integrate [Sentry](#sentry) error monitoring).
65+
Instead of directly using the OpenNext-generated worker (`.open-next/worker.js`), the application uses a custom worker entry point at [`platforms/cloudflare/src/worker-entrypoint.ts`](../platforms/cloudflare/src/worker-entrypoint.ts). This allows customizing the worker's behavior before requests are handled (currently used to integrate [Sentry](#sentry) error monitoring).
6666

6767
The custom entry point imports the OpenNext-generated handler from `.open-next/worker.js` and re-exports the `DOQueueHandler` Durable Object needed by the application.
6868

docs/technologies.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,25 +302,25 @@ Benefits:
302302

303303
`NEXT_PUBLIC_DEPLOY_TARGET` selects which platform adapter contributes its Next.js config, MDX flags, image loader, analytics, and Playwright webServer. It is consumed at build time by [`apps/site/next.config.mjs`](../apps/site/next.config.mjs), [`apps/site/mdx/plugins.mjs`](../apps/site/mdx/plugins.mjs), and [`apps/site/playwright.config.ts`](../apps/site/playwright.config.ts) via a dynamic import of `@node-core/platform-${target}/next.platform.config`.
304304

305-
| Value | Adapter | Set by |
306-
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
307-
| `vercel` | [`@node-core/platform-vercel`](../apps/vercel) | [`apps/site/vercel.json`](../apps/site/vercel.json) build env |
308-
| `cloudflare` | [`@node-core/platform-cloudflare`](../apps/cloudflare) | OpenNext `buildCommand` in [`open-next.config.ts`](../apps/cloudflare/open-next.config.ts) |
309-
| _(unset)_ | Falls back to the no-op defaults in [`apps/site/next.platform.config.mjs`](../apps/site/next.platform.config.mjs) and [`apps/site/playwright.platform.config.mjs`](../apps/site/playwright.platform.config.mjs) | Plain `pnpm dev` / `pnpm build` / `pnpm deploy` |
305+
| Value | Adapter | Set by |
306+
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
307+
| `vercel` | [`@node-core/platform-vercel`](../platforms/vercel) | [`platforms/vercel/vercel.json`](../platforms/vercel/vercel.json) build env |
308+
| `cloudflare` | [`@node-core/platform-cloudflare`](../platforms/cloudflare) | OpenNext `buildCommand` in [`open-next.config.ts`](../platforms/cloudflare/open-next.config.ts) |
309+
| _(unset)_ | Falls back to the no-op defaults in [`apps/site/next.platform.config.mjs`](../apps/site/next.platform.config.mjs) and [`apps/site/playwright.platform.config.mjs`](../apps/site/playwright.platform.config.mjs) | Plain `pnpm dev` / `pnpm build` / `pnpm deploy` |
310310

311-
Each adapter exports a default `{ nextConfig, aliases, images, mdx }` shape (any field optional). See [`apps/vercel/next.platform.config.mjs`](../apps/vercel/next.platform.config.mjs) and [`apps/cloudflare/next.platform.config.mjs`](../apps/cloudflare/next.platform.config.mjs) for reference.
311+
Each adapter exports a default `{ nextConfig, aliases, images, mdx }` shape (any field optional). See [`platforms/vercel/next.platform.config.mjs`](../platforms/vercel/next.platform.config.mjs) and [`platforms/cloudflare/next.platform.config.mjs`](../platforms/cloudflare/next.platform.config.mjs) for reference.
312312

313313
#### Vercel Integration
314314

315315
- Automatic deployments for branches (ignoring automated branches)
316-
- Custom install + ignore scripts ([see `vercel.json`](../apps/site/vercel.json))
316+
- Custom install + ignore scripts ([see `vercel.json`](../platforms/vercel/vercel.json))
317317
- Build-time dependencies must be in `dependencies`, not `devDependencies`
318318
- Sponsorship maintained by OpenJS Foundation
319319

320320
#### Cloudflare Integration
321321

322322
- OpenNext adapter builds a [Cloudflare Worker](https://www.cloudflare.com/en-gb/developer-platform/products/workers/) artifact from the Next.js build
323-
- All Cloudflare-specific files (Wrangler config, OpenNext config, custom worker entrypoint, image loader) live in [`apps/cloudflare`](../apps/cloudflare)
323+
- All Cloudflare-specific files (Wrangler config, OpenNext config, custom worker entrypoint, image loader) live in [`platforms/cloudflare`](../platforms/cloudflare)
324324
- See [Cloudflare build and deployment](./cloudflare-build-and-deployment.md) for details
325325

326326
### Package Management

apps/cloudflare/next.platform.config.mjs renamed to platforms/cloudflare/next.platform.config.mjs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* `apps/site/mdx/plugins.mjs` reads `.mdx` — never drags them into the
99
* worker runtime.
1010
*
11-
* @type {import('../site/next.platform.config').PlatformConfig}
11+
* @type {import('../../apps/site/next.platform.config').PlatformConfig}
1212
*/
1313
export default {
1414
aliases: {
@@ -25,16 +25,19 @@ export default {
2525
},
2626
nextConfig: async () => {
2727
const { getDeploymentId } = await import('@opennextjs/cloudflare');
28+
2829
return {
2930
// Skew protection: Cloudflare routes requests by deploymentId so that
3031
// a client and the worker stay in sync across rolling deploys.
31-
deploymentId: await getDeploymentId(),
32+
deploymentId: getDeploymentId(),
3233
};
3334
},
3435
images: async () => {
3536
const { createRequire } = await import('node:module');
3637
const { relative } = await import('node:path');
38+
3739
const require = createRequire(import.meta.url);
40+
3841
return {
3942
// Route optimized images through Cloudflare's Images service via the
4043
// custom loader. `remotePatterns` do NOT apply here — Cloudflare
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
"repository": {
1515
"type": "git",
1616
"url": "https://github.com/nodejs/nodejs.org",
17-
"directory": "apps/cloudflare"
17+
"directory": "platforms/cloudflare"
1818
},
1919
"scripts": {
20-
"cloudflare:build:worker": "pnpm --filter=@node-core/website exec opennextjs-cloudflare build --openNextConfigPath ../cloudflare/open-next.config.ts --config ../cloudflare/wrangler.jsonc",
21-
"cloudflare:deploy": "pnpm --filter=@node-core/website exec opennextjs-cloudflare deploy --openNextConfigPath ../cloudflare/open-next.config.ts --config ../cloudflare/wrangler.jsonc",
22-
"cloudflare:preview": "pnpm --filter=@node-core/website exec wrangler dev --config ../cloudflare/wrangler.jsonc",
20+
"cloudflare:build:worker": "pnpm --filter=@node-core/website exec opennextjs-cloudflare build --openNextConfigPath ../../platforms/cloudflare/open-next.config.ts --config ../../platforms/cloudflare/wrangler.jsonc",
21+
"cloudflare:deploy": "pnpm --filter=@node-core/website exec opennextjs-cloudflare deploy --openNextConfigPath ../../platforms/cloudflare/open-next.config.ts --config ../../platforms/cloudflare/wrangler.jsonc",
22+
"cloudflare:preview": "pnpm --filter=@node-core/website exec wrangler dev --config ../../platforms/cloudflare/wrangler.jsonc",
2323
"lint:types": "tsc --noEmit"
2424
},
2525
"dependencies": {

0 commit comments

Comments
 (0)