diff options
12 files changed, 153 insertions, 6 deletions
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<GetPictureResult> { 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'; <Image id="inline" src={import('../assets/social.jpg')} width={506} alt="inline" /> <br /> <Image id="query" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png?token=abc" width={544} height={184} format="webp" alt="query" /> + <br /> + <Image id="ipsum" src="https://picsum.photos/200/300" width={200} height={300} alt="ipsum" format="jpeg" /> </body> </html> 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'; <br /> <Picture id="social-jpg" src={socialJpg} sizes="(min-width: 640px) 50vw, 100vw" widths={[253, 506]} alt="Social image" /> <br /> - <Picture id="google" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" sizes="(min-width: 640px) 50vw, 100vw" widths={[272, 544]} aspectRatio={544/184} alt="Google logo" /> + <Picture id="google" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" sizes="(min-width: 640px) 50vw, 100vw" widths={[272, 544]} aspectRatio={544/184} alt="Google logo" formats={["avif", "webp", "png"]} /> <br /> <Picture id='inline' src={import('../assets/social.jpg')} sizes="(min-width: 640px) 50vw, 100vw" widths={[253, 506]} alt="Inline social image" /> + <br /> + <Picture id="ipsum" src="https://picsum.photos/200/300" sizes="100vw" widths={[100, 200]} aspectRatio={2/3} formats={["avif", "webp", "jpg"]} alt="ipsum" /> </body> </html> 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 @@ -51,6 +51,16 @@ describe('SSG images - dev', function () { }, }, { + 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', url: '/_image', @@ -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', @@ -190,6 +211,12 @@ describe('SSG images - build', function () { 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', regex: /^\/hero_\w{4,10}.webp/, @@ -254,6 +281,12 @@ describe('SSG images with subpath - build', function () { 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', regex: /^\/docs\/hero_\w{4,10}.webp/, 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 @@ -46,6 +46,16 @@ describe('SSR images - build', async function () { }, }, { + 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', url: '/_image', @@ -140,6 +150,16 @@ describe('SSR images with subpath - build', function () { }, }, { + 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', url: '/_image', 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 @@ -59,6 +59,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', url: '/_image', @@ -150,6 +161,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', url: '/_image', 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 @@ -201,6 +201,13 @@ describe('SSG pictures - build', function () { 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', regex: /^\/hero_\w{4,10}.jpg/, @@ -289,6 +296,13 @@ describe('SSG pictures with subpath - build', function () { 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', regex: /^\/docs\/hero_\w{4,10}.jpg/, 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 @@ -43,6 +43,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', url: '/_image', @@ -123,6 +134,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', url: '/_image', 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 @@ -55,6 +55,19 @@ describe('SSR pictures - dev', function () { 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', url: '/_image', @@ -149,6 +162,19 @@ describe('SSR pictures with subpath - dev', function () { 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', url: '/_image', |