diff --git a/.changeset/popular-plants-begin.md b/.changeset/popular-plants-begin.md
new file mode 100644
index 000000000000..dfe565a54577
--- /dev/null
+++ b/.changeset/popular-plants-begin.md
@@ -0,0 +1,5 @@
+---
+"@sveltejs/kit": patch
+---
+
+[fix] handle binary data when prerendering
diff --git a/packages/kit/src/core/prerender/prerender.js b/packages/kit/src/core/prerender/prerender.js
index e14a25760756..5995984c2861 100644
--- a/packages/kit/src/core/prerender/prerender.js
+++ b/packages/kit/src/core/prerender/prerender.js
@@ -136,9 +136,9 @@ export async function prerender({ config, entries, files, log }) {
}
});
- const text = await response.text();
+ const body = Buffer.from(await response.arrayBuffer());
- save('pages', response, text, decoded, encoded, referrer, 'linked');
+ save('pages', response, body, decoded, encoded, referrer, 'linked');
for (const [dependency_path, result] of dependencies) {
// this seems circuitous, but using new URL allows us to not care
@@ -159,7 +159,7 @@ export async function prerender({ config, entries, files, log }) {
}
if (config.prerender.crawl && response.headers.get('content-type') === 'text/html') {
- for (const href of crawl(text)) {
+ for (const href of crawl(body.toString())) {
if (href.startsWith('data:') || href.startsWith('#')) continue;
const resolved = resolve(encoded, href);
diff --git a/packages/kit/test/prerendering/basics/src/routes/fetch-image.svelte b/packages/kit/test/prerendering/basics/src/routes/fetch-image.svelte
new file mode 100644
index 000000000000..b02e92a1db04
--- /dev/null
+++ b/packages/kit/test/prerendering/basics/src/routes/fetch-image.svelte
@@ -0,0 +1,2 @@
+
+
diff --git a/packages/kit/test/prerendering/basics/src/routes/fetch-image/[...slug]/index.js b/packages/kit/test/prerendering/basics/src/routes/fetch-image/[...slug]/index.js
new file mode 100644
index 000000000000..83f52a7bc27e
--- /dev/null
+++ b/packages/kit/test/prerendering/basics/src/routes/fetch-image/[...slug]/index.js
@@ -0,0 +1,16 @@
+import * as fs from 'fs';
+
+export async function GET({ params }) {
+ const slug = params.slug.split('/');
+ const extension = slug[0].split('.').pop();
+
+ const file = fs.readFileSync(`./static/image.${extension}`);
+
+ return {
+ status: 200,
+ headers: {
+ 'Content-Type': 'image/' + extension
+ },
+ body: file
+ };
+}
diff --git a/packages/kit/test/prerendering/basics/static/image.jpg b/packages/kit/test/prerendering/basics/static/image.jpg
new file mode 100644
index 000000000000..396b0c8f56e9
Binary files /dev/null and b/packages/kit/test/prerendering/basics/static/image.jpg differ
diff --git a/packages/kit/test/prerendering/basics/static/image.png b/packages/kit/test/prerendering/basics/static/image.png
new file mode 100644
index 000000000000..31ffe06357c4
Binary files /dev/null and b/packages/kit/test/prerendering/basics/static/image.png differ
diff --git a/packages/kit/test/prerendering/basics/test/test.js b/packages/kit/test/prerendering/basics/test/test.js
index b7dd394892d2..9f754a6726f4 100644
--- a/packages/kit/test/prerendering/basics/test/test.js
+++ b/packages/kit/test/prerendering/basics/test/test.js
@@ -6,7 +6,7 @@ import * as assert from 'uvu/assert';
const build = fileURLToPath(new URL('../build', import.meta.url));
/** @param {string} file */
-const read = (file) => fs.readFileSync(`${build}/${file}`, 'utf-8');
+const read = (file, encoding = 'utf-8') => fs.readFileSync(`${build}/${file}`, encoding);
test('prerenders /', () => {
const content = read('index.html');
@@ -141,4 +141,9 @@ test('targets the data-sveltekit-hydrate parent node', () => {
);
});
+test('prerenders binary data', async () => {
+ assert.equal(Buffer.compare(read('fetch-image/image.jpg', null), read('image.jpg', null)), 0);
+ assert.equal(Buffer.compare(read('fetch-image/image.png', null), read('image.png', null)), 0);
+});
+
test.run();