summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/pink-deers-grab.md5
-rw-r--r--packages/astro/src/vite-plugin-astro-server/route.ts15
-rw-r--r--packages/astro/test/custom-404-server.test.js42
-rw-r--r--packages/astro/test/fixtures/custom-404-server/astro.config.mjs8
-rw-r--r--packages/astro/test/fixtures/custom-404-server/package.json8
-rw-r--r--packages/astro/test/fixtures/custom-404-server/src/pages/404.astro13
-rw-r--r--packages/astro/test/fixtures/custom-404-server/src/pages/[slug].astro6
-rw-r--r--packages/astro/test/fixtures/custom-404-server/src/pages/index.astro11
-rw-r--r--pnpm-lock.yaml6
9 files changed, 114 insertions, 0 deletions
diff --git a/.changeset/pink-deers-grab.md b/.changeset/pink-deers-grab.md
new file mode 100644
index 000000000..917105007
--- /dev/null
+++ b/.changeset/pink-deers-grab.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix loading of `/404.astro` page when dynamic route returns 404
diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts
index 4c9b8782b..8b8bf3482 100644
--- a/packages/astro/src/vite-plugin-astro-server/route.ts
+++ b/packages/astro/src/vite-plugin-astro-server/route.ts
@@ -230,6 +230,21 @@ export async function handleRoute({
}
} else {
const result = await renderPage(options);
+ if (result.status === 404) {
+ const fourOhFourRoute = await matchRoute('/404', env, manifestData);
+ return handleRoute({
+ ...options,
+ matchedRoute: fourOhFourRoute,
+ url: new URL(pathname, url),
+ body,
+ origin,
+ env,
+ manifestData,
+ incomingRequest,
+ incomingResponse,
+ manifest,
+ });
+ }
throwIfRedirectNotAllowed(result, config);
return await writeSSRResult(request, result, incomingResponse);
}
diff --git a/packages/astro/test/custom-404-server.test.js b/packages/astro/test/custom-404-server.test.js
new file mode 100644
index 000000000..db09bfbab
--- /dev/null
+++ b/packages/astro/test/custom-404-server.test.js
@@ -0,0 +1,42 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+
+describe('Custom 404 server', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/custom-404-server/',
+ site: 'http://example.com',
+ });
+ });
+
+ describe('dev', () => {
+ let devServer;
+ let $;
+
+ before(async () => {
+ devServer = await fixture.startDevServer();
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ it('renders /', async () => {
+ const html = await fixture.fetch('/').then((res) => res.text());
+ $ = cheerio.load(html);
+
+ expect($('h1').text()).to.equal('Home');
+ });
+
+ it('renders 404 for /a', async () => {
+ const html = await fixture.fetch('/a').then((res) => res.text());
+ $ = cheerio.load(html);
+
+ expect($('h1').text()).to.equal('Page not found');
+ expect($('p').text()).to.equal('/a');
+ });
+ });
+});
diff --git a/packages/astro/test/fixtures/custom-404-server/astro.config.mjs b/packages/astro/test/fixtures/custom-404-server/astro.config.mjs
new file mode 100644
index 000000000..980ae408c
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-server/astro.config.mjs
@@ -0,0 +1,8 @@
+import { defineConfig } from 'astro/config';
+import testAdapter from '../../test-adapter.js';
+
+// https://astro.build/config
+export default defineConfig({
+ output: 'server',
+ adapter: testAdapter(),
+});
diff --git a/packages/astro/test/fixtures/custom-404-server/package.json b/packages/astro/test/fixtures/custom-404-server/package.json
new file mode 100644
index 000000000..184b79c95
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-server/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/custom-404-server",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/custom-404-server/src/pages/404.astro b/packages/astro/test/fixtures/custom-404-server/src/pages/404.astro
new file mode 100644
index 000000000..63d560b0f
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-server/src/pages/404.astro
@@ -0,0 +1,13 @@
+---
+const canonicalURL = new URL(Astro.url.pathname, Astro.site);
+---
+
+<html lang="en">
+<head>
+ <title>Not Found - Custom 404</title>
+</head>
+<body>
+ <h1>Page not found</h1>
+ <p>{canonicalURL.pathname}</p>
+</body>
+</html>
diff --git a/packages/astro/test/fixtures/custom-404-server/src/pages/[slug].astro b/packages/astro/test/fixtures/custom-404-server/src/pages/[slug].astro
new file mode 100644
index 000000000..406a10a65
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-server/src/pages/[slug].astro
@@ -0,0 +1,6 @@
+---
+return new Response(null, {
+ status: 404,
+ statusText: 'Not Found'
+})
+---
diff --git a/packages/astro/test/fixtures/custom-404-server/src/pages/index.astro b/packages/astro/test/fixtures/custom-404-server/src/pages/index.astro
new file mode 100644
index 000000000..cf5ef9b58
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-server/src/pages/index.astro
@@ -0,0 +1,11 @@
+---
+---
+
+<html lang="en">
+<head>
+ <title>Custom 404</title>
+</head>
+<body>
+ <h1>Home</h1>
+</body>
+</html>
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 3c4781f32..dc5ddd7f1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2520,6 +2520,12 @@ importers:
specifier: workspace:*
version: link:../../..
+ packages/astro/test/fixtures/custom-404-server:
+ dependencies:
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+
packages/astro/test/fixtures/custom-assets-name:
dependencies:
'@astrojs/node':