aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matt Kane <m@mk.gg> 2025-03-03 14:32:04 +0000
committerGravatar GitHub <noreply@github.com> 2025-03-03 14:32:04 +0000
commitfac32ad98d66b73382f35d26a69352e566cd94d9 (patch)
treef0cff234e33a2d9afd69b5f605b579d5a417df52
parent21c233c3c9398aa3dbdfb612391617ef31a6ea63 (diff)
downloadastro-fac32ad98d66b73382f35d26a69352e566cd94d9.tar.gz
astro-fac32ad98d66b73382f35d26a69352e566cd94d9.tar.zst
astro-fac32ad98d66b73382f35d26a69352e566cd94d9.zip
fix: generate correct responsive srcsets on Vercel (#13351)
* fix: generate correct responsive srcsets on Vercel * [skipci] Apply suggestions from code review Co-authored-by: Emanuele Stoppa <my.burning@gmail.com> --------- Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
-rw-r--r--.changeset/metal-emus-bathe.md5
-rw-r--r--packages/integrations/vercel/src/image/shared.ts14
-rw-r--r--packages/integrations/vercel/src/index.ts1
-rw-r--r--packages/integrations/vercel/test/fixtures/image/astro.config.mjs7
-rw-r--r--packages/integrations/vercel/test/fixtures/image/src/assets/penguin.jpgbin0 -> 258734 bytes
-rw-r--r--packages/integrations/vercel/test/fixtures/image/src/pages/index.astro5
-rw-r--r--packages/integrations/vercel/test/image.test.js11
7 files changed, 41 insertions, 2 deletions
diff --git a/.changeset/metal-emus-bathe.md b/.changeset/metal-emus-bathe.md
new file mode 100644
index 000000000..dc06a88d6
--- /dev/null
+++ b/.changeset/metal-emus-bathe.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/vercel': patch
+---
+
+Ensures `srcset` for responsive images only contains allowed sizes
diff --git a/packages/integrations/vercel/src/image/shared.ts b/packages/integrations/vercel/src/image/shared.ts
index eb9681243..52c319417 100644
--- a/packages/integrations/vercel/src/image/shared.ts
+++ b/packages/integrations/vercel/src/image/shared.ts
@@ -69,6 +69,7 @@ export function getAstroImageConfig(
command: string,
devImageService: DevImageService,
astroImageConfig: AstroConfig['image'],
+ responsiveImages?: boolean,
) {
let devService = '@astrojs/vercel/dev-image-service';
@@ -86,12 +87,14 @@ export function getAstroImageConfig(
}
if (images) {
+ const config = imagesConfig ? imagesConfig : getDefaultImageConfig(astroImageConfig);
return {
image: {
service: {
entrypoint: command === 'dev' ? devService : '@astrojs/vercel/build-image-service',
- config: imagesConfig ? imagesConfig : getDefaultImageConfig(astroImageConfig),
+ config,
},
+ experimentalBreakpoints: responsiveImages ? config.sizes : undefined,
},
};
}
@@ -151,6 +154,15 @@ export function sharedValidateOptions(
}
}
+ if (options.widths) {
+ // Vercel only supports a fixed set of widths, so remove any that aren't in the list
+ options.widths = options.widths.filter((w) => configuredWidths.includes(w));
+ // Oh no, we've removed all the widths! Let's add the nearest one back in
+ if (options.widths.length === 0) {
+ options.widths = [options.width];
+ }
+ }
+
if (options.quality && typeof options.quality === 'string') {
options.quality = options.quality in qualityTable ? qualityTable[options.quality] : undefined;
}
diff --git a/packages/integrations/vercel/src/index.ts b/packages/integrations/vercel/src/index.ts
index 9db18f95b..d382ed766 100644
--- a/packages/integrations/vercel/src/index.ts
+++ b/packages/integrations/vercel/src/index.ts
@@ -241,6 +241,7 @@ export default function vercelAdapter({
command,
devImageService,
config.image,
+ config.experimental.responsiveImages,
),
});
},
diff --git a/packages/integrations/vercel/test/fixtures/image/astro.config.mjs b/packages/integrations/vercel/test/fixtures/image/astro.config.mjs
index ec1fb91f0..5c4aa7709 100644
--- a/packages/integrations/vercel/test/fixtures/image/astro.config.mjs
+++ b/packages/integrations/vercel/test/fixtures/image/astro.config.mjs
@@ -3,7 +3,12 @@ import { defineConfig } from 'astro/config';
import { testImageService } from '../../test-image-service.js';
export default defineConfig({
- adapter: vercel({ imageService: true }),
+ adapter: vercel({
+ imageService: true,
+ }),
+ experimental: {
+ responsiveImages: true,
+ },
image: {
service: testImageService(),
domains: ['astro.build'],
diff --git a/packages/integrations/vercel/test/fixtures/image/src/assets/penguin.jpg b/packages/integrations/vercel/test/fixtures/image/src/assets/penguin.jpg
new file mode 100644
index 000000000..73f0ee316
--- /dev/null
+++ b/packages/integrations/vercel/test/fixtures/image/src/assets/penguin.jpg
Binary files differ
diff --git a/packages/integrations/vercel/test/fixtures/image/src/pages/index.astro b/packages/integrations/vercel/test/fixtures/image/src/pages/index.astro
index db7c22eeb..b4dff7143 100644
--- a/packages/integrations/vercel/test/fixtures/image/src/pages/index.astro
+++ b/packages/integrations/vercel/test/fixtures/image/src/pages/index.astro
@@ -2,6 +2,7 @@
import { Image } from "astro:assets";
import astro from "../assets/astro.jpeg";
import penguin from "../assets/penguin.svg";
+import bigPenguin from "../assets/penguin.jpg";
---
<div id="basic-image">
@@ -11,3 +12,7 @@ import penguin from "../assets/penguin.svg";
<div id="svg">
<Image src={penguin} alt="Astro" />
</div>
+
+<div id="responsive">
+ <Image src={bigPenguin} alt="Astro" layout="responsive" width="1000" />
+</div>
diff --git a/packages/integrations/vercel/test/image.test.js b/packages/integrations/vercel/test/image.test.js
index 6def54086..f5dac6d86 100644
--- a/packages/integrations/vercel/test/image.test.js
+++ b/packages/integrations/vercel/test/image.test.js
@@ -74,5 +74,16 @@ describe('Image', () => {
assert.equal(res.status, 200);
assert.equal(res.headers.get('content-type'), 'image/svg+xml');
});
+
+ it('generates valid srcset for responsive images', async () => {
+ const html = await fixture.fetch('/').then((res) => res.text());
+ const $ = cheerio.load(html);
+ const img = $('#responsive img');
+ const widths = img
+ .attr('srcset')
+ .split(', ')
+ .map((entry) => entry.split(' ')[1]);
+ assert.deepEqual(widths, ['640w', '750w', '828w', '1080w', '1200w', '1920w']);
+ });
});
});