diff options
author | 2025-03-03 14:32:04 +0000 | |
---|---|---|
committer | 2025-03-03 14:32:04 +0000 | |
commit | fac32ad98d66b73382f35d26a69352e566cd94d9 (patch) | |
tree | f0cff234e33a2d9afd69b5f605b579d5a417df52 | |
parent | 21c233c3c9398aa3dbdfb612391617ef31a6ea63 (diff) | |
download | astro-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.md | 5 | ||||
-rw-r--r-- | packages/integrations/vercel/src/image/shared.ts | 14 | ||||
-rw-r--r-- | packages/integrations/vercel/src/index.ts | 1 | ||||
-rw-r--r-- | packages/integrations/vercel/test/fixtures/image/astro.config.mjs | 7 | ||||
-rw-r--r-- | packages/integrations/vercel/test/fixtures/image/src/assets/penguin.jpg | bin | 0 -> 258734 bytes | |||
-rw-r--r-- | packages/integrations/vercel/test/fixtures/image/src/pages/index.astro | 5 | ||||
-rw-r--r-- | packages/integrations/vercel/test/image.test.js | 11 |
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 Binary files differnew file mode 100644 index 000000000..73f0ee316 --- /dev/null +++ b/packages/integrations/vercel/test/fixtures/image/src/assets/penguin.jpg 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']); + }); }); }); |