From c88d6ac5dc5b3c890592022fa67e655114be183b Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Fri, 9 Jan 2026 16:00:35 +0900 Subject: [PATCH 1/6] 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 857d35442feb..edaf7633aa07 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 4d4d9631d16b982d5be84f86d3fe9cd9e35e9b80 Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Fri, 9 Jan 2026 20:27:19 +0900 Subject: [PATCH 2/6] 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 e6a281b39a7e2da7068e6c73865430320714d353 Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Fri, 9 Jan 2026 23:01:12 +0900 Subject: [PATCH 3/6] 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 1bc29b9498c24c4054ae4dc9ca2ebfebd535e080 Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Fri, 9 Jan 2026 23:45:44 +0900 Subject: [PATCH 4/6] 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 edaf7633aa07..857d35442feb 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 7eb900cec4dc4fc0a95b63ce96311796867c7339 Mon Sep 17 00:00:00 2001 From: Julien Cayzac Date: Sat, 10 Jan 2026 00:05:21 +0900 Subject: [PATCH 5/6] 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 84289a003c0e974f604eb983b34363cc25aa67b4 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/6] 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.