@netlify/plugin-nextjs 4.16.0 → 4.17.1-runtime.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@ const findDistDir = (publish) => {
9
9
  if (!(0, utils_1.shouldSkip)()) {
10
10
  return publish;
11
11
  }
12
- // In this situation, the user has disabled the plugin, which means that they might be using next export,
12
+ // In this situation, the user has disabled the next-runtime, which means that they might be using next export,
13
13
  // so we'll look in a few places to find the site root. This allows us to find the .next directory.
14
14
  for (const root of [(0, path_1.resolve)(publish, '..'), (0, path_1.resolve)(publish, '..', '..')]) {
15
15
  if ((0, fs_1.existsSync)((0, path_1.join)(root, 'next.config.js'))) {
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.onPreDev = void 0;
7
+ const path_1 = require("path");
8
+ const execa_1 = __importDefault(require("execa"));
9
+ const fs_extra_1 = require("fs-extra");
10
+ const edge_1 = require("./edge");
11
+ const files_1 = require("./files");
12
+ // The types haven't been updated yet
13
+ const onPreDev = async ({ constants, netlifyConfig }) => {
14
+ var _a;
15
+ const base = (_a = netlifyConfig.build.base) !== null && _a !== void 0 ? _a : process.cwd();
16
+ // Need to patch the files, because build might not have been run
17
+ await (0, files_1.patchNextFiles)(base);
18
+ // Clean up old functions
19
+ await (0, fs_extra_1.unlink)((0, path_1.resolve)('.netlify', 'middleware.js')).catch(() => {
20
+ // Ignore if it doesn't exist
21
+ });
22
+ await (0, edge_1.writeDevEdgeFunction)(constants);
23
+ if (!(0, fs_extra_1.existsSync)((0, path_1.resolve)(base, 'middleware.ts')) && !(0, fs_extra_1.existsSync)((0, path_1.resolve)(base, 'middleware.js'))) {
24
+ console.log("No middleware found. Create a 'middleware.ts' or 'middleware.js' file in your project root to add custom middleware.");
25
+ }
26
+ else {
27
+ console.log('Watching for changes in Next.js middleware...');
28
+ }
29
+ // Eventually we might want to do this via esbuild's API, but for now the CLI works fine
30
+ const childProcess = (0, execa_1.default)(`esbuild`, [
31
+ `--bundle`,
32
+ `--outdir=${(0, path_1.resolve)('.netlify')}`,
33
+ `--format=esm`,
34
+ '--watch',
35
+ // Watch for both, because it can have either ts or js
36
+ (0, path_1.resolve)(base, 'middleware.ts'),
37
+ (0, path_1.resolve)(base, 'middleware.js'),
38
+ ]);
39
+ childProcess.stdout.pipe(process.stdout);
40
+ childProcess.stderr.pipe(process.stderr);
41
+ // Don't return the promise because we don't want to wait for the child process to finish
42
+ };
43
+ exports.onPreDev = onPreDev;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateConfig = exports.writeEdgeFunctions = exports.loadMiddlewareManifest = void 0;
3
+ exports.enableEdgeInNextConfig = exports.writeEdgeFunctions = exports.writeDevEdgeFunction = exports.loadMiddlewareManifest = void 0;
4
4
  /* eslint-disable max-lines */
5
5
  const fs_1 = require("fs");
6
6
  const path_1 = require("path");
@@ -67,6 +67,25 @@ const writeEdgeFunction = async ({ edgeFunctionDefinition, edgeFunctionRoot, net
67
67
  pattern: stripLookahead(edgeFunctionDefinition.regexp),
68
68
  };
69
69
  };
70
+ const writeDevEdgeFunction = async ({ INTERNAL_EDGE_FUNCTIONS_SRC = '.netlify/edge-functions', }) => {
71
+ const manifest = {
72
+ functions: [
73
+ {
74
+ function: 'next-dev',
75
+ path: '/*',
76
+ },
77
+ ],
78
+ version: 1,
79
+ };
80
+ const edgeFunctionRoot = (0, path_1.resolve)(INTERNAL_EDGE_FUNCTIONS_SRC);
81
+ await (0, fs_extra_1.emptyDir)(edgeFunctionRoot);
82
+ await (0, fs_extra_1.writeJson)((0, path_1.join)(edgeFunctionRoot, 'manifest.json'), manifest);
83
+ const edgeFunctionDir = (0, path_1.join)(edgeFunctionRoot, 'next-dev');
84
+ await (0, fs_extra_1.ensureDir)(edgeFunctionDir);
85
+ await copyEdgeSourceFile({ edgeFunctionDir, file: 'next-dev.js', target: 'index.js' });
86
+ await copyEdgeSourceFile({ edgeFunctionDir, file: 'utils.ts' });
87
+ };
88
+ exports.writeDevEdgeFunction = writeDevEdgeFunction;
70
89
  /**
71
90
  * Writes Edge Functions for the Next middleware
72
91
  */
@@ -78,9 +97,7 @@ const writeEdgeFunctions = async (netlifyConfig) => {
78
97
  const edgeFunctionRoot = (0, path_1.resolve)('.netlify', 'edge-functions');
79
98
  await (0, fs_extra_1.emptyDir)(edgeFunctionRoot);
80
99
  if (!process.env.NEXT_DISABLE_EDGE_IMAGES) {
81
- if (!process.env.NEXT_USE_NETLIFY_EDGE) {
82
- console.log('Using Netlify Edge Functions for image format detection. Set env var "NEXT_DISABLE_EDGE_IMAGES=true" to disable.');
83
- }
100
+ console.log('Using Netlify Edge Functions for image format detection. Set env var "NEXT_DISABLE_EDGE_IMAGES=true" to disable.');
84
101
  const edgeFunctionDir = (0, path_1.join)(edgeFunctionRoot, 'ipx');
85
102
  await (0, fs_extra_1.ensureDir)(edgeFunctionDir);
86
103
  await copyEdgeSourceFile({ edgeFunctionDir, file: 'ipx.ts', target: 'index.ts' });
@@ -90,7 +107,7 @@ const writeEdgeFunctions = async (netlifyConfig) => {
90
107
  path: '/_next/image*',
91
108
  });
92
109
  }
93
- if (process.env.NEXT_USE_NETLIFY_EDGE) {
110
+ if (!process.env.NEXT_DISABLE_NETLIFY_EDGE) {
94
111
  const middlewareManifest = await (0, exports.loadMiddlewareManifest)(netlifyConfig);
95
112
  if (!middlewareManifest) {
96
113
  console.error("Couldn't find the middleware manifest");
@@ -121,11 +138,10 @@ const writeEdgeFunctions = async (netlifyConfig) => {
121
138
  await (0, fs_extra_1.writeJson)((0, path_1.join)(edgeFunctionRoot, 'manifest.json'), manifest);
122
139
  };
123
140
  exports.writeEdgeFunctions = writeEdgeFunctions;
124
- const updateConfig = async (publish) => {
141
+ const enableEdgeInNextConfig = async (publish) => {
125
142
  const configFile = (0, path_1.join)(publish, 'required-server-files.json');
126
143
  const config = await (0, fs_extra_1.readJSON)(configFile);
127
- config.config.env.NEXT_USE_NETLIFY_EDGE = 'true';
128
144
  await (0, fs_extra_1.writeJSON)(configFile, config);
129
145
  };
130
- exports.updateConfig = updateConfig;
146
+ exports.enableEdgeInNextConfig = enableEdgeInNextConfig;
131
147
  /* eslint-enable max-lines */
@@ -54,7 +54,7 @@ const matchesRewrite = (file, rewrites) => {
54
54
  exports.matchesRewrite = matchesRewrite;
55
55
  const getMiddleware = async (publish) => {
56
56
  var _a;
57
- if (process.env.NEXT_USE_NETLIFY_EDGE) {
57
+ if (!process.env.NEXT_DISABLE_NETLIFY_EDGE) {
58
58
  return [];
59
59
  }
60
60
  const manifestPath = (0, pathe_1.join)(publish, 'server', 'middleware-manifest.json');
@@ -276,19 +276,19 @@ const baseServerReplacements = [
276
276
  const nextServerReplacements = [
277
277
  [
278
278
  `getMiddlewareManifest() {\n if (this.minimalMode) return null;`,
279
- `getMiddlewareManifest() {\n if (this.minimalMode || process.env.NEXT_USE_NETLIFY_EDGE) return null;`,
279
+ `getMiddlewareManifest() {\n if (this.minimalMode || !process.env.NEXT_DISABLE_NETLIFY_EDGE) return null;`,
280
280
  ],
281
281
  [
282
282
  `generateCatchAllMiddlewareRoute(devReady) {\n if (this.minimalMode) return []`,
283
- `generateCatchAllMiddlewareRoute(devReady) {\n if (this.minimalMode || process.env.NEXT_USE_NETLIFY_EDGE) return [];`,
283
+ `generateCatchAllMiddlewareRoute(devReady) {\n if (this.minimalMode || !process.env.NEXT_DISABLE_NETLIFY_EDGE) return [];`,
284
284
  ],
285
285
  [
286
286
  `generateCatchAllMiddlewareRoute() {\n if (this.minimalMode) return undefined;`,
287
- `generateCatchAllMiddlewareRoute() {\n if (this.minimalMode || process.env.NEXT_USE_NETLIFY_EDGE) return undefined;`,
287
+ `generateCatchAllMiddlewareRoute() {\n if (this.minimalMode || !process.env.NEXT_DISABLE_NETLIFY_EDGE) return undefined;`,
288
288
  ],
289
289
  [
290
290
  `getMiddlewareManifest() {\n if (this.minimalMode) {`,
291
- `getMiddlewareManifest() {\n if (!this.minimalMode && !process.env.NEXT_USE_NETLIFY_EDGE) {`,
291
+ `getMiddlewareManifest() {\n if (!this.minimalMode && process.env.NEXT_DISABLE_NETLIFY_EDGE) {`,
292
292
  ],
293
293
  ];
294
294
  const patchNextFiles = async (root) => {
@@ -136,7 +136,7 @@ const findModuleFromBase = ({ paths, candidates }) => {
136
136
  exports.findModuleFromBase = findModuleFromBase;
137
137
  const isNextAuthInstalled = () => {
138
138
  try {
139
- // eslint-disable-next-line import/no-unassigned-import, import/no-unresolved, n/no-missing-require
139
+ // eslint-disable-next-line import/no-unassigned-import, import/no-extraneous-dependencies, n/no-extraneous-require
140
140
  require('next-auth');
141
141
  return true;
142
142
  }
@@ -42,7 +42,7 @@ const verifyNetlifyBuildVersion = ({ IS_LOCAL, NETLIFY_BUILD_VERSION, failBuild,
42
42
  // We check for build version because that's what's available to us, but prompt about the cli because that's what they can upgrade
43
43
  if (IS_LOCAL && !(0, semver_1.satisfies)(NETLIFY_BUILD_VERSION, REQUIRED_BUILD_VERSION, { includePrerelease: true })) {
44
44
  return failBuild((0, outdent_1.outdent) `
45
- This version of the Essential Next.js plugin requires netlify-cli@6.12.4 or higher. Please upgrade and try again.
45
+ This version of the Next Runtime requires netlify-cli@6.12.4 or higher. Please upgrade and try again.
46
46
  You can do this by running: "npm install -g netlify-cli@latest" or "yarn global add netlify-cli@latest"
47
47
  `);
48
48
  }
@@ -136,7 +136,7 @@ exports.checkZipSize = checkZipSize;
136
136
  const getProblematicUserRewrites = ({ redirects, basePath, }) => {
137
137
  const userRewrites = [];
138
138
  for (const redirect of redirects) {
139
- // This is the first of the plugin-generated redirects so we can stop checking
139
+ // This is the first of the runtime-generated redirects so we can stop checking
140
140
  if (redirect.from === `${basePath}/_next/static/*` && redirect.to === `/static/:splat` && redirect.status === 200) {
141
141
  break;
142
142
  }
@@ -159,7 +159,7 @@ const warnForProblematicUserRewrites = ({ redirects, basePath, }) => {
159
159
  return;
160
160
  }
161
161
  console.log((0, chalk_1.yellowBright)((0, outdent_1.outdent) `
162
- You have the following Netlify rewrite${userRewrites.length === 1 ? '' : 's'} that might cause conflicts with the Next.js plugin:
162
+ You have the following Netlify rewrite${userRewrites.length === 1 ? '' : 's'} that might cause conflicts with the Next.js Runtime:
163
163
 
164
164
  ${(0, chalk_1.reset)(userRewrites.map(({ from, to, status }) => `- ${from} ${to} ${status}`).join('\n'))}
165
165
 
package/lib/index.js CHANGED
@@ -8,6 +8,7 @@ const outdent_1 = require("outdent");
8
8
  const constants_1 = require("./constants");
9
9
  const cache_1 = require("./helpers/cache");
10
10
  const config_1 = require("./helpers/config");
11
+ const dev_1 = require("./helpers/dev");
11
12
  const edge_1 = require("./helpers/edge");
12
13
  const files_1 = require("./helpers/files");
13
14
  const functions_1 = require("./helpers/functions");
@@ -20,7 +21,7 @@ const plugin = {
20
21
  const { publish } = netlifyConfig.build;
21
22
  if ((0, utils_1.shouldSkip)()) {
22
23
  await (0, cache_1.restoreCache)({ cache, publish });
23
- console.log('Not running Essential Next.js plugin');
24
+ console.log('Not running Next Runtime');
24
25
  if ((0, fs_extra_1.existsSync)((0, path_1.join)(constants.INTERNAL_FUNCTIONS_SRC, constants_1.HANDLER_FUNCTION_NAME))) {
25
26
  console.log(`Please ensure you remove any generated functions from ${constants.INTERNAL_FUNCTIONS_SRC}`);
26
27
  }
@@ -34,7 +35,6 @@ const plugin = {
34
35
  netlifyConfig.build.environment.NEXT_PRIVATE_TARGET = 'server';
35
36
  },
36
37
  async onBuild({ constants, netlifyConfig, utils: { build: { failBuild }, }, }) {
37
- var _a;
38
38
  if ((0, utils_1.shouldSkip)()) {
39
39
  return;
40
40
  }
@@ -45,6 +45,28 @@ const plugin = {
45
45
  publish,
46
46
  failBuild,
47
47
  });
48
+ const middlewareManifest = await (0, edge_1.loadMiddlewareManifest)(netlifyConfig);
49
+ let usingEdge = false;
50
+ if (Object.keys(middlewareManifest === null || middlewareManifest === void 0 ? void 0 : middlewareManifest.functions).length !== 0) {
51
+ usingEdge = true;
52
+ if (process.env.NEXT_DISABLE_NETLIFY_EDGE) {
53
+ failBuild((0, outdent_1.outdent) `
54
+ You are using Next.js experimental edge runtime, but have set NEXT_DISABLE_NETLIFY_EDGE to true. This is not supported.
55
+ To use edge runtime, remove the env var ${(0, chalk_1.bold) `NEXT_DISABLE_NETLIFY_EDGE`}.
56
+ `);
57
+ }
58
+ }
59
+ if (Object.keys(middlewareManifest === null || middlewareManifest === void 0 ? void 0 : middlewareManifest.middleware).length !== 0) {
60
+ usingEdge = true;
61
+ if (process.env.NEXT_DISABLE_NETLIFY_EDGE) {
62
+ console.log((0, chalk_1.redBright)((0, outdent_1.outdent) `
63
+ You are using Next.js Middleware without Netlify Edge Functions.
64
+ This is deprecated because it negatively affects performance and will disable ISR and static rendering.
65
+ It also disables advanced middleware features from @netlify/next
66
+ To get the best performance and use Netlify Edge Functions, remove the env var ${(0, chalk_1.bold) `NEXT_DISABLE_NETLIFY_EDGE`}.
67
+ `));
68
+ }
69
+ }
48
70
  if (experimental.images) {
49
71
  experimentalRemotePatterns = experimental.images.remotePatterns || [];
50
72
  }
@@ -87,29 +109,20 @@ const plugin = {
87
109
  nextConfig: { basePath, i18n, trailingSlash, appDir },
88
110
  buildId,
89
111
  });
90
- // We call this even if we don't have edge functions enabled because we still use it for images
91
- await (0, edge_1.writeEdgeFunctions)(netlifyConfig);
92
- if (process.env.NEXT_USE_NETLIFY_EDGE) {
112
+ if (usingEdge) {
113
+ await (0, edge_1.writeEdgeFunctions)(netlifyConfig);
114
+ await (0, edge_1.enableEdgeInNextConfig)(publish);
93
115
  console.log((0, outdent_1.outdent) `
94
- ✨ Deploying to ${(0, chalk_1.greenBright) `Netlify Edge Functions`} ✨
116
+ ✨ Deploying middleware and functions to ${(0, chalk_1.greenBright) `Netlify Edge Functions`} ✨
95
117
  This feature is in beta. Please share your feedback here: https://ntl.fyi/next-netlify-edge
96
118
  `);
97
- await (0, edge_1.updateConfig)(publish);
98
- }
99
- const middlewareManifest = await (0, edge_1.loadMiddlewareManifest)(netlifyConfig);
100
- if (!process.env.NEXT_USE_NETLIFY_EDGE && ((_a = middlewareManifest === null || middlewareManifest === void 0 ? void 0 : middlewareManifest.sortedMiddleware) === null || _a === void 0 ? void 0 : _a.length)) {
101
- console.log((0, chalk_1.yellowBright)((0, outdent_1.outdent) `
102
- You are using Next.js Middleware without Netlify Edge Functions.
103
- This will soon be deprecated because it negatively affects performance and will disable ISR and static rendering.
104
- To get the best performance and use Netlify Edge Functions, set the env var ${(0, chalk_1.bold) `NEXT_USE_NETLIFY_EDGE=true`}.
105
- `));
106
119
  }
107
120
  },
108
121
  async onPostBuild({ netlifyConfig: { build: { publish }, redirects, headers, }, utils: { status, cache, functions, build: { failBuild }, }, constants: { FUNCTIONS_DIST }, }) {
109
122
  await (0, cache_1.saveCache)({ cache, publish });
110
123
  if ((0, utils_1.shouldSkip)()) {
111
124
  status.show({
112
- title: 'Essential Next.js plugin did not run',
125
+ title: 'Next Runtime did not run',
113
126
  summary: `Next cache was stored, but all other functions were skipped because ${process.env.NETLIFY_NEXT_PLUGIN_SKIP
114
127
  ? `NETLIFY_NEXT_PLUGIN_SKIP is set`
115
128
  : `NEXT_PLUGIN_FORCE_RUN is set to ${process.env.NEXT_PLUGIN_FORCE_RUN}`}`,
@@ -125,5 +138,24 @@ const plugin = {
125
138
  (0, verification_1.warnForRootRedirects)({ appDir });
126
139
  },
127
140
  };
128
- module.exports = plugin;
141
+ // The types haven't been updated yet
142
+ const nextRuntime = (_inputs, meta = {}) => {
143
+ var _a;
144
+ if (!((_a = meta === null || meta === void 0 ? void 0 : meta.events) === null || _a === void 0 ? void 0 : _a.has('onPreDev'))) {
145
+ return {
146
+ ...plugin,
147
+ onEnd: ({ utils }) => {
148
+ utils.status.show({
149
+ title: 'Please upgrade to the latest version of the Netlify CLI',
150
+ summary: 'To support for the latest Next.js features, please upgrade to the latest version of the Netlify CLI',
151
+ });
152
+ },
153
+ };
154
+ }
155
+ return {
156
+ ...plugin,
157
+ onPreDev: dev_1.onPreDev,
158
+ };
159
+ };
160
+ module.exports = nextRuntime;
129
161
  /* eslint-enable max-lines */
package/manifest.yml CHANGED
@@ -1 +1 @@
1
- name: netlify-plugin-nextjs-experimental
1
+ name: netlify-next-runtime-experimental
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/plugin-nextjs",
3
- "version": "4.16.0",
3
+ "version": "4.17.1-runtime.2",
4
4
  "description": "Run Next.js seamlessly on Netlify",
5
5
  "main": "lib/index.js",
6
6
  "files": [
@@ -9,10 +9,12 @@
9
9
  "manifest.yml"
10
10
  ],
11
11
  "dependencies": {
12
- "@netlify/functions": "^1.1.0",
13
- "@netlify/ipx": "^1.2.1",
12
+ "@netlify/esbuild": "0.14.25",
13
+ "@netlify/functions": "^1.2.0",
14
+ "@netlify/ipx": "^1.2.2",
14
15
  "@vercel/node-bridge": "^2.1.0",
15
16
  "chalk": "^4.1.2",
17
+ "execa": "^5.1.1",
16
18
  "fs-extra": "^10.0.0",
17
19
  "globby": "^11.0.4",
18
20
  "moize": "^6.1.0",
@@ -22,13 +24,13 @@
22
24
  "p-limit": "^3.1.0",
23
25
  "pathe": "^0.2.0",
24
26
  "pretty-bytes": "^5.6.0",
25
- "slash": "^3.0.0",
26
27
  "semver": "^7.3.5",
28
+ "slash": "^3.0.0",
27
29
  "tiny-glob": "^0.2.9"
28
30
  },
29
31
  "devDependencies": {
30
32
  "@delucis/if-env": "^1.1.2",
31
- "@netlify/build": "^27.11.4",
33
+ "@netlify/build": "^27.14.0",
32
34
  "@types/fs-extra": "^9.0.13",
33
35
  "@types/jest": "^27.4.1",
34
36
  "@types/node": "^17.0.25",
@@ -61,4 +63,4 @@
61
63
  "engines": {
62
64
  "node": ">=12.0.0"
63
65
  }
64
- }
66
+ }
@@ -0,0 +1,86 @@
1
+ import { NextRequest, NextResponse } from 'https://esm.sh/next/server'
2
+ import { fromFileUrl } from 'https://deno.land/std/path/mod.ts'
3
+ import { buildResponse } from './utils.ts'
4
+
5
+ globalThis.NFRequestContextMap ||= new Map()
6
+ globalThis.__dirname = fromFileUrl(new URL('./', import.meta.url)).slice(0, -1)
7
+
8
+ // Check if a file exists, given a relative path
9
+ const exists = async (relativePath) => {
10
+ const path = fromFileUrl(new URL(relativePath, import.meta.url))
11
+ try {
12
+ await Deno.stat(path)
13
+ return true
14
+ } catch (error) {
15
+ if (error instanceof Deno.errors.NotFound) {
16
+ return false
17
+ }
18
+ throw error
19
+ }
20
+ }
21
+
22
+ const handler = async (req, context) => {
23
+ // Uncomment when CLI update lands
24
+ // if (!Deno.env.get('NETLIFY_DEV')) {
25
+ // // Only run in dev
26
+ // return
27
+ // }
28
+
29
+ let middleware
30
+ // Dynamic imports and FS operations aren't allowed when deployed,
31
+ // but that's fine because this is only ever used locally.
32
+ // We don't want to just try importing and use that to test,
33
+ // because that would also throw if there's an error in the middleware,
34
+ // which we would want to surface not ignore.
35
+ if (await exists('../../middleware.js')) {
36
+ // These will be user code
37
+ const nextMiddleware = await import('../../middleware.js')
38
+ middleware = nextMiddleware.middleware
39
+ } else {
40
+ // No middleware, so we silently return
41
+ return
42
+ }
43
+
44
+ // This is the format expected by Next.js
45
+ const geo = {
46
+ country: context.geo.country?.code,
47
+ region: context.geo.subdivision?.code,
48
+ city: context.geo.city,
49
+ }
50
+
51
+ // A default request id is fine locally
52
+ const requestId = req.headers.get('x-nf-request-id') || 'request-id'
53
+
54
+ globalThis.NFRequestContextMap.set(requestId, {
55
+ request: req,
56
+ context,
57
+ })
58
+
59
+ const request = {
60
+ headers: Object.fromEntries(req.headers.entries()),
61
+ geo,
62
+ method: req.method,
63
+ ip: context.ip,
64
+ body: req.body || undefined,
65
+ }
66
+
67
+ const nextRequest = new NextRequest(req, request)
68
+
69
+ try {
70
+ const response = await middleware(nextRequest)
71
+ return buildResponse({
72
+ result: { response: response || NextResponse.next(), waitUntil: Promise.resolve() },
73
+ request: req,
74
+ context,
75
+ })
76
+ } catch (error) {
77
+ console.error(error)
78
+ return new Response(error.message, { status: 500 })
79
+ } finally {
80
+ if (requestId) {
81
+ globalThis.NFRequestContextMap.delete(requestId)
82
+ }
83
+ }
84
+ }
85
+
86
+ export default handler
@@ -45,6 +45,10 @@ declare global {
45
45
  globalThis.NFRequestContextMap ||= new Map()
46
46
 
47
47
  const handler = async (req: Request, context: Context) => {
48
+ if (Deno.env.get('NETLIFY_DEV')) {
49
+ // Don't run in dev
50
+ return
51
+ }
48
52
  const url = new URL(req.url)
49
53
 
50
54
  const geo = {
@@ -123,17 +123,38 @@ export const buildResponse = async ({
123
123
  request.headers.set('x-nf-next-middleware', 'skip')
124
124
 
125
125
  const rewrite = res.headers.get('x-middleware-rewrite')
126
+
127
+ // Data requests (i.e. requests for /_next/data ) need special handling
128
+ const isDataReq = request.headers.get('x-nextjs-data')
129
+
126
130
  if (rewrite) {
127
131
  const rewriteUrl = new URL(rewrite, request.url)
128
132
  const baseUrl = new URL(request.url)
133
+ const relativeUrl = relativizeURL(rewrite, request.url)
134
+
135
+ // Data requests might be rewritten to an external URL
136
+ // This header tells the client router the redirect target, and if it's external then it will do a full navigation
137
+ if (isDataReq) {
138
+ res.headers.set('x-nextjs-rewrite', relativeUrl)
139
+ }
129
140
  if (rewriteUrl.hostname !== baseUrl.hostname) {
130
141
  // Netlify Edge Functions don't support proxying to external domains, but Next middleware does
131
142
  const proxied = fetch(new Request(rewriteUrl.toString(), request))
132
143
  return addMiddlewareHeaders(proxied, res)
133
144
  }
134
- res.headers.set('x-middleware-rewrite', relativizeURL(rewrite, request.url))
145
+ res.headers.set('x-middleware-rewrite', relativeUrl)
146
+
135
147
  return addMiddlewareHeaders(context.rewrite(rewrite), res)
136
148
  }
149
+
150
+ const redirect = res.headers.get('Location')
151
+
152
+ // Data requests shouldn;t automatically redirect in the browser (they might be HTML pages): they're handled by the router
153
+ if (redirect && isDataReq) {
154
+ res.headers.delete('location')
155
+ res.headers.set('x-nextjs-redirect', relativizeURL(redirect, request.url))
156
+ }
157
+
137
158
  if (res.headers.get('x-middleware-next') === '1') {
138
159
  return addMiddlewareHeaders(context.next(), res)
139
160
  }