From 06a6fcfaf6fd1549d5380118594fffa29b34e7c6 Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Sun, 10 May 2026 21:10:50 +0900 Subject: [PATCH 1/5] test: when dimmension is 0 --- packages/astro/test/core-image-svg.test.ts | 31 +++++++++++++++++++ .../core-image-svg/src/assets/zero.svg | 7 +++++ .../pages/metadata-zero-dimensions.json.ts | 4 +++ .../src/pages/zero-dimensions.astro | 10 ++++++ 4 files changed, 52 insertions(+) create mode 100644 packages/astro/test/fixtures/core-image-svg/src/assets/zero.svg create mode 100644 packages/astro/test/fixtures/core-image-svg/src/pages/metadata-zero-dimensions.json.ts create mode 100644 packages/astro/test/fixtures/core-image-svg/src/pages/zero-dimensions.astro diff --git a/packages/astro/test/core-image-svg.test.ts b/packages/astro/test/core-image-svg.test.ts index 8b15ddb1922f..4a5a9585c322 100644 --- a/packages/astro/test/core-image-svg.test.ts +++ b/packages/astro/test/core-image-svg.test.ts @@ -150,6 +150,37 @@ describe('astro:assets - SVG Components', () => { assert.ok(json.image.src.startsWith('/')); }); }); + + // test for the components has no dimensions and the metadata is correct + describe('Metadata with zero dimensions svg image', () => { + it('successfully processes SVG with width="0" and height="0"', async () => { + const res = await fixture.fetch('/zero-dimensions'); + assert.equal(res.status, 200); + + const html = await res.text(); + const $ = cheerio.load(html, { xml: true }); + + const $svg = $('#zero-svg svg'); + // svg should be rendered with the width and height of 0 as specified in the source file, not overridden by default dimensions + assert.equal($svg.length, 1); + assert.equal($svg.attr('width'), '0'); + assert.equal($svg.attr('height'), '0'); + }); + + it('successfully returns metadata for an SVG image with zero dimensions', async () => { + const res = await fixture.fetch('/metadata-zero-dimensions.json'); + const json = await res.json(); + + assert.equal(json.image.width, 0); + assert.equal(json.image.height, 0); + assert.equal(json.image.format, 'svg'); + }); + + it('should not log NoImageMetadata errors for zero dimension svgs', () => { + const hasMetadataErrors = logs.some(log => log.message.includes('NoImageMetadata')); + assert.equal(hasMetadataErrors, false); + }) + }); }); describe('SVGO optimization', () => { diff --git a/packages/astro/test/fixtures/core-image-svg/src/assets/zero.svg b/packages/astro/test/fixtures/core-image-svg/src/assets/zero.svg new file mode 100644 index 000000000000..32a4e229e819 --- /dev/null +++ b/packages/astro/test/fixtures/core-image-svg/src/assets/zero.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/astro/test/fixtures/core-image-svg/src/pages/metadata-zero-dimensions.json.ts b/packages/astro/test/fixtures/core-image-svg/src/pages/metadata-zero-dimensions.json.ts new file mode 100644 index 000000000000..988859e45051 --- /dev/null +++ b/packages/astro/test/fixtures/core-image-svg/src/pages/metadata-zero-dimensions.json.ts @@ -0,0 +1,4 @@ +import type { APIRoute } from 'astro'; +import image from '../assets/zero.svg'; + +export const GET: APIRoute = async () => Response.json({ image }); diff --git a/packages/astro/test/fixtures/core-image-svg/src/pages/zero-dimensions.astro b/packages/astro/test/fixtures/core-image-svg/src/pages/zero-dimensions.astro new file mode 100644 index 000000000000..21dc3c7167d2 --- /dev/null +++ b/packages/astro/test/fixtures/core-image-svg/src/pages/zero-dimensions.astro @@ -0,0 +1,10 @@ +--- +import ZeroSvg from '../assets/zero.svg'; +--- + + +
+ +
+ + From d4914f42741a11887458d2450538a4f079e4c0f1 Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Sun, 10 May 2026 21:11:46 +0900 Subject: [PATCH 2/5] allow svg impoerts with zero dimmention --- packages/astro/src/assets/utils/metadata.ts | 2 +- packages/astro/src/assets/utils/vendor/image-size/types/svg.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/astro/src/assets/utils/metadata.ts b/packages/astro/src/assets/utils/metadata.ts index 5ac51fe2956f..b4d0b4975596 100644 --- a/packages/astro/src/assets/utils/metadata.ts +++ b/packages/astro/src/assets/utils/metadata.ts @@ -23,7 +23,7 @@ export async function imageMetadata( message: AstroErrorData.NoImageMetadata.message(src), }); } - if (!result.height || !result.width || !result.type) { + if (result.height === null || result.width === null || !result.type) { throw new AstroError({ ...AstroErrorData.NoImageMetadata, message: AstroErrorData.NoImageMetadata.message(src), diff --git a/packages/astro/src/assets/utils/vendor/image-size/types/svg.ts b/packages/astro/src/assets/utils/vendor/image-size/types/svg.ts index 3f43a7b13a96..086d8022cccb 100644 --- a/packages/astro/src/assets/utils/vendor/image-size/types/svg.ts +++ b/packages/astro/src/assets/utils/vendor/image-size/types/svg.ts @@ -95,7 +95,7 @@ export const SVG: IImage = { const root = extractorRegExps.root.exec(toUTF8String(input)) if (root) { const attrs = parseAttributes(root[0]) - if (attrs.width && attrs.height) { + if (attrs.width !== null && attrs.height !== null) { return calculateByDimensions(attrs) } if (attrs.viewbox) { From 32b0b9977209a5913e25d6e509ec62c369a66010 Mon Sep 17 00:00:00 2001 From: OfirHaf Date: Sun, 10 May 2026 09:44:56 +0300 Subject: [PATCH 3/5] fix(assets): treat SVG width/height of zero as valid dimensions When an SVG has explicit width="0" or height="0" attributes, the image metadata extraction threw a NoImageMetadata error because both check sites used JavaScript truthiness tests where 0 is falsy. In vendor/image-size/types/svg.ts, the calculate() function fell through the explicit-dimensions path when either dimension was 0 and then hit the TypeError('Invalid SVG') throw. In assets/utils/metadata.ts, the post-probe guard also rejected 0 via the !result.height || !result.width condition. Using 0 for width/height is a valid and recommended pattern for SVG filter containers that should be hidden from screen readers: Fix: change both truthiness checks to null checks so that 0 is accepted as an explicit dimension while null/undefined still signal a missing value. Fixes #16633 --- packages/astro/src/assets/utils/metadata.ts | 2 +- packages/astro/src/assets/utils/vendor/image-size/types/svg.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/astro/src/assets/utils/metadata.ts b/packages/astro/src/assets/utils/metadata.ts index b4d0b4975596..6ef850234323 100644 --- a/packages/astro/src/assets/utils/metadata.ts +++ b/packages/astro/src/assets/utils/metadata.ts @@ -23,7 +23,7 @@ export async function imageMetadata( message: AstroErrorData.NoImageMetadata.message(src), }); } - if (result.height === null || result.width === null || !result.type) { + if (result.height == null || result.width == null || !result.type) { throw new AstroError({ ...AstroErrorData.NoImageMetadata, message: AstroErrorData.NoImageMetadata.message(src), diff --git a/packages/astro/src/assets/utils/vendor/image-size/types/svg.ts b/packages/astro/src/assets/utils/vendor/image-size/types/svg.ts index 086d8022cccb..7965eb441c6c 100644 --- a/packages/astro/src/assets/utils/vendor/image-size/types/svg.ts +++ b/packages/astro/src/assets/utils/vendor/image-size/types/svg.ts @@ -95,7 +95,7 @@ export const SVG: IImage = { const root = extractorRegExps.root.exec(toUTF8String(input)) if (root) { const attrs = parseAttributes(root[0]) - if (attrs.width !== null && attrs.height !== null) { + if (attrs.width != null && attrs.height != null) { return calculateByDimensions(attrs) } if (attrs.viewbox) { From ca7a65fcd618cc6fec4a8b7b9804a0a90928a612 Mon Sep 17 00:00:00 2001 From: OfirHaf Date: Sun, 10 May 2026 11:51:17 +0300 Subject: [PATCH 4/5] chore: add changeset for SVG zero-dimension fix --- .changeset/wet-steaks-repeat.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wet-steaks-repeat.md diff --git a/.changeset/wet-steaks-repeat.md b/.changeset/wet-steaks-repeat.md new file mode 100644 index 000000000000..ff689cd066bf --- /dev/null +++ b/.changeset/wet-steaks-repeat.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fixes an issue where SVG images with `width="0"` or `height="0"` incorrectly threw a `NoImageMetadata` error instead of being treated as valid dimensions. From 5163e3e70d6746efdc9c937a262a90da387dfa6a Mon Sep 17 00:00:00 2001 From: dotnetCarpenter Date: Tue, 12 May 2026 00:23:20 +0200 Subject: [PATCH 5/5] fix indentations in test file --- packages/astro/test/core-image-svg.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/astro/test/core-image-svg.test.ts b/packages/astro/test/core-image-svg.test.ts index 4a5a9585c322..d72d4ca57cb1 100644 --- a/packages/astro/test/core-image-svg.test.ts +++ b/packages/astro/test/core-image-svg.test.ts @@ -154,18 +154,18 @@ describe('astro:assets - SVG Components', () => { // test for the components has no dimensions and the metadata is correct describe('Metadata with zero dimensions svg image', () => { it('successfully processes SVG with width="0" and height="0"', async () => { - const res = await fixture.fetch('/zero-dimensions'); + const res = await fixture.fetch('/zero-dimensions'); assert.equal(res.status, 200); const html = await res.text(); - const $ = cheerio.load(html, { xml: true }); + const $ = cheerio.load(html, { xml: true }); - const $svg = $('#zero-svg svg'); + const $svg = $('#zero-svg svg'); // svg should be rendered with the width and height of 0 as specified in the source file, not overridden by default dimensions assert.equal($svg.length, 1); - assert.equal($svg.attr('width'), '0'); - assert.equal($svg.attr('height'), '0'); - }); + assert.equal($svg.attr('width'), '0'); + assert.equal($svg.attr('height'), '0'); + }); it('successfully returns metadata for an SVG image with zero dimensions', async () => { const res = await fixture.fetch('/metadata-zero-dimensions.json');