---
title: Icon System
description: Guide for using Solar icons with configurable variants in Harmonic SaaS.
navigation:
  icon: i-lucide-image
---

# Icon System

Harmonic SaaS uses the **Solar icon collection** from Iconify with a configurable variant system that allows you to change the visual style of all icons globally.

## Solar Icon Variants

Solar icons come in 6 different variants, each with a distinct visual style:

- **linear** - Simple line icons
- **bold** - Thicker, more prominent lines
- **outline** - Outlined style with more detail
- **broken** - Broken line style
- **bold-duotone** - Two-tone with bold lines
- **line-duotone** - Two-tone with thin lines ✨ (default)

::tip
View all available Solar icons and their variants at [icones.js.org/collection/solar](https://icones.js.org/collection/solar)
::

## Configuration

The default variant is set in [nuxt.config.ts](nuxt.config.ts):

```typescript
runtimeConfig: {
  public: {
    solarIconVariant: 'line-duotone' // Default variant
  }
}
```

### Changing the Global Variant

Override the variant via environment variable:

```env
NUXT_PUBLIC_SOLAR_ICON_VARIANT=bold-duotone
```

All Solar icons throughout the application will automatically use the configured variant.

## Usage in Components

### Using the `useSolarIcon` Composable

The recommended way to use Solar icons in components:

```vue
<script setup lang="ts">
// Uses the configured variant (default: line-duotone)
const calendarIcon = useSolarIcon('calendar')

// Override variant for specific icon
const boldUserIcon = useSolarIcon('user', 'bold')
</script>

<template>
  <!-- With Nuxt UI components -->
  <UIcon :name="calendarIcon" />
  <UButton :icon="useSolarIcon('settings')" label="Settings" />

  <!-- Override variant -->
  <UIcon :name="boldUserIcon" />
</template>
```

### Available Variants

TypeScript provides autocomplete for all valid variants:

```typescript
type SolarIconVariant =
  | 'linear'
  | 'bold'
  | 'outline'
  | 'broken'
  | 'bold-duotone'
  | 'line-duotone'
```

## Usage in i18n Files

In i18n locale files, always use **full icon references** with the complete variant:

```json
{
  "account": {
    "links": [
      [
        {
          "label": "Profile",
          "icon": "i-solar-user-line-duotone",
          "to": "/dashboard/account"
        },
        {
          "label": "Security",
          "icon": "i-solar-shield-keyhole-line-duotone",
          "to": "/dashboard/account/security"
        }
      ]
    ]
  }
}
```

### Automatic Variant Transformation

Icons in i18n files are **automatically transformed** to use the configured variant at runtime:

1. You store icons with any variant (e.g., `i-solar-user-linear`)
2. The `useI18nList` composable detects Solar icons
3. Icons are automatically transformed to match `solarIconVariant`
4. Components receive icons with the correct variant

::note
This transformation happens at runtime, so changing the environment variable immediately affects all icons without editing any files.
::

**Example:**

```json
// In i18n file
{
  "icon": "i-solar-calendar-linear"
}
```

With `NUXT_PUBLIC_SOLAR_ICON_VARIANT=bold-duotone`, this becomes:
```
i-solar-calendar-bold-duotone
```

## For Apps Extending This Layer

Apps that extend Harmonic SaaS as a layer can override icons with **any icon collection**:

```json
// In your app's i18n override
{
  "account": {
    "links": [
      [{
        "label": "Profile",
        "icon": "i-heroicons-user-circle", // Different collection
        "to": "/dashboard/account"
      }]
    ]
  }
}
```

::warning
When using non-Solar icons, the `solarIconVariant` configuration has no effect. Only icons starting with `i-solar-` are transformed.
::

## Migration from Other Icon Sets

### Lucide → Solar Equivalents

| Lucide | Solar Equivalent |
|--------|------------------|
| `i-lucide-house` | `i-solar-home-2-line-duotone` |
| `i-lucide-user` | `i-solar-user-line-duotone` |
| `i-lucide-shield` | `i-solar-shield-keyhole-line-duotone` |
| `i-lucide-settings` | `i-solar-settings-line-duotone` |
| `i-lucide-message-circle` | `i-solar-chat-round-line-line-duotone` |
| `i-lucide-info` | `i-solar-info-circle-line-duotone` |

### Carbon → Solar Equivalents

| Carbon | Solar Equivalent |
|--------|------------------|
| `carbon:globe` | `i-solar-global-line-duotone` |
| `carbon:two-factor-authentication` | `i-solar-lock-keyhole-line-duotone` |
| `carbon:layers` | `i-solar-layers-line-duotone` |
| `carbon:carbon-ui-builder` | `i-solar-widget-4-line-duotone` |

## Examples

### Changing Variant Globally

Set environment variable and restart dev server:

```bash
NUXT_PUBLIC_SOLAR_ICON_VARIANT=bold pnpm dev
```

All icons automatically use the `bold` variant.

### Per-Component Variant Override

```vue
<script setup lang="ts">
// Most icons use the default variant
const navIcons = {
  home: useSolarIcon('home-2'),
  settings: useSolarIcon('settings'),
}

// This specific icon uses bold for emphasis
const alertIcon = useSolarIcon('danger-circle', 'bold')
</script>

<template>
  <UIcon :name="navIcons.home" />
  <UIcon :name="navIcons.settings" />
  <UIcon :name="alertIcon" class="text-red-500" />
</template>
```

### Mixed Icon Collections

```vue
<template>
  <!-- Solar icons (transformed) -->
  <UIcon :name="useSolarIcon('calendar')" />

  <!-- Non-Solar icons (unchanged) -->
  <UIcon name="i-heroicons-sparkles" />
  <UIcon name="i-lucide-github" />
</template>
```

## Benefits

✅ **Consistent visual style** - All icons share the same variant
✅ **Easy customization** - Change variant globally with one config
✅ **Runtime transformation** - No manual file updates needed
✅ **Layer-friendly** - Apps can override with any icon collection
✅ **Type-safe** - TypeScript autocomplete for variants
✅ **Performance optimized** - Only transforms when variant differs

## API Reference

### `useSolarIcon(iconName, variant?)`

Generates a Solar icon reference with the configured or specified variant.

**Parameters:**
- `iconName` (string) - The base icon name (e.g., 'calendar', 'user')
- `variant` (SolarIconVariant, optional) - Override the default variant

**Returns:** Full icon reference string (e.g., 'i-solar-calendar-line-duotone')

**Example:**
```typescript
const icon = useSolarIcon('calendar')
// Returns: 'i-solar-calendar-line-duotone'

const boldIcon = useSolarIcon('user', 'bold')
// Returns: 'i-solar-user-bold'
```

## Related

::card-group
  ::card
  ---
  title: Solar Icons Collection
  icon: i-lucide-external-link
  to: https://icones.js.org/collection/solar
  target: _blank
  ---
  Browse all available Solar icons
  ::

  ::card
  ---
  title: Nuxt Icon Documentation
  icon: i-lucide-external-link
  to: https://nuxt.com/modules/icon
  target: _blank
  ---
  Official Nuxt Icon module docs
  ::

  ::card
  ---
  title: Iconify Documentation
  icon: i-lucide-external-link
  to: https://iconify.design
  target: _blank
  ---
  Learn about the Iconify framework
  ::
::
