summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/ten-radios-rush.md5
-rw-r--r--packages/astro/src/core/app/index.ts4
-rw-r--r--packages/astro/src/vite-plugin-astro-server/index.ts8
-rw-r--r--packages/astro/test/ssr-api-route.test.js9
4 files changed, 23 insertions, 3 deletions
diff --git a/.changeset/ten-radios-rush.md b/.changeset/ten-radios-rush.md
new file mode 100644
index 000000000..1162c46e3
--- /dev/null
+++ b/.changeset/ten-radios-rush.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix: add default content type to endpoints with { body } shorthand
diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts
index 6fcb51717..e407adea2 100644
--- a/packages/astro/src/core/app/index.ts
+++ b/packages/astro/src/core/app/index.ts
@@ -149,7 +149,9 @@ export class App {
const headers = new Headers();
const mimeType = mime.getType(url.pathname);
if (mimeType) {
- headers.set('Content-Type', mimeType);
+ headers.set('Content-Type', `${mimeType};charset=utf-8`);
+ } else {
+ headers.set('Content-Type', 'text/plain;charset=utf-8');
}
const bytes = this.#encoder.encode(body);
headers.set('Content-Length', bytes.byteLength.toString());
diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts
index a628247ec..3e8fec074 100644
--- a/packages/astro/src/vite-plugin-astro-server/index.ts
+++ b/packages/astro/src/vite-plugin-astro-server/index.ts
@@ -1,5 +1,6 @@
import type http from 'http';
import type * as vite from 'vite';
+import mime from 'mime';
import type { AstroConfig, ManifestData } from '../@types/astro';
import type { SSROptions } from '../core/render/dev/index';
@@ -315,7 +316,12 @@ async function handleRequest(
if (result.type === 'response') {
await writeWebResponse(res, result.response);
} else {
- res.writeHead(200);
+ let contentType = 'text/plain';
+ const computedMimeType = route.pathname ? mime.getType(route.pathname) : null;
+ if (computedMimeType) {
+ contentType = computedMimeType;
+ }
+ res.writeHead(200, { 'Content-Type': `${contentType};charset=utf-8` });
res.end(result.body);
}
} else {
diff --git a/packages/astro/test/ssr-api-route.test.js b/packages/astro/test/ssr-api-route.test.js
index e4758f10e..ec6e65641 100644
--- a/packages/astro/test/ssr-api-route.test.js
+++ b/packages/astro/test/ssr-api-route.test.js
@@ -30,7 +30,7 @@ describe('API routes in SSR', () => {
const request = new Request('http://example.com/food.json');
const response = await app.render(request);
expect(response.status).to.equal(200);
- expect(response.headers.get('Content-Type')).to.equal('application/json');
+ expect(response.headers.get('Content-Type')).to.equal('application/json;charset=utf-8');
expect(response.headers.get('Content-Length')).to.not.be.empty;
const body = await response.json();
expect(body.length).to.equal(3);
@@ -56,6 +56,13 @@ describe('API routes in SSR', () => {
expect(text).to.equal(`ok`);
});
+ it('Infer content type with charset for { body } shorthand', async () => {
+ const response = await fixture.fetch('/food.json', {
+ method: 'GET',
+ });
+ expect(response.headers.get('Content-Type')).to.equal('application/json;charset=utf-8');
+ });
+
it('Can set multiple headers of the same type', async () => {
const response = await fixture.fetch('/login', {
method: 'POST',