> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yuvrajverma.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with Icons

> Learn how to use and configure icons throughout your Latch application

## Overview

Latch uses [Lucide React](https://lucide.dev) icons throughout the application. This guide explains the pattern for adding and configuring icons in your components and config files.

<Note>
  **Icon Pattern**: Config files store icon names as strings, then components import specific icons from `lucide-react` and map them using an `iconMap` object.
</Note>

***

## How It Works

<Tabs>
  <Tab title="1. Config File">
    In your config files, icons are defined as **PascalCase string names**:

    ```typescript config/example.ts theme={null}
    export const exampleConfig = {
      features: [
        {
          title: "Fast Performance",
          icon: "Zap", // String name matching Lucide icon
          color: "blue",
        },
        {
          title: "Secure",
          icon: "Shield",
          color: "green",
        },
      ],
    };
    ```

    <Check>Use exact PascalCase names from [lucide.dev/icons](https://lucide.dev/icons)</Check>
  </Tab>

  <Tab title="2. Component">
    Components import specific icons and create an `iconMap`:

    ```tsx components/Example.tsx theme={null}
    import { Zap, Shield } from "lucide-react";
    import { exampleConfig } from "@/config/example";

    const iconMap = { Zap, Shield };

    export default function Example() {
      return (
        <div>
          {exampleConfig.features.map((feature) => {
            const Icon = iconMap[feature.icon as keyof typeof iconMap];
            return (
              <div key={feature.title}>
                <Icon className="w-6 h-6" />
                <span>{feature.title}</span>
              </div>
            );
          })}
        </div>
      );
    }
    ```

    <Warning>
      **Never use** `import * as LucideIcons from "lucide-react"`. Always import specific icons to keep your bundle size optimized.
    </Warning>
  </Tab>

  <Tab title="Bundle Impact">
    ### Why Direct Imports Matter

    | Import Method   | Bundle Size | Icons Included    |
    | --------------- | ----------- | ----------------- |
    | Direct import   | **\~2KB**   | Only what you use |
    | Wildcard import | **\~300KB** | All 1,000+ icons  |

    ```typescript theme={null}
    // Good: Only bundles 3 icons (~2KB)
    import { Shield, Zap, Heart } from "lucide-react";

    // Bad: Bundles all icons (~300KB)
    import * as LucideIcons from "lucide-react";
    ```

    <Tip>Tree-shaking works automatically with direct imports - no configuration needed!</Tip>
  </Tab>
</Tabs>

***

## Adding New Icons

<Steps>
  <Step title="Find the Icon">
    Browse [lucide.dev/icons](https://lucide.dev/icons) to find the icon you need. Note the exact name (e.g., `Zap`, `Shield`, `Heart`).
  </Step>

  <Step title="Add to Config">
    Add the icon name as a string in your config file:

    ```typescript theme={null}
    icon: "Heart", // Exact name from lucide.dev
    ```
  </Step>

  <Step title="Import in Component">
    Import the icon in your component:

    ```typescript theme={null}
    import { Zap, Shield, Heart } from "lucide-react";
    ```
  </Step>

  <Step title="Add to iconMap">
    Add it to the iconMap object:

    ```typescript theme={null}
    const iconMap = { Zap, Shield, Heart };
    ```
  </Step>
</Steps>

***

## Icon Naming Conventions

All icons use **PascalCase** in both config and imports for consistency:

```typescript theme={null}
// Config
icon: "Shield"

// Component
import { Shield } from "lucide-react";
const iconMap = { Shield };
```

<Note>
  **Always use PascalCase**: Icon names in config files must match the exact PascalCase names from [lucide.dev/icons](https://lucide.dev/icons).
</Note>

***

## Real-World Examples

<Tabs>
  <Tab title="Game Features">
    <CodeGroup>
      ```typescript config/games/common.ts theme={null}
      export const gamesCommonConfig = {
        features: [
          { title: "DDoS Protection", icon: "Shield", color: "blue" },
          { title: "Instant Setup", icon: "Zap", color: "purple" },
          { title: "NVMe Storage", icon: "HardDrive", color: "green" },
          { title: "24/7 Support", icon: "LifeBuoy", color: "yellow" },
        ],
      };
      ```

      ```tsx components/sections/shared/CommonIncludes.tsx theme={null}
      import { Shield, Zap, HardDrive, LifeBuoy, Database, Lock, Globe, Gauge } from "lucide-react";
      import { gamesCommonConfig } from "@/config/games/common";

      const iconMap = { Shield, Zap, HardDrive, LifeBuoy, Database, Lock, Globe, Gauge };

      export default function CommonIncludes() {
        return (
          <div>
            {gamesCommonConfig.features.map((feature) => {
              const Icon = iconMap[feature.icon as keyof typeof iconMap];
              return (
                <div key={feature.title}>
                  <Icon className="h-4 w-4" />
                  <span>{feature.title}</span>
                </div>
              );
            })}
          </div>
        );
      }
      ```
    </CodeGroup>

    <Info>**8 icons imported** - Only bundles what's actually used across the component</Info>
  </Tab>

  <Tab title="Partner Benefits">
    <CodeGroup>
      ```typescript config/pages/partners.ts theme={null}
      export const partnersConfig = {
        benefits: [
          { title: "Priority Support", icon: "Headphones", color: "blue" },
          { title: "Referral Links", icon: "Link", color: "purple" },
          { title: "Exclusive Perks", icon: "Gift", color: "green" },
          { title: "Giveaway Coins", icon: "Coins", color: "yellow" },
        ],
      };
      ```

      ```tsx components/sections/partners/PartnerBenefits.tsx theme={null}
      import { Headphones, Link, Gift, Coins } from "lucide-react";
      import { partnersConfig } from "@/config/pages/partners";

      const iconMap = { Headphones, Link, Gift, Coins };

      export default function PartnerBenefits() {
        return (
          <div className="grid grid-cols-4 gap-6">
            {partnersConfig.benefits.map((benefit) => {
              const Icon = iconMap[benefit.icon as keyof typeof iconMap];
              return (
                <div key={benefit.title}>
                  <Icon className="w-8 h-8" />
                  <h3>{benefit.title}</h3>
                  <p>{benefit.description}</p>
                </div>
              );
            })}
          </div>
        );
      }
      ```
    </CodeGroup>

    <Check>**Clean mapping** - Icon names in config match imports exactly</Check>
  </Tab>

  <Tab title="Navbar">
    <CodeGroup>
      ```typescript config/branding.ts theme={null}
      export const navbarConfig = {
        buttons: [
          { name: "Docs", href: "/knowledgebase", style: "icon", icon: "BookOpen" },
          {
            name: "Login",
            style: "primary",
            dropdown: [
              { name: "Billing Panel", href: "/billing", icon: "CreditCard" },
              { name: "Game Panel", href: "/panel", icon: "Server" },
            ],
          },
        ],
      };
      ```

      ```tsx components/layout/Navbar.tsx theme={null}
      import { ChevronDown, BookOpen, CreditCard, Server } from "lucide-react";
      import { navbarButtons } from "@/config/branding.exports";

      const iconMap = { BookOpen, CreditCard, Server };

      export default function Navbar() {
        return (
          <nav>
            {navbarButtons.map((button) => {
              if (button.style === "icon" && button.icon) {
                const Icon = iconMap[button.icon as keyof typeof iconMap];
                return <Icon className="w-5 h-5" />;
              }
              // ... dropdown logic
            })}
          </nav>
        );
      }
      ```
    </CodeGroup>

    <Tip>Import `ChevronDown` for dropdown indicators even if not in config</Tip>
  </Tab>

  <Tab title="Partner Requirements">
    <CodeGroup>
      ```typescript config/pages/partners.ts theme={null}
      export const partnersConfig = {
        requirements: {
          items: [
            { platform: "YouTube", metric: "5,000+", icon: "Youtube", color: "red" },
            { platform: "Twitch", metric: "2,000+", icon: "Twitch", color: "purple" },
            { platform: "Website", metric: "50K+", icon: "Globe", color: "blue" },
            { platform: "Developer", metric: "1,000+", icon: "Code", color: "green" },
            { platform: "Discord", metric: "3,000+", icon: "MessageCircle", color: "indigo" },
            { platform: "Twitter/X", metric: "10K+", icon: "Twitter", color: "sky" },
          ],
        },
      };
      ```

      ```tsx components/sections/partners/PartnerRequirements.tsx theme={null}
      import { Youtube, Twitch, Globe, Code, MessageCircle, Twitter } from "lucide-react";
      import { partnersConfig } from "@/config/pages/partners";

      const iconMap = { Youtube, Twitch, Globe, Code, MessageCircle, Twitter };

      export default function PartnerRequirements() {
        return (
          <div className="grid grid-cols-3 gap-6">
            {partnersConfig.requirements.items.map((req) => {
              const Icon = iconMap[req.icon as keyof typeof iconMap];
              return (
                <div key={req.platform}>
                  <Icon className="w-8 h-8" />
                  <div>{req.platform}</div>
                  <div>{req.metric}</div>
                </div>
              );
            })}
          </div>
        );
      }
      ```
    </CodeGroup>

    <Note>**6 platform icons** - Mix of social and general icons for requirements</Note>
  </Tab>
</Tabs>

***

## Common Patterns

<Tabs>
  <Tab title="Icon Sizes">
    Standard sizes used throughout Latch:

    | Size       | Tailwind Class | Usage                              |
    | ---------- | -------------- | ---------------------------------- |
    | **Small**  | `w-4 h-4`      | Navbar, inline text, breadcrumbs   |
    | **Medium** | `w-5 h-5`      | Buttons, cards, list items         |
    | **Large**  | `w-6 h-6`      | Features, benefits, stats          |
    | **XL**     | `w-8 h-8`      | Hero sections, headers, highlights |
    | **2XL**    | `w-10 h-10`    | Large cards, testimonials          |
    | **3XL**    | `w-12 h-12`    | Icon containers, showcases         |

    ```tsx theme={null}
    // Navbar icon
    <Icon className="w-4 h-4" />

    // Feature icon
    <Icon className="w-6 h-6" />

    // Hero icon
    <Icon className="w-8 h-8" />
    ```
  </Tab>

  <Tab title="Dynamic Colors">
    Apply icon colors dynamically using Tailwind and config values:

    ```tsx theme={null}
    // From config color string
    <Icon className={`w-6 h-6 text-${feature.color}-500`} />

    // With opacity
    <Icon className={`w-6 h-6 text-${feature.color}-500/70`} />

    // Hover states
    <Icon className={`w-6 h-6 text-${color}-500 hover:text-${color}-600`} />
    ```

    **Common color values in configs:**

    * `blue`, `purple`, `green`, `red`, `yellow`
    * `indigo`, `sky`, `pink`, `orange`, `teal`

    <Warning>
      Tailwind's JIT requires complete class names. Dynamic colors work because Latch uses a limited set of predefined colors.
    </Warning>
  </Tab>

  <Tab title="Icon Containers">
    Wrap icons in styled containers for emphasis:

    <CodeGroup>
      ```tsx Simple Container theme={null}
      <div className="flex h-12 w-12 items-center justify-center rounded-lg bg-blue-500/10 border border-blue-500/20">
        <Icon className="h-6 w-6 text-blue-500" />
      </div>
      ```

      ```tsx Gradient Container theme={null}
      <div className="flex h-14 w-14 items-center justify-center rounded-xl bg-gradient-to-br from-blue-500/20 to-purple-500/20 border border-white/10">
        <Icon className="h-7 w-7 text-white" />
      </div>
      ```

      ```tsx With Animation theme={null}
      <div className="flex h-12 w-12 items-center justify-center rounded-lg bg-blue-500/10 border border-blue-500/20 transition-all hover:scale-110 hover:bg-blue-500/20">
        <Icon className="h-6 w-6 text-blue-500" />
      </div>
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Conditional Rendering">
    Handle optional or dynamic icons safely:

    ```tsx theme={null}
    // Safe fallback if icon not in map
    const Icon = iconMap[item.icon as keyof typeof iconMap];
    if (!Icon) return null;

    return <Icon className="w-5 h-5" />;
    ```

    ```tsx theme={null}
    // Optional icon with default
    const Icon = iconMap[item.icon as keyof typeof iconMap] || Shield;
    return <Icon className="w-5 h-5" />;
    ```

    ```tsx theme={null}
    // Conditional icon rendering
    {item.icon && (
      <div>
        {(() => {
          const Icon = iconMap[item.icon as keyof typeof iconMap];
          return Icon ? <Icon className="w-5 h-5" /> : null;
        })()}
      </div>
    )}
    ```
  </Tab>
</Tabs>

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use Direct Imports">
    **Good:**

    ```typescript theme={null}
    import { Shield, Zap } from "lucide-react";
    ```

    **Bad:**

    ```typescript theme={null}
    import * as LucideIcons from "lucide-react"; // Bloats bundle
    ```

    <Warning>
      You **can** use `import * as LucideIcons`, but it prevents tree-shaking and bundles ALL 1,000+ icons (\~300KB extra) even if you only use 5. Direct imports ensure only used icons are bundled.
    </Warning>
  </Accordion>

  <Accordion title="Keep iconMap One-Liner">
    **Good:**

    ```typescript theme={null}
    const iconMap = { Shield, Zap, HardDrive };
    ```

    **Bad:**

    ```typescript theme={null}
    const iconMap = {
      Shield,
      Zap,
      HardDrive,
    }; // Unnecessary verbosity
    ```
  </Accordion>

  <Accordion title="Match Config Icon Names">
    Ensure config strings match the exact PascalCase Lucide icon names:

    ```typescript theme={null}
    // Config
    icon: "MessageCircle" // Exact PascalCase match

    // Component
    import { MessageCircle } from "lucide-react";
    const iconMap = { MessageCircle };
    ```
  </Accordion>

  <Accordion title="Use Type Safety">
    ```typescript theme={null}
    const Icon = iconMap[feature.icon as keyof typeof iconMap];
    ```

    This prevents runtime errors if an icon is missing from the map.
  </Accordion>
</AccordionGroup>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Icon not displaying?">
    **Check:**

    1. Icon name in config uses **exact PascalCase** from lucide.dev
    2. Icon is imported in component
    3. Icon is added to iconMap with same name
    4. Icon exists on [lucide.dev/icons](https://lucide.dev/icons)

    **Example:**

    ```typescript theme={null}
    // Config: icon: "Mail"
    // Component: import { Mail } from "lucide-react";
    // iconMap: { Mail }
    ```
  </Accordion>

  <Accordion title="TypeScript errors?">
    Use `as keyof typeof iconMap` for type safety:

    ```typescript theme={null}
    const Icon = iconMap[item.icon as keyof typeof iconMap];
    ```
  </Accordion>

  <Accordion title="Icon names with spaces or dashes?">
    Lucide icons use PascalCase with no spaces:

    * Wrong: "message-circle"
    * Wrong: "message circle"
    * Correct: "MessageCircle"
  </Accordion>

  <Accordion title="Icon not found in Lucide?">
    1. Search [lucide.dev/icons](https://lucide.dev/icons)
    2. Consider similar alternatives
    3. Use a custom SVG if needed (add to `/public/icons/`)
  </Accordion>
</AccordionGroup>

***

## Where Icons Are Used

<CardGroup cols={2}>
  <Card title="Branding" icon="palette" href="../configuration/branding">
    Navbar icons, social links, logo
  </Card>

  <Card title="Home Page" icon="home" href="../configuration/home">
    Hero icons, features, stats, benefits
  </Card>

  <Card title="Game Servers" icon="gamepad-2" href="../products-hosting/game">
    Game features, common includes, specs
  </Card>

  <Card title="Partners" icon="handshake" href="../products-hosting/partners">
    Benefits, requirements, platform icons
  </Card>

  <Card title="Knowledge Base" icon="book-open" href="../configuration/knowledgebase">
    Article categories, content blocks
  </Card>

  <Card title="Hardware" icon="cpu" href="../configuration/hardware">
    Processor features, specifications
  </Card>
</CardGroup>

***

## Quick Reference

| Location    | Icon Pattern      | Example                                      |
| ----------- | ----------------- | -------------------------------------------- |
| **Config**  | PascalCase string | `"Shield"`                                   |
| **Import**  | Named import      | `import { Shield } from "lucide-react"`      |
| **iconMap** | Object shorthand  | `const iconMap = { Shield }`                 |
| **Usage**   | Dynamic lookup    | `iconMap[item.icon as keyof typeof iconMap]` |

<Tip>
  When adding multiple icons, do it all at once:

  1. Update config with all icon names
  2. Import all icons in one line
  3. Add all to iconMap in one line
</Tip>
