Иконки — единый компонент Icon (@nuxt/icon)

В проекте используется модуль @nuxt/icon, который предоставляет универсальный компонент <Icon /> c единой схемой имени: "<коллекция>:<имя>". Для Lucide используется префикс lucide:.

  • Пример: <Icon name="lucide:coffee" />
  • Модуль автоматически инлайнит SVG, умеет управлять размером/цветом через классы Tailwind, хорошо работает в SSR.

Быстрый старт (Lucide)

<template>
  <div class="flex items-center gap-3">
    <Icon
      name="lucide:coffee"
      class="size-5"
    />
    <Icon
      name="lucide:mouse-pointer-click"
      class="size-5 text-primary"
    />
    <Icon
      name="lucide:sparkles"
      class="text-accent size-6"
    />
  </div>
</template>

Под капотом используется Iconify, поэтому вам доступны тысячи иконок из разных коллекций. Для Lucide — достаточно префикса lucide:.

Свойства и стили

  • Размер/цвет: задавайте через классы Tailwind (h-*, w-*, text-*).
  • Доступность: для декоративных иконок добавляйте aria-hidden="true"; если иконка несёт смысл — добавьте role="img" и aria-label.
<template>
  <Icon
    name="lucide:info"
    class="size-4 text-muted-foreground"
    aria-hidden="true"
  />
</template>

Использование в UIButton

Компонент UIButton ожидает иконку в слот #icon. Пример (слева, справа, только иконка):

<template>
  <div class="flex flex-wrap gap-2">
    <UIButton icon-placement="left">
      <template #icon>
        <Icon
          name="lucide:coffee"
          class="size-4"
        />
      </template>
      Coffee
    </UIButton>

    <UIButton icon-placement="right">
      Forward
      <template #icon>
        <Icon
          name="lucide:arrow-right"
          class="size-4"
        />
      </template>
    </UIButton>

    <UIButton
      size="icon"
      icon-placement="only"
      aria-label="Open menu"
    >
      <template #icon>
        <Icon
          name="lucide:menu"
          class="size-4"
        />
      </template>
    </UIButton>
  </div>
</template>

Как добавить свои иконки

Локальные SVG как кастомная коллекция

  1. Сложите SVG‑файлы в каталог (например, app/icons). Имена файлов — это имена иконок.
app/icons/
├─ logo.svg
└─ brand-mark.svg
  1. Импортируйте SVG как raw‑строки и объявите коллекцию в nuxt.config.ts:
// nuxt.config.ts
import logo from './app/icons/logo.svg?raw';
import brandMark from './app/icons/brand-mark.svg?raw';

export default defineNuxtConfig({
  // ... ваш конфиг
  icon: {
    // Регистрируем кастомную коллекцию с префиксом 'app'
    customCollections: {
      app: {
        icons: {
          logo: logo,
          'brand-mark': brandMark
        }
      }
    }
  }
});
  1. Использование в шаблоне:
<template>
  <div class="flex items-center gap-3">
    <Icon
      name="app:logo"
      class="size-6"
    />
    <Icon
      name="app:brand-mark"
      class="size-6 text-primary"
    />
  </div>
</template>

Плюсы: простой процесс, храните SVG рядом с кодом; минусы: требуется импортировать каждую иконку в конфиг (но это наглядно и контролируемо).

Кастомные иконки

Иконки соцсетей

<template>
  <Icon
    name="cs:vk"
    class="size-5 text-primary-foreground"
  />
  <Icon
    name="cs:tg"
    class="size-5 text-primary-foreground"
  />
  <Icon
    name="cs:wa"
    class="size-5 text-primary-foreground"
  />
  <Icon
    name="cs:dzen"
    class="size-5 text-primary-foreground"
  />
  <Icon
    name="cs:viber"
    class="size-5 text-primary-foreground"
  />
</template>

Советы

  • Единообразие: используйте один компонент <Icon /> для всех иконок (и Lucide, и кастомных) — так проще поддерживать.
  • Контроль размера: в UI придерживайтесь размеров 16/20/24px (h-4/5/6, w-4/5/6), чтобы иконки выглядели ровно в кнопках/инпутах.
  • Цвет: наследуйте от текста (text-foreground) или явно задавайте text-* для состояния (напр. text-primary).
  • Декоративные иконки: ставьте aria-hidden="true". Если иконка несёт смысл — aria-label или соседний текст.
  • Отладка: если иконка не отрисовалась — проверьте префикс (напр., lucide:), имя и корректность регистра. Для кастомных — убедитесь, что коллекция подключена и сервер перезапущен.