Skip to content

Vite Plugin

Process images at build time — same as the CLI but integrated into the Vite lifecycle. Runs on buildStart and re-runs in dev mode when source images change.

ts
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { vueImageKit } from '@macrulez/vue-image-kit/vite'

export default defineConfig({
  plugins: [
    vue(),
    vueImageKit({
      input: './src/images',
      output: './public/images',
      widths: [400, 800, 1200],
      manifest: './src/assets/images.ts',
    }),
  ],
})

All CLI options are supported. sharp must be installed as a dev dependency.

buildStart/handleHotUpdate call the same generate() the CLI does, so incremental generation applies here too — and is auto-enabled during vite dev specifically (not vite build) unless you set incremental explicitly. A single source-file change in dev reprocesses just that file, not the whole batch.

Build-time imports

The plugin also resolves query-suffixed imports, so you never wire props by hand — the metadata comes straight into your JS at build time:

ts
import meta from './photo.jpg?vik'
// → { src, srcset, webp, avif, width, height, placeholder, blurhash, thumbhash, name, src400, ... }

import hash from './photo.jpg?thumbhash'
// → 'base64string'

Pass the metadata straight to <VImage>'s image prop — no manual field wiring:

vue
<script setup lang="ts">
import meta from './hero.jpg?vik'
</script>

<template>
  <VImage :image="meta" alt="Hero" />
</template>
  • ?vik resizes/encodes the image into output and returns the full manifest entry (URLs use publicPath, exactly like the generated manifest). The ThumbHash is always included.
  • ?thumbhash computes only the hash string and writes no files.

Both re-run when the source image changes in dev. sharp is required; thumbhash is required for hash output.

TypeScript — enable typed ?vik / ?thumbhash imports by referencing the bundled declarations once (e.g. in env.d.ts):

ts
/// <reference types="@macrulez/vue-image-kit/vite/client" />

On-demand dev serving

Both the CLI and the build-time imports above are batch/ahead-of-time — they process images before they're requested. If you'd rather not run a build step at all during development, set dev.onDemand: true and images resize on request instead, cached to disk after the first hit:

ts
vueImageKit({
  dev: { onDemand: true }, // mounts a handler at /_vik/image during `vite dev`
})
html
<img src="/_vik/image?src=/photos/cat.jpg&w=800&format=webp" />

This is dev-only — configureServer (the Vite hook it uses) never runs during vite build. For production without a CDN, mount the same handler in your own server — see Self-hosted on-demand server.

dev options

The handler behind dev.onDemand is the same createImageHandler the self-hosted server uses — root is fixed to Vite's own project root (server.config.root), everything else is the same tuning surface:

  • onDemandboolean · default: false. Mounts the handler during vite dev.
  • routestring · default: /_vik/image. Route to mount it at.
  • cacheDirstring · default: <root>/.vik-cache. See Self-hosted on-demand server → Options.
  • maxAgenumber · default: 31536000 (1 year).
  • allowedWidthsnumber[], optional. Restrict w to exactly these values.
  • maxWidthnumber · default: 4000. Upper bound for w when allowedWidths isn't set.