From 6450ec07fe14dab7a83a08c1212209bb19497687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ce=CC=81dric=20Andrietti?= Date: Mon, 19 Oct 2026 12:54:19 +0200 Subject: [PATCH 1/6] fix(build): restrict production SVGO minimizer to SVG files Sharp already skips SVGs; without a matching filter, svgoMinify ran on raster assets and could fail or corrupt them during production builds. Co-authored-by: Cursor --- config/webpack.common.js | 1 + 1 file changed, 1 insertion(+) diff --git a/config/webpack.common.js b/config/webpack.common.js index 95a2983c..7300ba74 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -44,6 +44,7 @@ module.exports = { }, { implementation: ImageMinimizerPlugin.svgoMinify, + filter: (source, sourcePath) => /\.svg$/i.test(sourcePath), options: { encodeOptions: { multipass: true, From ce7f5f0b90cde0f24f0d8ff93624a1bb04d8e0b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ce=CC=81dric=20Andrietti?= Date: Mon, 19 Oct 2026 15:46:47 +0200 Subject: [PATCH 2/6] fix(svgo): drop prefixIds to keep sprite symbol IDs stable prefixIds renames symbol IDs during production SVGO minimization, which breaks icon sprites referenced as #icon-{slug} in PHP and markup. Co-authored-by: Cursor --- config/svgo.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/config/svgo.config.js b/config/svgo.config.js index efb68e56..42288fcb 100644 --- a/config/svgo.config.js +++ b/config/svgo.config.js @@ -10,6 +10,5 @@ module.exports = { // Plugins that are not in the "preset-default" and that you want to activate 'removeTitle', 'convertStyleToAttrs', - 'prefixIds', ], } From b518ada7423aac7e17c4f391d65f996a09da224d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ce=CC=81dric=20Andrietti?= Date: Mon, 19 Oct 2026 15:59:17 +0200 Subject: [PATCH 3/6] fix(build): skip prod SVGO on extracted sprite sheets under dist/icons Production SVGO on merged sprite SVGs collapses symbols; icons are already optimized via svgo-loader at compile time. Matches BBT sprite workflow. Co-authored-by: Cursor --- config/webpack.common.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/config/webpack.common.js b/config/webpack.common.js index 7300ba74..116fd96b 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -44,7 +44,18 @@ module.exports = { }, { implementation: ImageMinimizerPlugin.svgoMinify, - filter: (source, sourcePath) => /\.svg$/i.test(sourcePath), + filter: (source, sourcePath) => { + if (!/\.svg$/i.test(sourcePath)) { + return false + } + + // svg-sprite-loader extract: dist/icons/{sprite}.svg — prod SVGO breaks entries. + if (/[/\\]icons[/\\][^/\\]+\.svg$/i.test(sourcePath)) { + return false + } + + return true + }, options: { encodeOptions: { multipass: true, From 07419a0b320c6008b74e67e9523ff8be2b6712e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ce=CC=81dric=20Andrietti?= Date: Mon, 19 Oct 2026 16:21:50 +0200 Subject: [PATCH 4/6] fix(build): skip SVGO for icons/ asset paths Match webpack extract names like icons/sprite.svg so prod minify does not empty sprite sheets. Co-authored-by: Cursor --- config/webpack.common.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/webpack.common.js b/config/webpack.common.js index 116fd96b..1b24a244 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -49,8 +49,9 @@ module.exports = { return false } - // svg-sprite-loader extract: dist/icons/{sprite}.svg — prod SVGO breaks entries. - if (/[/\\]icons[/\\][^/\\]+\.svg$/i.test(sourcePath)) { + // svg-sprite-loader extract publicPath is `icons/` — prod SVGO + // removes unused entries and empties sprite sheets. + if (/(?:^|[/\\])icons[/\\]/i.test(sourcePath)) { return false } From 80593dee154410ba1674a500ab9f553669cac4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ce=CC=81dric=20Andrietti?= Date: Mon, 19 Oct 2026 16:26:32 +0200 Subject: [PATCH 5/6] docs(build): clarify svgoMinify filter behavior Co-authored-by: Cursor --- config/webpack.common.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/config/webpack.common.js b/config/webpack.common.js index 1b24a244..915fda9c 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -44,13 +44,17 @@ module.exports = { }, { implementation: ImageMinimizerPlugin.svgoMinify, + // Return true to run SVGO on this asset, false to leave it unchanged. + // sourcePath is the webpack compilation asset name (e.g. icons/sprite.svg). filter: (source, sourcePath) => { + // Only SVG assets go through SVGO (raster images use sharpMinify above). if (!/\.svg$/i.test(sourcePath)) { return false } - // svg-sprite-loader extract publicPath is `icons/` — prod SVGO - // removes unused entries and empties sprite sheets. + // Skip extracted sprite sheets under icons/ (svg-sprite-loader publicPath). + // Those files only hold defs; SVGO treats them as unused and + // strips them, which empties the sprite and breaks #icon-* references. if (/(?:^|[/\\])icons[/\\]/i.test(sourcePath)) { return false } From 5360ce630997fb6e499f3d063ed75bcf0bc9796c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ce=CC=81dric=20Andrietti?= Date: Mon, 19 Oct 2026 16:30:33 +0200 Subject: [PATCH 6/6] refactor(build): exclude icons/ at ImageMinimizerPlugin level Co-authored-by: Cursor --- config/webpack.common.js | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/config/webpack.common.js b/config/webpack.common.js index 915fda9c..860f9a38 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -15,6 +15,8 @@ module.exports = { optimization: { minimizer: [ new ImageMinimizerPlugin({ + // svg-sprite-loader extract publicPath; sprites are already optimized via svgo-loader. + exclude: /(?:^|[/\\])icons[/\\]/i, minimizer: [ { implementation: ImageMinimizerPlugin.sharpMinify, @@ -44,23 +46,7 @@ module.exports = { }, { implementation: ImageMinimizerPlugin.svgoMinify, - // Return true to run SVGO on this asset, false to leave it unchanged. - // sourcePath is the webpack compilation asset name (e.g. icons/sprite.svg). - filter: (source, sourcePath) => { - // Only SVG assets go through SVGO (raster images use sharpMinify above). - if (!/\.svg$/i.test(sourcePath)) { - return false - } - - // Skip extracted sprite sheets under icons/ (svg-sprite-loader publicPath). - // Those files only hold defs; SVGO treats them as unused and - // strips them, which empties the sprite and breaks #icon-* references. - if (/(?:^|[/\\])icons[/\\]/i.test(sourcePath)) { - return false - } - - return true - }, + filter: (source, sourcePath) => /\.svg$/i.test(sourcePath), options: { encodeOptions: { multipass: true,