# Adding New SVG Icons (Sufi Icons)
Sufi Icons (si) are the only icon set used in the platform. All icons live in a single registry and are rendered by `SbIcon`. This guide explains how to add a new SVG icon.
## Where icons are defined
| File | Purpose |
|------|---------|
| `SufiChain.SufiBlazor/Icons/SiIconCategory.cs` | Enum of categories (Navigation, Actions, Media, Files, etc.) |
| `SufiChain.SufiBlazor/Icons/SiIconMetadata.cs` | Record: Name, Category, Description, Svg |
| `SufiChain.SufiBlazor/Icons/SufiIcons.cs` | Static registry: dictionary of all icons, `GetIcon`, `GetSvg`, `GetByCategory`, `Search` |
| `SufiChain.SufiBlazor/Components/Common/SbIcon.razor` | Renders icon by name via `SufiIcons.GetSvg(Name)` — **do not add icons here** |
Icons are **not** defined in `SbIcon.razor`. They are defined only in `SufiIcons.cs` inside `CreateIconRegistry()`.
## SVG contract (required for consistency)
All new outline-style icons must follow this contract so they scale and theme correctly:
- **ViewBox**: `viewBox="0 0 24 24"`
- **Fill**: `fill="none"` for outline icons
- **Stroke**: `stroke="currentColor"` and `stroke-width="2"`
- **Caps/joins**: `stroke-linecap="round"` and `stroke-linejoin="round"`
- **No scripts, external refs, or editor metadata**
Example outline SVG:
```xml
```
For solid/filled icons (e.g. dots, filled shapes), use `fill="currentColor"` and no stroke. The registry defines constants `SvgOutlineAttrs` and `SvgSolidAttrs` in `SufiIcons.cs` — use them when building the SVG string in code.
## Step-by-step: add a new icon
### 1. Choose a name and category
- **Name**: kebab-case (e.g. `file-pdf`, `user-plus`). Must be unique.
- **Category**: Pick one of the values in `SiIconCategory` (e.g. `SiIconCategory.Files`, `SiIconCategory.Actions`). If you need a new category, add it to the enum in `SiIconCategory.cs` first.
### 2. Add the icon to the registry
Open `sufi-platform/src/modules/sufi-blazor/src/SufiChain.SufiBlazor/Icons/SufiIcons.cs` and find the method `CreateIconRegistry()`. Add a new entry to the dictionary:
```csharp
["your-icon-name"] = new("your-icon-name", SiIconCategory.YourCategory, "Short description for search/accessibility",
$""),
```
- Use `SvgOutlineAttrs` for stroke-based icons or `SvgSolidAttrs` for fill-only icons.
- Escape double quotes inside the SVG string (e.g. `\"` for attributes).
- Place the entry in the appropriate comment block (e.g. `// ========== File Icons ==========`) so the file stays organized.
### 3. Verify in the demo
Run the SufiBlazorDemo app and open the Icon page (e.g. `/components/icon`). Your icon should appear in the grid and in search. You can filter by category to confirm it’s in the right group.
### 4. Use the icon in the app
Use the same name (with or without the `si-` prefix) in `SbIcon`:
```razor
```
For menu items and other string-based icon fields, use the same name:
```csharp
icon: "your-icon-name"
```
## Naming conventions
- Use **kebab-case**: `chevron-down`, `folder-open`, `shield-check`.
- Prefer **short, clear names** that match common icon sets (e.g. Lucide/Feather) for easier recognition.
- **No** `si-` prefix in the registry key; the component accepts both `"home"` and `"si-home"` and normalizes internally.
## Optional: AI-generated icons
If you generate SVG with an AI or tooling:
1. Enforce the same contract (24×24 viewBox, stroke/fill, round caps/joins, `currentColor`).
2. Strip scripts, external references, and metadata.
3. Prefer optimizing with SVGO (or similar) before pasting into the registry, and avoid aggressive rounding of path data.
The file `.cursor/plans/icons-list.csv` in the repo contains icon names, categories, and prompts used for the initial pack; you can use it as a reference for naming and categories.
## Summary checklist
- [ ] Name is kebab-case and unique.
- [ ] Category exists in `SiIconCategory` (add enum value if needed).
- [ ] New entry added in `SufiIcons.CreateIconRegistry()` with correct SVG.
- [ ] SVG follows the contract (viewBox, stroke/fill, round caps/joins, `currentColor`).
- [ ] Icon appears and is searchable on the demo Icon page.
- [ ] Usage in app is via `` or `icon: "your-icon-name"` only.