Skip to content

Commit a32aee6

Browse files
feat(node)!: remove experimentalErrorPageHost (#15654)
Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com>
1 parent 830a267 commit a32aee6

14 files changed

Lines changed: 102 additions & 184 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
'@astrojs/node': major
3+
---
4+
5+
Removes the `experimentalErrorPageHost` option
6+
7+
This option allowed fetching a prerendered error page from a different host than the server is currently running on.
8+
9+
However, there can be security implications with prefetching from other hosts, and often more customization was required to do this safely. This has now been removed as a built-in option so that you can implement your own secure solution as needed and appropriate for your project via middleware.
10+
11+
#### What should I do?
12+
13+
If you were previously using this feature, you must remove the option from your adapter configuration as it no longer exists:
14+
15+
```diff
16+
// astro.config.mjs
17+
import { defineConfig } from 'astro/config'
18+
import node from '@astrojs/node'
19+
20+
export default defineConfig({
21+
adapter: node({
22+
mode: 'standalone',
23+
- experimentalErrorPageHost: 'http://localhost:4321'
24+
})
25+
})
26+
```
27+
28+
You can replicate the previous behavior by checking the response status in a middleware and fetching the prerendered page yourself:
29+
30+
```ts
31+
// src/middleware.ts
32+
import { defineMiddleware } from 'astro:middleware'
33+
34+
export const onRequest = defineMiddleware(async (ctx, next) => {
35+
const response = await next()
36+
if (response.status === 404 || response.status === 500) {
37+
return fetch(`http://localhost:4321/${response.status}.html`);
38+
}
39+
return response
40+
})
41+
```

packages/integrations/node/src/index.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,10 @@ export function getAdapter({ staticHeaders }: Pick<Options, 'staticHeaders'>): A
2929
};
3030
}
3131

32-
const protocols = ['http:', 'https:'];
33-
3432
export default function createIntegration(userOptions: UserOptions): AstroIntegration {
3533
if (!userOptions?.mode) {
3634
throw new AstroError(`Setting the 'mode' option is required.`);
3735
}
38-
const { experimentalErrorPageHost } = userOptions;
39-
if (
40-
experimentalErrorPageHost &&
41-
(!URL.canParse(experimentalErrorPageHost) ||
42-
!protocols.includes(new URL(experimentalErrorPageHost).protocol))
43-
) {
44-
throw new AstroError(
45-
`Invalid experimentalErrorPageHost: ${experimentalErrorPageHost}. It should be a valid URL.`,
46-
);
47-
}
4836

4937
let _config: AstroConfig | undefined = undefined;
5038
let _routeToHeaders: RouteToHeaders | undefined = undefined;
@@ -90,7 +78,6 @@ export default function createIntegration(userOptions: UserOptions): AstroIntegr
9078
host: _config.server.host,
9179
port: _config.server.port,
9280
staticHeaders: userOptions.staticHeaders ?? false,
93-
experimentalErrorPageHost,
9481
}),
9582
],
9683
},

packages/integrations/node/src/serve-app.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,15 @@ export function createAppHandler(app: BaseApp, options: Options): RequestHandler
6262
// Read prerendered error pages directly from disk instead of fetching over HTTP.
6363
// This avoids SSRF risks and is more efficient.
6464
const prerenderedErrorPageFetch = async (url: string): Promise<Response> => {
65-
if (url.includes('/404')) {
65+
const { pathname } = new URL(url);
66+
if (pathname.endsWith('/404.html') || pathname.endsWith('/404/index.html')) {
6667
const response = await readErrorPageFromDisk(client, 404);
6768
if (response) return response;
6869
}
69-
if (url.includes('/500')) {
70+
if (pathname.endsWith('/500.html') || pathname.endsWith('/500/index.html')) {
7071
const response = await readErrorPageFromDisk(client, 500);
7172
if (response) return response;
7273
}
73-
// Fallback: if experimentalErrorPageHost is configured, fetch from there
74-
if (options.experimentalErrorPageHost) {
75-
const originUrl = new URL(options.experimentalErrorPageHost);
76-
const errorPageUrl = new URL(url);
77-
errorPageUrl.protocol = originUrl.protocol;
78-
errorPageUrl.host = originUrl.host;
79-
return fetch(errorPageUrl);
80-
}
8174
// No file found and no fallback configured - return empty response
8275
return new Response(null, { status: 404 });
8376
};

packages/integrations/node/src/types.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,6 @@ export interface UserOptions {
2020
* - The CSP header of the static pages is added when CSP support is enabled.
2121
*/
2222
staticHeaders?: boolean;
23-
24-
/**
25-
* The host that should be used if the server needs to fetch the prerendered error page.
26-
* If not provided, this will default to the host of the server. This should be set if the server
27-
* should fetch prerendered error pages from a different host than the public URL of the server.
28-
* This is useful for example if the server is behind a reverse proxy or a load balancer, or if
29-
* static files are hosted on a different domain. Do not include a path in the URL: it will be ignored.
30-
*/
31-
experimentalErrorPageHost?: string | URL;
3223
}
3324

3425
export interface Options extends UserOptions {

packages/integrations/node/test/error-page-host.test.js

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

packages/integrations/node/test/fixtures/prerender-error-page/src/pages/404.astro

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

packages/integrations/node/test/fixtures/prerender-error-page/src/pages/500.astro

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

packages/integrations/node/test/fixtures/prerender-error-page/src/pages/index.astro

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/integrations/node/test/fixtures/prerender-error-page/package.json renamed to packages/integrations/node/test/fixtures/prerendered-error-page-fetch/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "@test/nodejs-prerender-error-page",
2+
"name": "@test/nodejs-prerendered-error-page-fetch",
33
"version": "0.0.0",
44
"private": true,
55
"dependencies": {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<html><body><h1>Custom 404 Page</h1></body></html>

0 commit comments

Comments
 (0)