diff options
-rw-r--r-- | .changeset/fifty-olives-end.md | 5 | ||||
-rw-r--r-- | packages/integrations/image/src/lib/get-picture.ts | 28 | ||||
-rw-r--r-- | packages/integrations/image/test/picture-ssg.test.js | 24 |
3 files changed, 43 insertions, 14 deletions
diff --git a/.changeset/fifty-olives-end.md b/.changeset/fifty-olives-end.md new file mode 100644 index 000000000..393418e66 --- /dev/null +++ b/.changeset/fifty-olives-end.md @@ -0,0 +1,5 @@ +--- +'@astrojs/image': patch +--- + +Share fallback img src with source of Picture component diff --git a/packages/integrations/image/src/lib/get-picture.ts b/packages/integrations/image/src/lib/get-picture.ts index 4149a93a2..d4deebb79 100644 --- a/packages/integrations/image/src/lib/get-picture.ts +++ b/packages/integrations/image/src/lib/get-picture.ts @@ -59,6 +59,13 @@ export async function getPicture(params: GetPictureParams): Promise<GetPictureRe throw new Error('`aspectRatio` must be provided for remote images'); } + // always include the original image format + const allFormats = await resolveFormats(params); + const lastFormat = allFormats[allFormats.length - 1]; + const maxWidth = Math.max(...widths); + + let image: astroHTML.JSX.ImgHTMLAttributes; + async function getSource(format: OutputFormat) { const imgs = await Promise.all( widths.map(async (width) => { @@ -69,8 +76,13 @@ export async function getPicture(params: GetPictureParams): Promise<GetPictureRe fit, position, background, - height: Math.round(width / aspectRatio!), + aspectRatio, }); + + if (format === lastFormat && width === maxWidth) { + image = img; + } + return `${img.src} ${width}w`; }) ); @@ -81,23 +93,11 @@ export async function getPicture(params: GetPictureParams): Promise<GetPictureRe }; } - // always include the original image format - const allFormats = await resolveFormats(params); - - const image = await getImage({ - src, - width: Math.max(...widths), - aspectRatio, - fit, - position, - background, - format: allFormats[allFormats.length - 1], - }); - const sources = await Promise.all(allFormats.map((format) => getSource(format))); return { sources, + // @ts-expect-error image will always be defined image, }; } diff --git a/packages/integrations/image/test/picture-ssg.test.js b/packages/integrations/image/test/picture-ssg.test.js index 9f0074b17..c14046220 100644 --- a/packages/integrations/image/test/picture-ssg.test.js +++ b/packages/integrations/image/test/picture-ssg.test.js @@ -381,3 +381,27 @@ describe('SSG pictures with subpath - build', function () { }); }); }); + +describe('SSG pictures others - build', function () { + let fixture; + let $; + let html; + + before(async () => { + fixture = await loadFixture({ root: './fixtures/basic-picture/' }); + await fixture.build(); + + html = await fixture.readFile('/index.html'); + $ = cheerio.load(html); + }); + + it('fallback image should share last source', async () => { + const hero = $('#hero'); + const picture = hero.closest('picture'); + + const source = picture.children('source').last(); + const image = picture.children('img').last(); + + expect(source.attr('srcset')).to.include(image.attr('src')); + }); +}); |