diff --git a/.changeset/clever-laws-lie.md b/.changeset/clever-laws-lie.md new file mode 100644 index 000000000..f5c3b328a --- /dev/null +++ b/.changeset/clever-laws-lie.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Add support for ESM importing SVGs when using `astro:assets` diff --git a/packages/astro/src/assets/services/service.ts b/packages/astro/src/assets/services/service.ts index 3e1275455..84d40c876 100644 --- a/packages/astro/src/assets/services/service.ts +++ b/packages/astro/src/assets/services/service.ts @@ -1,5 +1,6 @@ import { AstroError, AstroErrorData } from '../../core/errors/index.js'; import { isRemotePath } from '../../core/path.js'; +import { VALID_INPUT_FORMATS } from '../consts.js'; import { isESMImportedImage } from '../internal.js'; import { ImageTransform, OutputFormat } from '../types.js'; @@ -144,6 +145,20 @@ export const baseService: Omit = { return options.src; } + if ( + isESMImportedImage(options.src) && + !VALID_INPUT_FORMATS.includes(options.src.format as any) + ) { + throw new AstroError({ + ...AstroErrorData.UnsupportedImageFormat, + message: AstroErrorData.UnsupportedImageFormat.message( + options.src.format, + options.src.src, + VALID_INPUT_FORMATS + ), + }); + } + const searchParams = new URLSearchParams(); searchParams.append('href', isESMImportedImage(options.src) ? options.src.src : options.src); diff --git a/packages/astro/src/assets/vite-plugin-assets.ts b/packages/astro/src/assets/vite-plugin-assets.ts index 4fc8e9598..770e43400 100644 --- a/packages/astro/src/assets/vite-plugin-assets.ts +++ b/packages/astro/src/assets/vite-plugin-assets.ts @@ -197,7 +197,7 @@ export default function assets({ resolvedConfig = viteConfig; }, async load(id) { - if (/\.(heic|heif|avif|jpeg|jpg|png|tiff|webp|gif)$/.test(id)) { + if (/\.(jpeg|jpg|png|tiff|webp|gif|svg)$/.test(id)) { const url = pathToFileURL(id); const meta = await imageMetadata(url); diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index 6b353565e..9e4dd7b80 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -464,7 +464,7 @@ See https://docs.astro.build/en/guides/server-side-rendering/ for more informati title: 'Error while loading image service', code: 3023, message: - 'There was an error loading the configured image service. Please see the stack trace for more information', + 'There was an error loading the configured image service. Please see the stack trace for more information.', }, MissingImageDimension: { title: 'Missing image dimensions', @@ -474,6 +474,15 @@ See https://docs.astro.build/en/guides/server-side-rendering/ for more informati missingDimension === 'both' ? 'width and height are' : `${missingDimension} is` } required.`, }, + UnsupportedImageFormat: { + title: 'Unsupported image format', + code: 3025, + message: (format: string, imagePath: string, supportedFormats: readonly string[]) => + `Received unsupported format \`${format}\` from \`${imagePath}\`. Currently only ${supportedFormats.join( + ', ' + )} are supported for optimization.`, + hint: "If you do not need optimization, using an `img` tag directly instead of the `Image` component might be what you're looking for.", + }, // No headings here, that way Vite errors are merged with Astro ones in the docs, which makes more sense to users. // Vite Errors - 4xxx /** diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js index c4a6b4d5e..de950ddac 100644 --- a/packages/astro/test/core-image.test.js +++ b/packages/astro/test/core-image.test.js @@ -71,6 +71,16 @@ describe('astro:image', () => { let $img = $('#local img'); expect($img.attr('alt')).to.equal('a penguin'); }); + + it('errors on unsupported formats', async () => { + logs.length = 0; + let res = await fixture.fetch('/unsupported-format'); + await res.text(); + + expect(logs).to.have.a.lengthOf(1); + console.log(logs[0].message); + expect(logs[0].message).to.contain('Received unsupported format'); + }); }); describe('remote', () => { diff --git a/packages/astro/test/fixtures/core-image/src/assets/penguin.svg b/packages/astro/test/fixtures/core-image/src/assets/penguin.svg new file mode 100644 index 000000000..047e020e4 --- /dev/null +++ b/packages/astro/test/fixtures/core-image/src/assets/penguin.svg @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/astro/test/fixtures/core-image/src/pages/unsupported-format.astro b/packages/astro/test/fixtures/core-image/src/pages/unsupported-format.astro new file mode 100644 index 000000000..2d1f08b96 --- /dev/null +++ b/packages/astro/test/fixtures/core-image/src/pages/unsupported-format.astro @@ -0,0 +1,6 @@ +--- +import { Image } from "astro:assets"; +import tux from "../assets/penguin.svg"; +--- + +...