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();