Nuxt
Готовые конфигурации модуля Nuxt. В каждом рецепте сказано, когда его применять, показаны полный nuxt.config.ts и шаблон и описано, что вы получите. Выбрать рецепт поможет страница Выбор способа.
Установите sharp — и thumbhash там, где считается ThumbHash, — в dev-зависимости:
npm install -D sharp thumbhashМинимальная настройка
Когда применять. Нужны только <VImage>, v-lazy-img и автоимпорт composables, ничего заранее готовить не требуется.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@macrulez/vue-image-kit/nuxt'],
vueImageKit: {
breakpoints: { sm: '(max-width: 640px)', md: '(max-width: 1024px)' },
},
})Что вы получите. Компонент и директива регистрируются глобально, стили подключаются сами, а каждый composable импортируется автоматически. breakpoints — именованные медиазапросы для art direction.
Размытие для всего в папке
Когда применять. Изображения выводятся из данных (:src="item.image") или из шаблонов, и нужно размытие и правильный размер для всех сразу, не трогая ни одного шаблона.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@macrulez/vue-image-kit/nuxt'],
vueImageKit: {
placeholders: { dirs: ['public/images'] },
},
})<template>
<VImage v-for="item in items" :key="item.id" :src="item.image" :alt="item.title" />
</template>Что вы получите. Модуль сам регистрирует плагин Vite, при каждой сборке строит манифест из public/images и передаёт его каждому <VImage>. Запускать команду и хранить файл в репозитории не нужно. Каждая запись записана под URL, по которому отдаётся файл (/images/cat.jpg), и <VImage> находит её по точному src.
При серверном рендеринге у изображения уже есть width и height, поэтому страница не прыгает; само размытие рисуется в браузере после гидратации. В nuxt dev манифест следует за папкой: новый или изменённый файл вызывает перезагрузку.
Что важно знать. Пути в dirs — относительно корня проекта. Папка должна отдаваться по постоянному URL, как public/; для изображений, которые хранятся в другом месте, — следующий рецепт.
Изображения вне public
Когда применять. Файлы лежат в репозитории, но шаблон ссылается на них по другому URL — обычно CDN или путь прокси.
vueImageKit: {
placeholders: {
dirs: [
'public/images',
{ dir: 'content/photos', urlPrefix: 'https://cdn.example.com/photos' },
],
},
}Что вы получите. content/photos/a.jpg сохраняется как https://cdn.example.com/photos/a.jpg — тот src, который использует ваш шаблон. Без urlPrefix папка вне public/ записывается по пути в проекте, который в продакшене ничему не соответствует, и сборка об этом предупредит.
Изображения, импортированные через ~/assets, устроены иначе: их URL при сборке хешируется, поэтому ни один манифест не может знать его заранее. Для них — следующий рецепт.
Размытие для импортированного изображения
Когда применять. Изображение импортируется в компонент из ~/assets, и нужно его размытие.
// nuxt.config.ts
import { vueImageKit } from '@macrulez/vue-image-kit/vite'
export default defineNuxtConfig({
modules: ['@macrulez/vue-image-kit/nuxt'],
vite: {
plugins: [vueImageKit({ generate: false })],
},
})<script setup lang="ts">
import photo from '~/assets/photo.jpg'
import placeholder from '~/assets/photo.jpg?placeholder'
</script>
<template>
<VImage :src="photo" v-bind="placeholder" alt="Photo" />
</template>Что вы получите. ?placeholder считается при сборке и возвращает { hazehash, placeholderColor, width, height } (blurhash, если пакет hazehash не установлен) — пропсы <VImage>. generate: false не даёт плагину ничего уменьшать. Импорты получают типы, когда вы добавите /// <reference types="@macrulez/vue-image-kit/vite/client" /> в любой .d.ts файл проекта.
Выбор полей. Список возвращает ровно то, что вы назвали, так что один импорт может нести и размытие, и реальный размер, и готовое превью. Значения — это обычные данные, встроенные при сборке и одинаковые на сервере и в браузере, поэтому при гидратации расхождений быть не может:
<script setup lang="ts">
import cover from '~/assets/cover.jpg'
import ph from '~/assets/cover.jpg?placeholder=blurhash,size'
import preview from '~/assets/cover.jpg?preview'
</script>
<template>
<VImage :src="cover" v-bind="ph" alt="Cover" />
<section class="hero" :style="{ backgroundImage: `url(${preview})` }" />
</template>Поля: hazehash, blurhash, thumbhash, color, size, preview, aspect и all; есть и импорты по одному значению (?color, ?size, ?aspect, ?preview), и настройки для отдельного изображения (?blurhash&components=6x4). Всё это описано в разделе Выбор того, что считать.
Типы для списков. Список или импорт с настройками нельзя типизировать встроенными декларациями, поэтому пусть их напишет плагин. Опция types принадлежит плагину, который вы добавляете сами в vite.plugins; плагин, который модуль регистрирует для dirs или urls, её не принимает:
vite: {
plugins: [vueImageKit({ generate: false, types: 'vik-imports.d.ts' })],
},Файл записывается в проект и подхватывается конфигурацией TypeScript, которую генерирует Nuxt; один раз запустите nuxt dev или nuxt build, чтобы он появился.
Что важно знать. Модуль сам регистрирует плагин Vite, только если вы передали ему dirs или urls. Для одних лишь импортов ?placeholder добавьте плагин, как выше. Если нужны оба способа, передайте модулю dirs и не добавляйте vite.plugins — тогда импорты тоже заработают.
Размытие для каждого импортируемого изображения
Когда применять. Проект импортирует свои изображения (import hero from '~/assets/hero.webp' или src="~/assets/hero.webp" в шаблоне), и нужно размытие для всех них без правки единого шаблона.
vueImageKit: {
placeholders: { imports: true },
},Что вы получите. Каждое статически импортированное растровое изображение получает при сборке свой HazeHash (или BlurHash, если hazehash не установлен) и реальный размер, а <VImage :src="hero" /> находит их сам — в dev, в продакшен-сборке и при серверном рендеринге. Модуль сам регистрирует плагин Vite; ни манифеста, ни запроса добавлять не нужно. Нужен sharp как dev-зависимость.
Что важно знать. Импорты с запросом, SVG и ленивые import() пропускаются; imports: { exclude: ['/sprites/'] } исключает изображения, которые никогда не показываются через <VImage>. См. Плейсхолдер для каждого импортируемого изображения.
Файл манифеста плюс папки
Когда применять. Вы уже запускаете npx vue-image-kit placeholders, чтобы заполнить шаблоны, и хотите добавить к этому папки.
vueImageKit: {
placeholders: {
manifest: './image-placeholders.ts',
dirs: ['public/images'],
},
}Что вы получите. Два манифеста объединяются, причём записи из файла важнее записей из папок. Простая строка placeholders: './image-placeholders.ts' по-прежнему означает только файл.
Удалённые изображения
Когда применять. Изображения приходят с CDN или внешнего хоста.
vueImageKit: {
placeholders: {
urls: ['https://res.cloudinary.com/demo/image/upload/sample.jpg'],
},
}Что вы получите. Каждый URL скачивается при сборке и записывается под этой же строкой. Распознаваемый CDN запрашивается в уменьшенной версии. Результаты кешируются, поэтому повторная сборка не качает заново.
Другой вид плейсхолдера и настройка
Когда применять. Нужен BlurHash или ThumbHash вместо HazeHash по умолчанию, только цвет или более длинный HazeHash (tuning.budget).
vueImageKit: {
placeholders: {
dirs: ['public/images'],
mode: 'thumbhash',
tuning: { components: [6, 4], sample: 128, color: 'average' },
},
}mode — 'hazehash' (по умолчанию, если установлен пакет hazehash), 'blurhash' (по умолчанию в остальных случаях), 'thumbhash' или 'color'. tuning описан в разделе Настройка хешей. Те же настройки действуют и на импорты ?placeholder.
Варианты по запросу
Когда применять. Нужны уменьшенные файлы WebP/AVIF без шага сборки и без CDN.
vueImageKit: {
onDemandServer: true,
}<VImage src="/photos/cat.jpg" alt="Photo" :widths="[400, 800]" loader="server" />Что вы получите. Маршрут Nitro /_vik/image, который уменьшает изображения из public/ при первом запросе и кеширует их. См. Изображения по запросу как маршрут Nitro.
Варианты, собранные заранее
Когда применять. Вы предпочитаете готовые файлы, которые делаются до сборки приложения.
Nuxt запускает две сборки Vite — клиентскую и серверную, — поэтому плагин в vite.plugins обработал бы папку дважды. Вместо этого запускайте команду из скрипта:
{
"scripts": {
"images": "vue-image-kit generate --input ./assets/originals --output ./public/images --widths 400,800,1200",
"prebuild": "npm run images"
}
}Что вы получите. Файлы в public/images и, с --manifest, TypeScript-список этих файлов. Все опции — на странице Генерация изображений.