summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/cool-ducks-mix.md5
-rw-r--r--packages/astro/src/core/build/generate.ts21
-rw-r--r--packages/astro/src/core/endpoint/index.ts14
-rw-r--r--packages/astro/src/vite-plugin-astro-server/index.ts13
-rw-r--r--packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts11
5 files changed, 41 insertions, 23 deletions
diff --git a/.changeset/cool-ducks-mix.md b/.changeset/cool-ducks-mix.md
new file mode 100644
index 000000000..938ecd06d
--- /dev/null
+++ b/.changeset/cool-ducks-mix.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Allow 200 response for endpoints in build
diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts
index e89fc0b28..039e8283c 100644
--- a/packages/astro/src/core/build/generate.ts
+++ b/packages/astro/src/core/build/generate.ts
@@ -21,7 +21,7 @@ import {
} from '../../core/path.js';
import { runHookBuildGenerated } from '../../integrations/index.js';
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
-import { call as callEndpoint } from '../endpoint/index.js';
+import { call as callEndpoint, throwIfRedirectNotAllowed } from '../endpoint/index.js';
import { debug, info } from '../logger/core.js';
import { createEnvironment, createRenderContext, renderPage } from '../render/index.js';
import { callGetStaticPaths } from '../render/route-cache.js';
@@ -374,18 +374,19 @@ async function generatePath(
const result = await callEndpoint(endpointHandler, env, ctx);
if (result.type === 'response') {
- throw new Error(`Returning a Response from an endpoint is not supported in SSG mode.`);
+ throwIfRedirectNotAllowed(result.response, opts.settings.config);
+ // If there's no body, do nothing
+ if (!result.response.body) return;
+ body = await result.response.text();
+ } else {
+ body = result.body;
+ encoding = result.encoding;
}
- body = result.body;
- encoding = result.encoding;
} else {
const response = await renderPage(mod, ctx, env);
-
- // If there's a redirect or something, just do nothing.
- if (response.status !== 200 || !response.body) {
- return;
- }
-
+ throwIfRedirectNotAllowed(response, opts.settings.config);
+ // If there's no body, do nothing
+ if (!response.body) return;
body = await response.text();
}
diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts
index 79102f8b1..11d6cb664 100644
--- a/packages/astro/src/core/endpoint/index.ts
+++ b/packages/astro/src/core/endpoint/index.ts
@@ -1,4 +1,4 @@
-import type { APIContext, EndpointHandler, Params } from '../../@types/astro';
+import type { APIContext, AstroConfig, EndpointHandler, Params } from '../../@types/astro';
import type { Environment, RenderContext } from '../render/index';
import { renderEndpoint } from '../../runtime/server/index.js';
@@ -113,3 +113,15 @@ export async function call(
cookies: context.cookies,
};
}
+
+function isRedirect(statusCode: number) {
+ return statusCode >= 300 && statusCode < 400;
+}
+
+export function throwIfRedirectNotAllowed(response: Response, config: AstroConfig) {
+ if (config.output !== 'server' && isRedirect(response.status)) {
+ throw new Error(
+ `Redirects are only available when using output: 'server'. Update your Astro config if you need SSR features.`
+ );
+ }
+}
diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts
index bf34f83bc..d98b9344f 100644
--- a/packages/astro/src/vite-plugin-astro-server/index.ts
+++ b/packages/astro/src/vite-plugin-astro-server/index.ts
@@ -19,6 +19,7 @@ import { createRequest } from '../core/request.js';
import { createRouteManifest, matchAllRoutes } from '../core/routing/index.js';
import { resolvePages } from '../core/util.js';
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
+import { throwIfRedirectNotAllowed } from '../core/endpoint/index.js';
interface AstroPluginOptions {
settings: AstroSettings;
@@ -293,18 +294,6 @@ async function handleRequest(
}
}
-function isRedirect(statusCode: number) {
- return statusCode >= 300 && statusCode < 400;
-}
-
-function throwIfRedirectNotAllowed(response: Response, config: AstroConfig) {
- if (config.output !== 'server' && isRedirect(response.status)) {
- throw new Error(
- `Redirects are only available when using output: 'server'. Update your Astro config if you need SSR features.`
- );
- }
-}
-
async function handleRoute(
matchedRoute: AsyncReturnType<typeof matchRoute>,
url: URL,
diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts
new file mode 100644
index 000000000..b1b48634f
--- /dev/null
+++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts
@@ -0,0 +1,11 @@
+export const get = () => {
+ return new Response(
+ undefined,
+ {
+ status: 301,
+ headers: {
+ Location: 'https://example.com',
+ }
+ }
+ );
+};