From 350c1b258292c15a14b92f19b9770e63d876fccb Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Fri, 9 Jan 2026 16:00:35 +0900 Subject: [PATCH 1/8] add support for SVG rasterization --- .changeset/common-signs-punch.md | 5 +++++ packages/astro/src/assets/services/noop.ts | 8 +------- packages/astro/src/assets/services/service.ts | 5 +---- packages/astro/src/assets/services/sharp.ts | 4 ---- 4 files changed, 7 insertions(+), 15 deletions(-) create mode 100644 .changeset/common-signs-punch.md diff --git a/.changeset/common-signs-punch.md b/.changeset/common-signs-punch.md new file mode 100644 index 000000000000..d1d2badefefe --- /dev/null +++ b/.changeset/common-signs-punch.md @@ -0,0 +1,5 @@ +--- +'astro': minor +--- + +The built-in image service now supports converting SVG images to raster formats. diff --git a/packages/astro/src/assets/services/noop.ts b/packages/astro/src/assets/services/noop.ts index 471edc652410..cbcf348ae62b 100644 --- a/packages/astro/src/assets/services/noop.ts +++ b/packages/astro/src/assets/services/noop.ts @@ -1,4 +1,3 @@ -import { isESMImportedImage } from '../utils/imageKind.js'; import { baseService, type LocalImageService, verifyOptions } from './service.js'; // Empty service used for platforms that don't support Sharp / users who don't want transformations. @@ -6,12 +5,7 @@ const noopService: LocalImageService = { ...baseService, propertiesToHash: ['src'], async validateOptions(options) { - if (isESMImportedImage(options.src) && options.src.format === 'svg') { - options.format = 'svg'; - } else { - delete options.format; - } - + delete options.format; verifyOptions(options); return options; diff --git a/packages/astro/src/assets/services/service.ts b/packages/astro/src/assets/services/service.ts index 0ce8fbd4c338..b4935001c641 100644 --- a/packages/astro/src/assets/services/service.ts +++ b/packages/astro/src/assets/services/service.ts @@ -185,10 +185,7 @@ export function verifyOptions(options: ImageTransform): void { throw new AstroError(AstroErrorData.IncompatibleDescriptorOptions); } - if ( - (options.src.format === 'svg' && options.format !== 'svg') || - (options.src.format !== 'svg' && options.format === 'svg') - ) { + if (options.src.format !== 'svg' && options.format === 'svg') { throw new AstroError(AstroErrorData.UnsupportedImageConversion); } } diff --git a/packages/astro/src/assets/services/sharp.ts b/packages/astro/src/assets/services/sharp.ts index ccc909b68f6c..c666b9e0d47e 100644 --- a/packages/astro/src/assets/services/sharp.ts +++ b/packages/astro/src/assets/services/sharp.ts @@ -58,10 +58,6 @@ const sharpService: LocalImageService = { if (!sharp) sharp = await loadSharp(); const transform: BaseServiceTransform = transformOptions as BaseServiceTransform; - // Return SVGs as-is - // TODO: Sharp has some support for SVGs, we could probably support this once Sharp is the default and only service. - if (transform.format === 'svg') return { data: inputBuffer, format: 'svg' }; - const result = sharp(inputBuffer, { failOnError: false, pages: -1, From 1ef19c1ffcb75816c15497f5837f7f893528a17d Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Fri, 9 Jan 2026 20:27:19 +0900 Subject: [PATCH 2/8] revert change to noop service --- packages/astro/src/assets/services/noop.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/assets/services/noop.ts b/packages/astro/src/assets/services/noop.ts index cbcf348ae62b..471edc652410 100644 --- a/packages/astro/src/assets/services/noop.ts +++ b/packages/astro/src/assets/services/noop.ts @@ -1,3 +1,4 @@ +import { isESMImportedImage } from '../utils/imageKind.js'; import { baseService, type LocalImageService, verifyOptions } from './service.js'; // Empty service used for platforms that don't support Sharp / users who don't want transformations. @@ -5,7 +6,12 @@ const noopService: LocalImageService = { ...baseService, propertiesToHash: ['src'], async validateOptions(options) { - delete options.format; + if (isESMImportedImage(options.src) && options.src.format === 'svg') { + options.format = 'svg'; + } else { + delete options.format; + } + verifyOptions(options); return options; From 1574aac379bc4282031d6a2caa4eaa426adf2dae Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Fri, 9 Jan 2026 23:01:12 +0900 Subject: [PATCH 3/8] removed forgotten check --- packages/astro/src/assets/services/service.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/astro/src/assets/services/service.ts b/packages/astro/src/assets/services/service.ts index b4935001c641..748525e0b9aa 100644 --- a/packages/astro/src/assets/services/service.ts +++ b/packages/astro/src/assets/services/service.ts @@ -213,11 +213,6 @@ export function verifyOptions(options: ImageTransform): void { export const baseService: Omit = { propertiesToHash: DEFAULT_HASH_PROPS, validateOptions(options) { - // We currently do not support processing SVGs, so whenever the input format is a SVG, force the output to also be one - if (isESMImportedImage(options.src) && options.src.format === 'svg') { - options.format = 'svg'; - } - // Run verification-only checks verifyOptions(options); From 1b4c100725219882598ba776a68f1b99cd42254e Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Fri, 9 Jan 2026 23:45:44 +0900 Subject: [PATCH 4/8] revert code I mistakenly removed --- packages/astro/src/assets/services/sharp.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/astro/src/assets/services/sharp.ts b/packages/astro/src/assets/services/sharp.ts index c666b9e0d47e..ccc909b68f6c 100644 --- a/packages/astro/src/assets/services/sharp.ts +++ b/packages/astro/src/assets/services/sharp.ts @@ -58,6 +58,10 @@ const sharpService: LocalImageService = { if (!sharp) sharp = await loadSharp(); const transform: BaseServiceTransform = transformOptions as BaseServiceTransform; + // Return SVGs as-is + // TODO: Sharp has some support for SVGs, we could probably support this once Sharp is the default and only service. + if (transform.format === 'svg') return { data: inputBuffer, format: 'svg' }; + const result = sharp(inputBuffer, { failOnError: false, pages: -1, From 3f972ecc06bf86303216ce0eb54fbf1d5baf978d Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Sat, 10 Jan 2026 00:05:21 +0900 Subject: [PATCH 5/8] fixes default format for SVG --- packages/astro/src/assets/services/service.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/assets/services/service.ts b/packages/astro/src/assets/services/service.ts index 748525e0b9aa..5f831bdfc26b 100644 --- a/packages/astro/src/assets/services/service.ts +++ b/packages/astro/src/assets/services/service.ts @@ -218,7 +218,11 @@ export const baseService: Omit = { // Apply defaults and normalization separate from verification if (!options.format) { - options.format = DEFAULT_OUTPUT_FORMAT; + if (isESMImportedImage(options.src) && options.src.format === 'svg') { + options.format = 'svg'; + } else { + options.format = DEFAULT_OUTPUT_FORMAT; + } } if (options.width) options.width = Math.round(options.width); if (options.height) options.height = Math.round(options.height); From 2b34a396655c1f0f4a87045efe699bf1ff8418a0 Mon Sep 17 00:00:00 2001 From: Erika <3019731+Princesseuh@users.noreply.github.com> Date: Mon, 12 Jan 2026 18:12:20 +0100 Subject: [PATCH 6/8] Update .changeset/common-signs-punch.md Co-authored-by: Chris Swithinbank --- .changeset/common-signs-punch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/common-signs-punch.md b/.changeset/common-signs-punch.md index d1d2badefefe..789f91b9e66d 100644 --- a/.changeset/common-signs-punch.md +++ b/.changeset/common-signs-punch.md @@ -1,5 +1,5 @@ --- -'astro': minor +'astro': major --- The built-in image service now supports converting SVG images to raster formats. From 16066c837519f6df9c5dd63ef800944e2f84c880 Mon Sep 17 00:00:00 2001 From: Princesseuh <3019731+Princesseuh@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:08:59 +0100 Subject: [PATCH 7/8] chore: changeset --- .changeset/common-signs-punch.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.changeset/common-signs-punch.md b/.changeset/common-signs-punch.md index 789f91b9e66d..050c5b65559f 100644 --- a/.changeset/common-signs-punch.md +++ b/.changeset/common-signs-punch.md @@ -2,4 +2,12 @@ 'astro': major --- -The built-in image service now supports converting SVG images to raster formats. +Adds support for converting SVGs to raster images (PNGs, WebP, etc) to the default Sharp image service. + +Previously, the following code would have silently ignored the `format` property and the result would remain a SVG: + +```astro + +``` + +After this update, this will now result in an AVIF file being generated. From a37ecd35b77d3f4cc337e3841be8ab74cf62db9b Mon Sep 17 00:00:00 2001 From: Erika <3019731+Princesseuh@users.noreply.github.com> Date: Fri, 23 Jan 2026 13:20:55 +0100 Subject: [PATCH 8/8] Apply suggestions from code review Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com> --- .changeset/common-signs-punch.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.changeset/common-signs-punch.md b/.changeset/common-signs-punch.md index 050c5b65559f..199a795992d7 100644 --- a/.changeset/common-signs-punch.md +++ b/.changeset/common-signs-punch.md @@ -2,12 +2,4 @@ 'astro': major --- -Adds support for converting SVGs to raster images (PNGs, WebP, etc) to the default Sharp image service. - -Previously, the following code would have silently ignored the `format` property and the result would remain a SVG: - -```astro - -``` - -After this update, this will now result in an AVIF file being generated. +Adds support for converting SVGs to raster images (PNGs, WebP, etc) to the default Sharp image service - ([v6 upgrade guidance](https://v6.docs.astro.build/en/guides/upgrade-to/v6/#changed-svg-rasterization))