fix: dev server should redirect when a page doesn't exist (#7841)
This commit is contained in:
parent
3b422272e6
commit
2275c7d56b
2 changed files with 24 additions and 7 deletions
5
.changeset/plenty-bats-shake.md
Normal file
5
.changeset/plenty-bats-shake.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Allow to return a redirect in dev mode when the original route is not present in the file system.
|
|
@ -31,6 +31,7 @@ import { preload } from './index.js';
|
||||||
import { getComponentMetadata } from './metadata.js';
|
import { getComponentMetadata } from './metadata.js';
|
||||||
import { handle404Response, writeSSRResult, writeWebResponse } from './response.js';
|
import { handle404Response, writeSSRResult, writeWebResponse } from './response.js';
|
||||||
import { getScriptsForURL } from './scripts.js';
|
import { getScriptsForURL } from './scripts.js';
|
||||||
|
import { isEndpointResult } from '../core/render/core.js';
|
||||||
|
|
||||||
const clientLocalsSymbol = Symbol.for('astro.locals');
|
const clientLocalsSymbol = Symbol.for('astro.locals');
|
||||||
|
|
||||||
|
@ -140,7 +141,7 @@ type HandleRoute = {
|
||||||
incomingRequest: http.IncomingMessage;
|
incomingRequest: http.IncomingMessage;
|
||||||
incomingResponse: http.ServerResponse;
|
incomingResponse: http.ServerResponse;
|
||||||
manifest: SSRManifest;
|
manifest: SSRManifest;
|
||||||
status?: number;
|
status?: 404 | 500;
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function handleRoute({
|
export async function handleRoute({
|
||||||
|
@ -216,7 +217,7 @@ export async function handleRoute({
|
||||||
const onRequest = options.middleware?.onRequest as MiddlewareResponseHandler | undefined;
|
const onRequest = options.middleware?.onRequest as MiddlewareResponseHandler | undefined;
|
||||||
|
|
||||||
const result = await tryRenderRoute(route.type, renderContext, env, mod, onRequest);
|
const result = await tryRenderRoute(route.type, renderContext, env, mod, onRequest);
|
||||||
if (route.type === 'endpoint' && !(result instanceof Response)) {
|
if (isEndpointResult(result, route.type)) {
|
||||||
if (result.type === 'response') {
|
if (result.type === 'response') {
|
||||||
if (result.response.headers.get('X-Astro-Response') === 'Not-Found') {
|
if (result.response.headers.get('X-Astro-Response') === 'Not-Found') {
|
||||||
const fourOhFourRoute = await matchRoute('/404', env, manifestData);
|
const fourOhFourRoute = await matchRoute('/404', env, manifestData);
|
||||||
|
@ -254,7 +255,7 @@ export async function handleRoute({
|
||||||
attachToResponse(response, result.cookies);
|
attachToResponse(response, result.cookies);
|
||||||
await writeWebResponse(incomingResponse, response);
|
await writeWebResponse(incomingResponse, response);
|
||||||
}
|
}
|
||||||
} else if (result instanceof Response) {
|
} else {
|
||||||
if (result.status === 404) {
|
if (result.status === 404) {
|
||||||
const fourOhFourRoute = await matchRoute('/404', env, manifestData);
|
const fourOhFourRoute = await matchRoute('/404', env, manifestData);
|
||||||
return handleRoute({
|
return handleRoute({
|
||||||
|
@ -273,13 +274,24 @@ export async function handleRoute({
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = result;
|
let response = result;
|
||||||
// Response.status is read-only, so a clone is required to override
|
|
||||||
if (status && response.status !== status) {
|
if (
|
||||||
|
// We are in a recursion, and it's possible that this function is called itself with a status code
|
||||||
|
// By default, the status code passed via parameters is computed by the matched route.
|
||||||
|
//
|
||||||
|
// By default, we should give priority to the status code passed, although it's possible that
|
||||||
|
// the `Response` emitted by the user is a redirect. If so, then return the returned response.
|
||||||
|
response.status < 400 &&
|
||||||
|
response.status >= 300
|
||||||
|
) {
|
||||||
|
await writeSSRResult(request, response, incomingResponse);
|
||||||
|
return;
|
||||||
|
} else if (status && response.status !== status && (status === 404 || status === 500)) {
|
||||||
|
// Response.status is read-only, so a clone is required to override
|
||||||
response = new Response(result.body, { ...result, status });
|
response = new Response(result.body, { ...result, status });
|
||||||
}
|
}
|
||||||
await writeSSRResult(request, response, incomingResponse);
|
await writeSSRResult(request, response, incomingResponse);
|
||||||
}
|
}
|
||||||
// unreachable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GetScriptsAndStylesParams {
|
interface GetScriptsAndStylesParams {
|
||||||
|
@ -360,7 +372,7 @@ async function getScriptsAndStyles({ env, filePath }: GetScriptsAndStylesParams)
|
||||||
return { scripts, styles, links, metadata };
|
return { scripts, styles, links, metadata };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStatus(matchedRoute?: MatchedRoute): number | undefined {
|
function getStatus(matchedRoute?: MatchedRoute): 404 | 500 | undefined {
|
||||||
if (!matchedRoute) return 404;
|
if (!matchedRoute) return 404;
|
||||||
if (matchedRoute.route.route === '/404') return 404;
|
if (matchedRoute.route.route === '/404') return 404;
|
||||||
if (matchedRoute.route.route === '/500') return 500;
|
if (matchedRoute.route.route === '/500') return 500;
|
||||||
|
|
Loading…
Reference in a new issue