Иконки — единый компонент 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 как кастомная коллекция
- Сложите SVG‑файлы в каталог (например,
app/icons). Имена файлов — это имена иконок.
app/icons/
├─ logo.svg
└─ brand-mark.svg
- Импортируйте 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
}
}
}
}
});
- Использование в шаблоне:
<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:), имя и корректность регистра. Для кастомных — убедитесь, что коллекция подключена и сервер перезапущен.