diff --git a/.changeset/swift-wolves-argue.md b/.changeset/swift-wolves-argue.md new file mode 100644 index 000000000..af8bff1fb --- /dev/null +++ b/.changeset/swift-wolves-argue.md @@ -0,0 +1,5 @@ +--- +'@astrojs/image': patch +--- + +Fixes a bug related to filenames for remote images in SSG builds diff --git a/packages/integrations/image/components/Image.astro b/packages/integrations/image/components/Image.astro index 1777fffab..578db702d 100644 --- a/packages/integrations/image/components/Image.astro +++ b/packages/integrations/image/components/Image.astro @@ -17,7 +17,7 @@ interface RemoteImageProps extends TransformOptions, astroHTML.JSX.ImgHTMLAttrib src: string; /** Defines an alternative text description of the image. Set to an empty string (alt="") if the image is not a key part of the content (it's decoration or a tracking pixel). */ alt: string; - format: OutputFormat; + format?: OutputFormat; width: number; height: number; } diff --git a/packages/integrations/image/src/lib/get-picture.ts b/packages/integrations/image/src/lib/get-picture.ts index 652afb49d..6895891f0 100644 --- a/packages/integrations/image/src/lib/get-picture.ts +++ b/packages/integrations/image/src/lib/get-picture.ts @@ -36,7 +36,7 @@ async function resolveFormats({ src, formats }: GetPictureParams) { unique.add(extname(metadata.src).replace('.', '') as OutputFormat); } - return [...unique]; + return Array.from(unique).filter(Boolean); } export async function getPicture(params: GetPictureParams): Promise { diff --git a/packages/integrations/image/src/utils/paths.ts b/packages/integrations/image/src/utils/paths.ts index cf62ba0cf..2f4109062 100644 --- a/packages/integrations/image/src/utils/paths.ts +++ b/packages/integrations/image/src/utils/paths.ts @@ -14,7 +14,7 @@ function extname(src: string, format?: OutputFormat) { const index = src.lastIndexOf('.'); if (index <= 0) { - return undefined; + return ''; } return src.substring(index); @@ -38,11 +38,12 @@ export function propsToFilename(transform: TransformOptions) { // strip off the querystring first, then remove the file extension let filename = removeQueryString(transform.src); filename = basename(filename); + const ext = extname(filename); filename = removeExtname(filename); - const ext = transform.format || extname(transform.src)?.substring(1); + const outputExt = transform.format ? `.${transform.format}` : ext - return `/${filename}_${shorthash(JSON.stringify(transform))}.${ext}`; + return `/${filename}_${shorthash(JSON.stringify(transform))}${outputExt}`; } export function appendForwardSlash(path: string) { diff --git a/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro b/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro index 6b203591b..02d33b1c8 100644 --- a/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro +++ b/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro @@ -20,5 +20,7 @@ import { Image } from '@astrojs/image/components'; inline
query +
+ ipsum diff --git a/packages/integrations/image/test/fixtures/basic-picture/src/pages/index.astro b/packages/integrations/image/test/fixtures/basic-picture/src/pages/index.astro index 68db37012..0ab9d211d 100644 --- a/packages/integrations/image/test/fixtures/basic-picture/src/pages/index.astro +++ b/packages/integrations/image/test/fixtures/basic-picture/src/pages/index.astro @@ -12,8 +12,10 @@ import { Picture } from '@astrojs/image/components';

- +
+
+ diff --git a/packages/integrations/image/test/image-ssg.test.js b/packages/integrations/image/test/image-ssg.test.js index 04d62125d..386dc9b07 100644 --- a/packages/integrations/image/test/image-ssg.test.js +++ b/packages/integrations/image/test/image-ssg.test.js @@ -50,6 +50,16 @@ describe('SSG images - dev', function () { href: 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png', }, }, + { + title: 'Remote without file extension', + id: '#ipsum', + url: '/_image', + query: { + w: '200', + h: '300', + href: 'https://picsum.photos/200/300' + } + }, { title: 'Public images', id: '#hero', @@ -120,6 +130,17 @@ describe('SSG images with subpath - dev', function () { href: 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png', }, }, + + { + title: 'Remote without file extension', + id: '#ipsum', + url: '/_image', + query: { + w: '200', + h: '300', + href: 'https://picsum.photos/200/300' + } + }, { title: 'Public images', id: '#hero', @@ -189,6 +210,12 @@ describe('SSG images - build', function () { regex: /^\/googlelogo_color_272x92dp_\w{4,10}.webp/, size: { width: 544, height: 184, type: 'webp' }, }, + { + title: 'Remote without file extension', + id: '#ipsum', + regex: /^\/300_\w{4,10}/, + size: { width: 200, height: 300, type: 'jpg' }, + }, { title: 'Public images', id: '#hero', @@ -253,6 +280,12 @@ describe('SSG images with subpath - build', function () { regex: /^\/docs\/googlelogo_color_272x92dp_\w{4,10}.webp/, size: { width: 544, height: 184, type: 'webp' }, }, + { + title: 'Remote without file extension', + id: '#ipsum', + regex: /^\/docs\/300_\w{4,10}/, + size: { width: 200, height: 300, type: 'jpg' }, + }, { title: 'Public images', id: '#hero', diff --git a/packages/integrations/image/test/image-ssr-build.test.js b/packages/integrations/image/test/image-ssr-build.test.js index d3b05a44b..8a0f2529f 100644 --- a/packages/integrations/image/test/image-ssr-build.test.js +++ b/packages/integrations/image/test/image-ssr-build.test.js @@ -45,6 +45,16 @@ describe('SSR images - build', async function () { href: 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png', }, }, + { + title: 'Remote without file extension', + id: '#ipsum', + url: '/_image', + query: { + w: '200', + h: '300', + href: 'https://picsum.photos/200/300', + }, + }, { title: 'Remote images with search', id: '#query', @@ -139,6 +149,16 @@ describe('SSR images with subpath - build', function () { href: 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png', }, }, + { + title: 'Remote without file extension', + id: '#ipsum', + url: '/_image', + query: { + w: '200', + h: '300', + href: 'https://picsum.photos/200/300', + }, + }, { title: 'Remote images with search', id: '#query', diff --git a/packages/integrations/image/test/image-ssr-dev.test.js b/packages/integrations/image/test/image-ssr-dev.test.js index a280268d0..2251bf071 100644 --- a/packages/integrations/image/test/image-ssr-dev.test.js +++ b/packages/integrations/image/test/image-ssr-dev.test.js @@ -58,6 +58,17 @@ describe('SSR images - dev', function () { }, contentType: 'image/webp', }, + { + title: 'Remote wihtout file extension', + id: '#ipsum', + url: '/_image', + query: { + w: '200', + h: '300', + href: 'https://picsum.photos/200/300', + }, + contentType: 'image/jpeg', + }, { title: 'Public images', id: '#hero', @@ -149,6 +160,17 @@ describe('SSR images with subpath - dev', function () { }, contentType: 'image/webp', }, + { + title: 'Remote wihtout file extension', + id: '#ipsum', + url: '/_image', + query: { + w: '200', + h: '300', + href: 'https://picsum.photos/200/300', + }, + contentType: 'image/jpeg', + }, { title: 'Public images', id: '#hero', diff --git a/packages/integrations/image/test/picture-ssg.test.js b/packages/integrations/image/test/picture-ssg.test.js index 2a7f86c21..5ecf08800 100644 --- a/packages/integrations/image/test/picture-ssg.test.js +++ b/packages/integrations/image/test/picture-ssg.test.js @@ -200,6 +200,13 @@ describe('SSG pictures - build', function () { size: { width: 544, height: 184, type: 'png' }, alt: 'Google logo', }, + { + title: 'Remote without file extension', + id: '#ipsum', + regex: /^\/300_\w{4,10}/, + size: { width: 200, height: 300, type: 'jpg' }, + alt: 'ipsum', + }, { title: 'Public images', id: '#hero', @@ -288,6 +295,13 @@ describe('SSG pictures with subpath - build', function () { size: { width: 544, height: 184, type: 'png' }, alt: 'Google logo', }, + { + title: 'Remote without file extension', + id: '#ipsum', + regex: /^\/docs\/300_\w{4,10}/, + size: { width: 200, height: 300, type: 'jpg' }, + alt: 'ipsum', + }, { title: 'Public images', id: '#hero', diff --git a/packages/integrations/image/test/picture-ssr-build.test.js b/packages/integrations/image/test/picture-ssr-build.test.js index 15e884aad..ff6c8440e 100644 --- a/packages/integrations/image/test/picture-ssr-build.test.js +++ b/packages/integrations/image/test/picture-ssr-build.test.js @@ -42,6 +42,17 @@ describe('SSR pictures - build', function () { }, alt: 'Google logo', }, + { + title: 'Remote without file extension', + id: '#ipsum', + url: '/_image', + query: { + w: '200', + h: '300', + href: 'https://picsum.photos/200/300', + }, + alt: 'ipsum', + }, { title: 'Public images', id: '#hero', @@ -122,6 +133,17 @@ describe('SSR pictures with subpath - build', function () { }, alt: 'Google logo', }, + { + title: 'Remote without file extension', + id: '#ipsum', + url: '/_image', + query: { + w: '200', + h: '300', + href: 'https://picsum.photos/200/300', + }, + alt: 'ipsum', + }, { title: 'Public images', id: '#hero', diff --git a/packages/integrations/image/test/picture-ssr-dev.test.js b/packages/integrations/image/test/picture-ssr-dev.test.js index ac1d3e638..fa465384d 100644 --- a/packages/integrations/image/test/picture-ssr-dev.test.js +++ b/packages/integrations/image/test/picture-ssr-dev.test.js @@ -54,6 +54,19 @@ describe('SSR pictures - dev', function () { contentType: 'image/png', alt: 'Google logo', }, + { + title: 'Remote without file extension', + id: '#ipsum', + url: '/_image', + query: { + f: 'jpg', + w: '200', + h: '300', + href: 'https://picsum.photos/200/300', + }, + contentType: 'image/jpeg', + alt: 'ipsum', + }, { title: 'Public images', id: '#hero', @@ -148,6 +161,19 @@ describe('SSR pictures with subpath - dev', function () { contentType: 'image/png', alt: 'Google logo', }, + { + title: 'Remote without file extension', + id: '#ipsum', + url: '/_image', + query: { + f: 'jpg', + w: '200', + h: '300', + href: 'https://picsum.photos/200/300', + }, + contentType: 'image/jpeg', + alt: 'ipsum', + },, { title: 'Public images', id: '#hero',