summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/itchy-trains-allow.md5
-rw-r--r--packages/astro/src/vite-plugin-astro-server/route.ts8
-rw-r--r--packages/astro/test/astro-response.test.js20
-rw-r--r--packages/astro/test/fixtures/astro-response/src/pages/not-found-custom.astro4
-rw-r--r--packages/astro/test/test-utils.js4
5 files changed, 37 insertions, 4 deletions
diff --git a/.changeset/itchy-trains-allow.md b/.changeset/itchy-trains-allow.md
new file mode 100644
index 000000000..6a53bca2f
--- /dev/null
+++ b/.changeset/itchy-trains-allow.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixes a case where setting the status of a page to `404` in development would show the default 404 page (or custom one if provided) instead of using the current page
diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts
index 51b7537bf..108b53273 100644
--- a/packages/astro/src/vite-plugin-astro-server/route.ts
+++ b/packages/astro/src/vite-plugin-astro-server/route.ts
@@ -241,7 +241,13 @@ export async function handleRoute({
);
}
- if (statusCode === 404 && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== 'no') {
+ if (
+ statusCode === 404 &&
+ // If the body isn't null, that means the user sets the 404 status
+ // but uses the current route to handle the 404
+ response.body === null &&
+ response.headers.get(REROUTE_DIRECTIVE_HEADER) !== 'no'
+ ) {
const fourOhFourRoute = await matchRoute('/404', manifestData, pipeline);
if (fourOhFourRoute) {
renderContext = await RenderContext.create({
diff --git a/packages/astro/test/astro-response.test.js b/packages/astro/test/astro-response.test.js
index 87313a76a..2440c7362 100644
--- a/packages/astro/test/astro-response.test.js
+++ b/packages/astro/test/astro-response.test.js
@@ -1,9 +1,11 @@
+// @ts-check
import assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test';
import { loadFixture } from './test-utils.js';
// Asset bundling
describe('Returning responses', () => {
+ /** @type {Awaited<ReturnType<typeof loadFixture>>} */
let fixture;
/** @type {import('./test-utils').DevServer} */
let devServer;
@@ -21,7 +23,23 @@ describe('Returning responses', () => {
});
it('Works from a page', async () => {
- let response = await fixture.fetch('/not-found');
+ const response = await fixture.fetch('/not-found');
assert.equal(response.status, 404);
});
+
+ it('Returns the default 404 is body is null', async () => {
+ const response = await fixture.fetch('/not-found');
+ const html = await response.text();
+
+ assert.equal(response.status, 404);
+ assert.equal(html.includes('<pre>Path: /not-found</pre>'), true);
+ });
+
+ it('Returns the page is body is not null', async () => {
+ const response = await fixture.fetch('/not-found-custom');
+ const html = await response.text();
+
+ assert.equal(response.status, 404);
+ assert.equal(html.includes('Custom 404'), true);
+ });
});
diff --git a/packages/astro/test/fixtures/astro-response/src/pages/not-found-custom.astro b/packages/astro/test/fixtures/astro-response/src/pages/not-found-custom.astro
new file mode 100644
index 000000000..482331ebc
--- /dev/null
+++ b/packages/astro/test/fixtures/astro-response/src/pages/not-found-custom.astro
@@ -0,0 +1,4 @@
+---
+Astro.response.status = 404
+---
+<div>Custom 404</div> \ No newline at end of file
diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js
index fca78b083..c33e43ca3 100644
--- a/packages/astro/test/test-utils.js
+++ b/packages/astro/test/test-utils.js
@@ -34,12 +34,12 @@ process.env.ASTRO_TELEMETRY_DISABLED = true;
* @property {typeof build} build
* @property {(url: string) => string} resolveUrl
* @property {(path: string) => Promise<boolean>} pathExists
- * @property {(url: string, opts: Parameters<typeof fetch>[1]) => Promise<Response>} fetch
+ * @property {(url: string, opts?: Parameters<typeof fetch>[1]) => Promise<Response>} fetch
* @property {(path: string) => Promise<string>} readFile
* @property {(path: string, updater: (content: string) => string) => Promise<void>} editFile
* @property {(path: string) => Promise<string[]>} readdir
* @property {(pattern: string) => Promise<string[]>} glob
- * @property {typeof dev} startDevServer
+ * @property {(inlineConfig?: Parameters<typeof dev>[0]) => ReturnType<typeof dev>} startDevServer
* @property {typeof preview} preview
* @property {() => Promise<void>} clean
* @property {() => Promise<App>} loadTestAdapterApp