Flagsmith / Flagsmith/flagsmith

Refactor Icon.tsx: split 70 inline SVGs into individual files

Open
#7,019 1 comment 0 reactions 0 assignees View on GitHub
front-end tech-debt
Dominant language
Python
Stars
6.6k
Forks
567
Avg merge
1d 13h
Merged PRs (30d)
121

Description

## Problem

`Icon.tsx` is 1,268 lines / 66KB containing 61 inline SVGs in a single switch statement. Additionally, 19 separate SVG components exist in `web/components/svg/` and ~35 icons use `@ionic/react` IonIcon across 42 files (#7022) — 3 icon systems total.

### Performance impact

- **66KB parsed on every page load** even if only a few icons are used
- **Not tree-shakable** — bundler includes all 61 icons regardless of usage
- **No lazy loading** — heavy icons (GitHub SVGs) load on pages that don't need them

### For non-frontend context

Think of it like importing an entire Python library when you only need one function. Tree-shaking (the bundler excluding unused code) only works with proper module imports, not giant switch statements.

## Solution

1. Extract each icon to its own file (e.g. `components/icons/CloseIcon.tsx`)
2. Integrate the 19 `svg/` components into the same system
3. Keep the `` API as a convenience wrapper that dynamically imports
4. Bundlers tree-shake unused icons automatically

```tsx
// Before: 66KB loaded regardless

// After: only this icon is bundled
import { CloseIcon } from 'components/icons/CloseIcon'

```

## Acceptance criteria

- [ ] Each icon in its own file
- [ ] `svg/` components integrated
- [ ] Existing `` API still works
- [ ] Measurable reduction in initial bundle size
- [ ] No visual regressions

## Related

- #7022 — Remove @ionic/react IonIcon (blocked by this issue)

---
Part of the Design System Audit (#6606) · Epic: #6882

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.