логотип PurpleSchool
логотип PurpleSchool

Как использовать SVG в Nuxt

Автор

Олег Марков

Введение

SVG — это масштабируемый векторный формат для отображения графики прямо в браузере. Его применяют для иконок, иллюстраций, сложных диаграмм и визуальных эффектов, потому что изображения не теряют качества при масштабировании. В Nuxt, современном фреймворке для создания приложений на Vue, разработчики нередко сталкиваются с задачей интеграции SVG-графики. Здесь я объясню, как именно это реализовать, какие подходы существуют и что выбрать для конкретных задач. Разберем плюсы и минусы, приведу наглядные примеры из реальных проектов и объясню, как свести к минимуму рутину при работе с SVG.

Использование SVG-файлов в Nuxt

В Nuxt поддержка SVG возможна различными способами — от простого добавления через тег img до инлайна по средствам плагинов и модификации webpack-конфига. Рассмотрим их поэтапно.

Использование SVG позволяет создавать масштабируемую и векторную графику для ваших Nuxt-приложений. Однако для эффективного использования SVG необходимо понимать, как работают векторные изображения, как оптимизировать SVG-файлы и как интегрировать их с вашими компонентами. Если вы хотите углубить свои знания об использовании SVG в Nuxt, приходите на наш большой курс Nuxt - fullstack Vue фреймворк. На курсе 129 уроков и 13 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Вариант 1. Использование SVG как URL

Начнем с самого простого способа. Допустим, у вас есть иконка logo.svg в папке static. Ваш Nuxt проект устроен так, что все, что лежит в папке static, будет раздаваться как статика без обработки.

Пример использования: html <template> <div> <img src="/logo.svg" alt="Логотип" /> </div> </template> Здесь мы просто ссылаемся на файл в папке static. Этот способ понятен и работает для большинства базовых кейсов.

Недостатки:

  • Вы не сможете кастомизировать svg напрямую (например, манипулировать цветом за счет привязки CSS).
  • SVG не становится частью DOM, а значит, анимации, динамические изменения и доступность для тестов сильно ограничены.

Вариант 2. Инлайновая встраиваемая SVG

Когда вам нужно больше контроля над SVG (смена цвета иконки через props, добавление обработчиков событий и т.д.), лучше использовать инлайновое подключение SVG прямо в шаблоне компонента.

Пример: html <template> <svg width="40" height="40" viewBox="0 0 40 40" fill="none"> <circle cx="20" cy="20" r="18" stroke="blue" stroke-width="4" /> </svg> </template> Преимущества:

  • SVG становится частью HTML и управляется через JavaScript и CSS.
  • Можно динамически менять атрибуты прямо через props.

Минусы:

  • При большом числе SVG их код может засорять шаблоны Nuxt-компонентов.
  • Нет удобной возможности переиспользования между разными компонентами без вынесения SVG в отдельные компоненты.

Вариант 3. Хранение SVG-файлов в assets и импорт через require или import

Nuxt автоматически поддерживает загрузку ресурсов из папки assets, которую чаще используют для SCSS-соединений, картинок и т.д. Однако SVG из assets не доступны напрямую по URL. Их приходится импортировать, и тут уже можно применить загрузчики webpack.

Пример: ```html

**Комментарий:**  
Здесь SVG подключен как изображение, а не внедрен в DOM, поэтому кастомизация ограничена.

Чтобы получить доступ к svg-разметке, можно воспользоваться специальным загрузчиком, например [vue-svg-loader](https://github.com/vuejs/vue-svg-loader).

### Вариант 4. Использование vue-svg-loader для инлайна SVG как компонентов

Этот подход позволяет обрабатывать SVG как полноценные Vue-компоненты, а значит динамика, кастомизация и переиспользование становятся очень простыми.

#### Установка и настройка vue-svg-loader

1. Установите загрузчик:
bash npm install -D vue-svg-loader

2. Добавьте настройку в ваш nuxt.config.js:
js export default { build: { extend(config) { // Удаляем стандартную обработку для svg, чтобы не было конфликтов const svgRule = config.module.rules.find(rule =

rule.test && rule.test.test('.svg')) if (svgRule) { svgRule.exclude = [/assets/svg/] }

  // Добавляем новое правило
  config.module.rules.push({
    test: /\.svg$/,
    include: [/assets\/svg/], // Подключаем только определенную папку
    use: [
      'babel-loader',
      {
        loader: 'vue-svg-loader',
        options: {
          svgo: {
            plugins: [
              { removeViewBox: false }
            ]
          }
        }
      }
    ]
  })
}
  
}

} ```

  1. Создайте папку assets/svg и поместите SVG-файлы туда.

  2. Импортируйте SVG, как обычный компонент:

Пример: ```html

**Комментарий:**  
Теперь можно менять наполнение SVG, стилизовать через class и даже передавать события.  
`vue-svg-loader` позволяет использовать SVG как части шаблонов, объекты наследуют все возможности Vue-компонентов.

**Преимущества:**
- Full-привязка ко всем возможностям Vue.
- Простота переиспользования SVG как компонентов.
- Быстрая стилизация и замена свойств через props/slot.

**Обратите внимание:**  
По умолчанию Nuxt может выбирать разный loader для svg в зависимости от вашей версии. Если что-то идет не по плану — проверьте порядок правил webpack.

### Вариант 5. Плагины для автоматизации SVG-иконок (например, unplugin-icons)

В Nuxt-проектах часто нужно использовать большую библиотеку иконок с возможностью их подгрузки "на лету". Для этого подходят плагины вроде [unplugin-icons](https://github.com/unplugin/unplugin-icons).

#### Быстрый старт с unplugin-icons

1. Установите плагин:
bash npm install -D unplugin-icons @iconify/json
2. Добавьте плагин в Nuxt:
js

// nuxt.config.js import Icons from 'unplugin-icons/vite' export default { vite: { plugins: [ Icons({ compiler: 'vue3', autoInstall: true }) ] } } ```

  1. Используйте иконки прямо в шаблоне:
<template>
  <div>
    <i-heroicons-outline-home class="icon" />
  </div>
</template>

В этом примере i-heroicons-outline-home — это иконка из heroicons, которую вы вызываете по алиасу, не заботясь о подключении файла.

Достоинства:

  • Сотни иконок "из коробки".
  • Можно добавить свои иконки в виде svg.
  • Сжатие, оптимизация и загрузка только используемых иконок.

Совет:
Если в проекте много SVG-иконок, попробуйте unplugin-icons или аналогичные решения — это сразу улучшает “девелоперский опыт”.

Вариант 6. Оптимизация SVG (svgo, vite-plugin-svg-sprite)

SVG могут быть избыточными из-за лишних атрибутов, ненужных тегов или комментариев внутри файла. Оптимизировать их лучше до того, как вы начнете работать с ними в Nuxt.

SVGO — инструмент для оптимизации

Установите глобально или в проект: bash npm install -D svgo Затем запускайте: bash npx svgo assets/svg/logo.svg -o assets/svg/logo.optimized.svg

vite-plugin-svg-sprite для Nuxt 3

Если вы на Nuxt 3, можно использовать сразу svg-спрайты:

npm install -D vite-plugin-svg-sprite

Пример конфигурации: js // nuxt.config.js import svgSpritePlugin from 'vite-plugin-svg-sprite' export default { vite: { plugins: [ svgSpritePlugin({ symbolId: 'icon-[name]' }) ] } } Затем в шаблоне: html <svg> <use xlink:href="#icon-logo" /> </svg> Здесь вы можете быстро обращаться к иконкам и использовать их как sprite, что экономит трафик и повышает производительность.

Вариант 7. Использование Nuxt Content для SVG (Markdown)

Если вы пишете документацию или блог на Nuxt Content, можно вставлять SVG прямо в Markdown.

![Моя иконка](./my-cool-icon.svg)

SVG попадет как обычное изображение. Но учтите: инлайн-директива тут, как правило, невозможна без настройки markdown-it.

Выбор подхода — что использовать и когда

  • Для статических изображений, иллюстраций и баннеров — используйте <img src="..."> или Vite asset imports.
  • Для иконок, которые нужно стилизовать в зависимости от состояния — инлайн SVG через vue-svg-loader или unplugin-icons.
  • Для коллекций иконок и оптимизации отдачи — попробуйте sptrie-решения и плагины.
  • Для markdown/контента — простой URL или Markdown link.

SVG и доступность (a11y)

Обратите внимание: SVG не всегда доступны по умолчанию. Всегда добавляйте атрибуты aria-label и role="img", если иконка несет смысловую нагрузку.

Пример: html <svg role="img" aria-label="Логотип компании"> <!-- ... --> </svg> Если это purely декоративные элементы, используйте aria-hidden="true" и убирайте из фокуса.

Пример: html <svg aria-hidden="true" focusable="false"> <!-- ... --> </svg> Это особенно важно, если вы делаете интерфейсы для широкой аудитории.

Организация SVG-файлов и компонентов

Храните SVG-иконки в отдельной папке. Если вы делаете свой набор иконок, создайте структуры:

  • assets/svg для файлов
  • components/icons для Vue-оберток

Для общего переиспользования заведите компонент Icon:

<template>
  <component :is="iconComponent" v-bind="$attrs" />
</template>

<script>
export default {
  props: {
    name: {
      type: String,
      required: true
    }
  },
  computed: {
    iconComponent() {
      // Кешируйте здесь маппинг ваших иконок
      const icons = {
        logo: () => import('~/assets/svg/logo.svg'),
        user: () => import('~/assets/svg/user.svg')
      }
      return icons[this.name] || null
    }
  }
}
</script>

Такой конструктор позволяет по атрибуту передавать нужную иконку и отображать ее.

Заключение

Nuxt позволяет гибко интегрировать SVG графику в проекты: можно использовать простые теги <img>, инлайновое подключение svg-кода, специальные загрузчики для импорта SVG как компонента, а также автоматизировать сборку и использование множества иконок с помощью плагинов. Для каждого варианта есть свои особенности и рекомендуемые сценарии, а оптимальные подходы зависят от ваших целей — универсальной библиотеки иконок, уникальных иллюстраций или сложной визуализации прямо в DOM. Внимательно отнеситесь к аспектам доступности и не забывайте оптимизировать SVG перед загрузкой в проект.

Работа с графикой и изображениями - это важный аспект веб-разработки. Чтобы создавать гибкие и масштабируемые приложения, необходимо освоить все возможности фреймворка, включая работу с сервером, базами данных и API. На нашем курсе Nuxt - fullstack Vue фреймворк вы найдете все необходимые знания и навыки для достижения успеха. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в Nuxt прямо сегодня.

Частозадаваемые технические вопросы по теме статьи и ответы на них

1. Почему svg-файл не стилизуется через CSS, когда я использую тег img? > SVG, подключенный через <img src="..." />, не становится частью DOM и не может быть стилизован напрямую через внешние CSS классы. Чтобы управлять стилями, импортируйте SVG как компонент с помощью vue-svg-loader или вставляйте его инлайном.

2. Как оптимизировать размер SVG перед подключением в Nuxt? > Используйте инструмент svgo: установите через npm npm install -D svgo и оптимизируйте файлы командой npx svgo путь_к_файлу.svg. Это уменьшит размер svg и ускорит загрузку страницы.

3. Можно ли анимировать SVG, импортированный как компонент через vue-svg-loader? > Да, анимации доступны. Добавляйте анимации через CSS (например, к отдельным слоям SVG), либо используйте Vue props и директивы, чтобы управлять анимацией из родительского компонента.

4. Почему не работает импорт SVG через import в Nuxt 3? > В Nuxt 3 по умолчанию изменены настройки загрузчиков. Добавьте нужный загрузчик для SVG (например, vite-plugin-svg или настройте vue-svg-loader), а для индивидуальных требований проверьте схему asset imports в документации Nuxt.

5. Как добавить пользовательские наборы SVG-иконок для использования в unplugin-icons? > Для этого создайте собственную директорию с вашими SVG, настройте плагин unplugin-icons на считывание этих файлов и используйте схему алиасов. В документации плагина есть конкретные примеры по созданию кастомных коллекций.

Стрелочка влевоКак использовать useAsyncData в NuxtКоманды для запуска NuxtСтрелочка вправо

Постройте личный план изучения Nuxt до уровня Middle — бесплатно!

Nuxt — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Nuxt

Генерация статического сайта с помощью NuxtКак использовать useAsyncData в NuxtКак использовать SVG в NuxtКоманды для запуска NuxtРабота с JSON-данными в NuxtКак настроить HTML-шаблон в NuxtГенерация статического сайта с помощью NuxtРуководство по получению данных с Fetch в NuxtКак отключить определенные функции в NuxtРабота с данными в Nuxt с помощью useNuxtDataНастройка и использование cookie в NuxtГайд по аутентификации (auth) в NuxtКак создавать API-маршруты в Nuxt
Использование Vite для ускорения разработки в NuxtРуководство по использованию TypeScript в NuxtКак запустить Nuxt-приложение в productionКак работает Server-Side Rendering SSR в NuxtНастройка и оптимизация серверной части Nuxt-приложенияРуководство по настройке маршрутизации в NuxtКакие проекты разумно реализовывать на NuxtИнструкция по управлению пакетами NPM в NuxtИнтеграция Node.js для Nuxt-приложенияНастройка мета-тегов для SEO в NuxtНастройка и использование HTTPS в NuxtКак отлавливать и обрабатывать ошибки в NuxtКак развернуть Nuxt приложение в DockerРуководство по развертыванию приложений в Nuxt CloudКак оптимизировать сборку на NuxtИнтеграция Laravel и Nuxt
Открыть базу знаний

Лучшие курсы по теме

Иконка ракетыСкоро!
изображение курса

Nuxt

Антон Ларичев
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий