diff --git a/.changeset/yellow-grapes-design.md b/.changeset/yellow-grapes-design.md
new file mode 100644
index 000000000..ba3594ce2
--- /dev/null
+++ b/.changeset/yellow-grapes-design.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix prerendered 404 page handling in SSR
diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts
index c97131b43..286314d4f 100644
--- a/packages/astro/src/core/app/index.ts
+++ b/packages/astro/src/core/app/index.ts
@@ -102,7 +102,9 @@ export class App {
if (routeData.prerender) return undefined;
return routeData;
} else if (matchNotFound) {
- return matchRoute('/404', this.#manifestData);
+ const notFoundRouteData = matchRoute('/404', this.#manifestData);
+ if (notFoundRouteData?.prerender) return undefined;
+ return notFoundRouteData;
} else {
return undefined;
}
diff --git a/packages/astro/test/fixtures/ssr-prerender-404/package.json b/packages/astro/test/fixtures/ssr-prerender-404/package.json
new file mode 100644
index 000000000..fb2290464
--- /dev/null
+++ b/packages/astro/test/fixtures/ssr-prerender-404/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/ssr-prerender-404",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/ssr-prerender-404/src/pages/404.astro b/packages/astro/test/fixtures/ssr-prerender-404/src/pages/404.astro
new file mode 100644
index 000000000..749c70954
--- /dev/null
+++ b/packages/astro/test/fixtures/ssr-prerender-404/src/pages/404.astro
@@ -0,0 +1,5 @@
+---
+export const prerender = true
+---
+
+Page does not exist
diff --git a/packages/astro/test/fixtures/ssr-prerender-404/src/pages/static.astro b/packages/astro/test/fixtures/ssr-prerender-404/src/pages/static.astro
new file mode 100644
index 000000000..54680cfcb
--- /dev/null
+++ b/packages/astro/test/fixtures/ssr-prerender-404/src/pages/static.astro
@@ -0,0 +1,18 @@
+---
+export const prerender = true;
+
+const { searchParams } = Astro.url;
+---
+
+
+
+ Static Page
+
+
+
+ Hello world!
+ {searchParams.get('q')}
+
+
diff --git a/packages/astro/test/ssr-prerender-404.test.js b/packages/astro/test/ssr-prerender-404.test.js
new file mode 100644
index 000000000..8ebcb01c8
--- /dev/null
+++ b/packages/astro/test/ssr-prerender-404.test.js
@@ -0,0 +1,33 @@
+import { expect } from 'chai';
+import { loadFixture } from './test-utils.js';
+import testAdapter from './test-adapter.js';
+
+describe('SSR: prerender 404', () => {
+ /** @type {import('./test-utils').Fixture} */
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/ssr-prerender-404/',
+ output: 'server',
+ adapter: testAdapter(),
+ experimental: {
+ prerender: true,
+ },
+ });
+ await fixture.build();
+ });
+
+ describe('Prerendering', () => {
+ it('Prerendered 404.astro page is not rendered', async () => {
+ const app = await fixture.loadTestAdapterApp();
+ const request = new Request('http://example.com/non-existent-page');
+ const response = await app.render(request);
+ expect(response.status).to.equal(404);
+ expect(response.statusText).to.equal(
+ 'Not found',
+ 'should be actual 404 response, not 404 page'
+ );
+ });
+ });
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5c460b4b7..380705f81 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2540,6 +2540,12 @@ importers:
dependencies:
astro: link:../../..
+ packages/astro/test/fixtures/ssr-prerender-404:
+ specifiers:
+ astro: workspace:*
+ dependencies:
+ astro: link:../../..
+
packages/astro/test/fixtures/ssr-prerender-get-static-paths:
specifiers:
astro: workspace:*
@@ -4190,14 +4196,15 @@ packages:
- react
dev: false
- /@astrojs/markdown-remark/2.0.1_astro@packages+astro:
- resolution: {integrity: sha512-xQF1rXGJN18m+zZucwRRtmNehuhPMMhZhi6HWKrtpEAKnHSPk8lqf1GXgKH7/Sypglu8ivdECZ+EGs6kOYVasQ==}
+ /@astrojs/markdown-remark/2.1.0_astro@packages+astro:
+ resolution: {integrity: sha512-w9T5o3UWQIfMcCkM2nLWrlfVQazh/7mw+2N/85QGcSUkZy6oNJoyy8Xz/ZkDhHLx8HPO0RT9fABR0B/H+aDaEw==}
peerDependencies:
astro: '*'
dependencies:
- '@astrojs/prism': 2.0.0
+ '@astrojs/prism': 2.1.1
astro: link:packages/astro
github-slugger: 1.5.0
+ image-size: 1.0.2
import-meta-resolve: 2.2.1
rehype-raw: 6.1.1
rehype-stringify: 9.0.3
@@ -4217,8 +4224,8 @@ packages:
resolution: {integrity: sha512-mol57cw1jJMcQgKMRGn7p6cewajq6JTNtqj5aAZgROWam/phVDSOCbXj/WU3O9+3qFnyKtpczoufQKwJTQltAw==}
engines: {node: '>=16.12.0'}
dependencies:
- '@astrojs/markdown-remark': 2.0.1_astro@packages+astro
- '@astrojs/prism': 2.0.0
+ '@astrojs/markdown-remark': 2.1.0_astro@packages+astro
+ '@astrojs/prism': 2.1.1
'@mdx-js/mdx': 2.3.0
'@mdx-js/rollup': 2.3.0
acorn: 8.8.2
@@ -4262,8 +4269,8 @@ packages:
- supports-color
dev: false
- /@astrojs/prism/2.0.0:
- resolution: {integrity: sha512-YgeoeEPqsxaEpg0rwe/bUq3653LqSQnMjrLlpYwrbQQMQQqz6Y5yXN+RX3SfLJ6ppNb4+Fu2+Z49EXjk48Ihjw==}
+ /@astrojs/prism/2.1.1:
+ resolution: {integrity: sha512-Gnwnlb1lGJzCQEg89r4/WqgfCGPNFC7Kuh2D/k289Cbdi/2PD7Lrdstz86y1itDvcb2ijiRqjqWnJ5rsfu/QOA==}
engines: {node: '>=16.12.0'}
dependencies:
prismjs: 1.29.0