Skip to content

Commit f61268c

Browse files
khuezyconico974
andauthored
Nextjs 13.4.13+ Fix (#208)
* Fixes Nextjs 13.4.13+ issues (middleware, interception, routing) --------- Co-authored-by: Dorseuil Nicolas <[email protected]>
1 parent 60e510f commit f61268c

40 files changed

+2068
-895
lines changed

README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,19 +288,13 @@ export default async function handler(req, res) {
288288
If the pages router is in use, you must also invalidate the `_next/data/BUILD_ID/foo.json` path. The value for `BUILD_ID` can be found in the `.next/BUILD_ID` build output and can be accessed at runtime via the `process.env.NEXT_BUILD_ID` environment variable.
289289

290290
```ts
291-
await invalidateCloudFrontPaths([
292-
"/foo",
293-
`/_next/data/${process.env.NEXT_BUILD_ID}/foo.json`,
294-
]);
291+
await invalidateCloudFrontPaths(["/foo", `/_next/data/${process.env.NEXT_BUILD_ID}/foo.json`]);
295292
```
296293

297294
And here is an example of the `invalidateCloudFrontPaths()` function:
298295

299296
```ts
300-
import {
301-
CloudFrontClient,
302-
CreateInvalidationCommand,
303-
} from "@aws-sdk/client-cloudfront";
297+
import { CloudFrontClient, CreateInvalidationCommand } from "@aws-sdk/client-cloudfront";
304298

305299
const cloudFront = new CloudFrontClient({});
306300

@@ -585,6 +579,15 @@ For Next.js 13.2 and later versions, you need to explicitly set the `__NEXT_PRIV
585579
586580
On every request, we try to detect whether the route is using the Pages Router or the App Router. If the Pages Router is being used, we set `__NEXT_PRIVATE_PREBUNDLED_REACT` to `undefined`, which means the React version from the `node_modules` is used. However, if the App Router is used, `__NEXT_PRIVATE_PREBUNDLED_REACT` is set, and the prebundled React version is used.
587581

582+
#### WORKAROUND: 13.4.13+ breaking changes (middleware, redirect, rewrites)
583+
584+
Nextjs 13.4.13 refactored the middleware logic so that it no longer runs in the server handler. Instead they are executed as workeres in child threads, which introduces a non-acceptable latency of ~5 seconds. In order to circumvent this issue, open-next needs to implement the middleware handler before processing the server handler ourselves.
585+
586+
We've introduced a custom esbuild plugin to conditionally inject and override code to properly handle the breaking changes.
587+
588+
The default request handler is in `adapters/plugins/default.ts`
589+
When open-next needs to override that implementation due to NextJs breaking compatibility, the `createServerBundle` in `build.ts` determines the proper overrides to replace the code of the `default.ts` file.
590+
588591
## Example
589592

590593
In the `example` folder, you can find a Next.js benchmark app. It contains a variety of pages that each test a single Next.js feature. The app is deployed to both Vercel and AWS using [SST](https://docs.sst.dev/start/nextjs).

examples/app-pages-router/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313
"dependencies": {
1414
"open-next": "workspace:*",
1515
"@example/shared": "workspace:*",
16-
"@open-next/utils": "workspace:*"
16+
"@open-next/utils": "workspace:*",
17+
"next": "latest",
18+
"react": "latest",
19+
"react-dom": "latest"
1720
},
1821
"devDependencies": {
1922
"@types/node": "20.5.0",
2023
"@types/react": "18.2.20",
2124
"@types/react-dom": "18.2.7",
2225
"autoprefixer": "10.4.15",
23-
"next": "13.4.12",
2426
"postcss": "8.4.27",
25-
"react": "18.2.0",
26-
"react-dom": "18.2.0",
2727
"tailwindcss": "3.3.3",
2828
"typescript": "^4.9.3"
2929
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { headers } from "next/headers";
2+
3+
export default function Headers() {
4+
const middlewareHeader = headers().get("request-header");
5+
return (
6+
<div>
7+
<h1>Headers</h1>
8+
<div>{middlewareHeader}</div>
9+
</div>
10+
);
11+
}

examples/app-router/app/page.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ export default function Home() {
3434
<Nav href={"/parallel"} title="Parallel">
3535
Parallel routing
3636
</Nav>
37+
<Nav href={"/headers"} title="Headers">
38+
Headers from middleware should be available via headers()
39+
</Nav>
40+
<Nav href={"/search-query"} title="Search Query">
41+
Search Query Params should be available in middleware
42+
</Nav>
3743
</main>
3844
</>
3945
);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { headers } from "next/headers";
2+
3+
export default function SearchQuery({
4+
searchParams: propsSearchParams,
5+
}: {
6+
searchParams: Record<string, string>;
7+
}) {
8+
const mwSearchParams = headers().get("search-params");
9+
return (
10+
<>
11+
<h1>Search Query</h1>
12+
<div>Search Params via Props: {propsSearchParams.searchParams}</div>
13+
<div>Search Params via Middleware: {mwSearchParams}</div>
14+
</>
15+
);
16+
}

examples/app-router/middleware.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,18 @@ export function middleware(request: NextRequest) {
2020
});
2121
}
2222

23-
const rHeaders = new Headers(request.headers);
23+
const requestHeaders = new Headers();
24+
requestHeaders.set("request-header", "request-header");
25+
requestHeaders.set(
26+
"search-params",
27+
`mw/${request.nextUrl.searchParams.get("searchParams") || ""}`,
28+
);
29+
const responseHeaders = new Headers();
30+
responseHeaders.set("response-header", "response-header");
2431
const r = NextResponse.next({
32+
headers: responseHeaders,
2533
request: {
26-
headers: rHeaders,
34+
headers: requestHeaders,
2735
},
2836
});
2937
return r;

examples/app-router/next.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ const nextConfig = {
77
experimental: {
88
serverActions: true,
99
},
10+
headers() {
11+
return [
12+
{
13+
source: "/(.*)",
14+
headers: [
15+
{
16+
key: "e2e-headers",
17+
value: "next.config.js",
18+
},
19+
],
20+
},
21+
];
22+
},
1023
};
1124

1225
module.exports = nextConfig;

examples/app-router/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313
"dependencies": {
1414
"open-next": "workspace:*",
1515
"@example/shared": "workspace:*",
16-
"@open-next/utils": "workspace:*"
16+
"@open-next/utils": "workspace:*",
17+
"next": "latest",
18+
"react": "latest",
19+
"react-dom": "latest"
1720
},
1821
"devDependencies": {
1922
"@types/node": "20.5.0",
2023
"@types/react": "18.2.20",
2124
"@types/react-dom": "18.2.7",
2225
"autoprefixer": "10.4.15",
23-
"next": "13.4.12",
2426
"postcss": "8.4.27",
25-
"react": "18.2.0",
26-
"react-dom": "18.2.0",
2727
"tailwindcss": "3.3.3",
2828
"typescript": "^4.9.3"
2929
}

examples/pages-router/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
"@types/react": "18.2.20",
1717
"@types/react-dom": "18.2.7",
1818
"autoprefixer": "10.4.15",
19-
"next": "13.4.12",
19+
"next": "latest",
2020
"postcss": "8.4.27",
21-
"react": "18.2.0",
22-
"react-dom": "18.2.0",
21+
"react": "latest",
22+
"react-dom": "latest",
2323
"tailwindcss": "3.3.3",
2424
"typescript": "^4.9.3"
2525
}

packages/open-next/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@
4040
"@node-minify/core": "^8.0.6",
4141
"@node-minify/terser": "^8.0.6",
4242
"@tsconfig/node18": "^1.0.1",
43-
"esbuild": "^0.15.18",
43+
"esbuild": "^0.18.18",
44+
"@esbuild-plugins/node-resolve": "0.2.2",
45+
"path-to-regexp": "^6.2.1",
4446
"promise.series": "^0.2.0"
4547
},
4648
"devDependencies": {
4749
"@types/aws-lambda": "^8.10.109",
48-
"@types/node": "^18.11.17",
50+
"@types/node": "^18.16.1",
4951
"typescript": "^4.9.3"
5052
},
5153
"bugs": {

0 commit comments

Comments
 (0)