diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c25dc96741..8280246b78 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -265,7 +265,7 @@ The project supports three types of icons, all with automatic imports (no manual
2. **Iconify Icons** - 200,000+ icons from various libraries: ``, ``
3. **Custom Icons** - Your own SVG icons: ``
-Icons are powered by the unplugin-icons system, which automatically discovers and imports icons as Vue components. Custom icons are stored in `src/assets/icons/custom/`.
+Icons are powered by the unplugin-icons system, which automatically discovers and imports icons as Vue components. Custom icons are stored in `src/assets/icons/custom/` and processed by `build/customIconCollection.ts` with automatic validation.
For detailed instructions and code examples, see [src/assets/icons/README.md](src/assets/icons/README.md).
diff --git a/build/customIconCollection.js b/build/customIconCollection.js
deleted file mode 100644
index ae52b97ae0..0000000000
--- a/build/customIconCollection.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { readFileSync, readdirSync } from 'fs'
-import { join } from 'path'
-import { dirname } from 'path'
-import { fileURLToPath } from 'url'
-
-const fileName = fileURLToPath(import.meta.url)
-const dirName = dirname(fileName)
-const customIconsPath = join(dirName, '..', 'src', 'assets', 'icons', 'custom')
-
-// Create an Iconify collection for custom icons
-export const iconCollection = {
- prefix: 'comfy',
- icons: {},
- width: 16,
- height: 16
-}
-
-// Read all SVG files from the custom icons directory
-const files = readdirSync(customIconsPath)
-files.forEach((file) => {
- if (file.endsWith('.svg')) {
- const name = file.replace('.svg', '')
- const content = readFileSync(join(customIconsPath, file), 'utf-8')
-
- iconCollection.icons[name] = {
- body: content
- }
- }
-})
diff --git a/build/customIconCollection.ts b/build/customIconCollection.ts
new file mode 100644
index 0000000000..f2d823ed5d
--- /dev/null
+++ b/build/customIconCollection.ts
@@ -0,0 +1,100 @@
+import { existsSync, readFileSync, readdirSync } from 'fs'
+import { join } from 'path'
+import { dirname } from 'path'
+import { fileURLToPath } from 'url'
+
+const fileName = fileURLToPath(import.meta.url)
+const dirName = dirname(fileName)
+const customIconsPath = join(dirName, '..', 'src', 'assets', 'icons', 'custom')
+
+// Iconify collection structure
+interface IconifyIcon {
+ body: string
+ width?: number
+ height?: number
+}
+
+interface IconifyCollection {
+ prefix: string
+ icons: Record
+ width?: number
+ height?: number
+}
+
+// Create an Iconify collection for custom icons
+export const iconCollection: IconifyCollection = {
+ prefix: 'comfy',
+ icons: {},
+ width: 16,
+ height: 16
+}
+
+/**
+ * Validates that an SVG file contains valid SVG content
+ */
+function validateSvgContent(content: string, filename: string): void {
+ if (!content.trim()) {
+ throw new Error(`Empty SVG file: ${filename}`)
+ }
+
+ if (!content.includes('