Nuxt Module
hazehash-nuxt — a Nuxt module that registers the PlaceholderImage component and generates the hashes of your images during the build, so the component works with just a src. On the server the markup contains only the average colour and the aspect ratio; in the browser the blurred preview is drawn into a canvas and the real image fades in over it.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['hazehash-nuxt'],
})<template>
<PlaceholderImage src="/images/hero.jpg" alt="Hero" :width="1600" :height="900" />
</template>The module needs Nuxt 3.9 or newer. Add sharp to the project so the hashes can be generated:
npm install hazehash-nuxt
npm install --save-dev sharpHow it works
- At build time the module scans the configured directories and encodes every image with
hazehash/node. Up to four images are encoded at a time, and the result for each file is cached with its size, its modification time, the budget and the profile innode_modules/.cache/hazehash/manifest.json, so unchanged images are not encoded again. - The manifest, an object such as
{ "/images/hero.jpg": "Ed7UwRWKKv5znm6a7sC1tziHDNpMuCikxrYpIg" }, becomes the virtual module#hazehash/manifest. A key is the URL prefix of the directory followed by the path of the file inside it. - The registered component looks the hash up by its
srcwhen nohashprop is given. A hash passed explicitly always wins, which is the way to use hashes stored in a database or a CMS. - During development the manifest is regenerated when an image inside a scanned directory is added, changed or removed.
If sharp is missing, the build continues without hashes and prints one warning ([hazehash] hash generation disabled). An image that cannot be decoded is skipped with a warning ([hazehash] skipped …), so one broken file never fails the build.
Configuration
The options go under the hazehash key of nuxt.config.ts:
export default defineNuxtConfig({
modules: ['hazehash-nuxt'],
hazehash: {
componentName: 'PlaceholderImage',
generate: true,
dirs: [{ dir: 'public', prefix: '/' }],
extensions: ['.jpg', '.jpeg', '.png', '.webp', '.avif', '.gif'],
budget: 28,
profile: 'default',
},
})componentName
string · default: 'PlaceholderImage'
The name the component is registered under, for example 'HazeImage' to avoid a clash with a component of your own.
generate
boolean · default: true
Whether hashes are generated at build time. false turns the scan off, the manifest stays empty, and sharp is not needed; use it when every <PlaceholderImage> is given its hash explicitly.
dirs
{ dir: string; prefix?: string }[] · default: [{ dir: 'public', prefix: '/' }]
The directories to scan and the URL prefix of their files in the manifest. dir is relative to the project root unless it is absolute, and the scan is recursive. prefix defaults to '/'. A file public/images/hero.jpg in the default directory gets the key /images/hero.jpg, which is exactly the src you write in the template.
dirs: [
{ dir: 'public', prefix: '/' },
{ dir: 'media/photos', prefix: '/photos/' },
]The second entry is for a folder that your server publishes under another URL: media/photos/lake.jpg gets the key /photos/lake.jpg.
extensions
string[] · default: ['.jpg', '.jpeg', '.png', '.webp', '.avif', '.gif']
The file extensions treated as images, compared without regard to case.
budget
number · default: 28
The maximum number of bytes per hash. See Choosing a budget.
profile
'fast' | 'default' | 'high' · default: 'default'
How hard the encoder searches, as in encode().
Auto-imports
useHazeHash(src)
ComputedRef<string | undefined>
The hash the module generated for an image URL such as /images/hero.jpg, or undefined when there is none. src can be a plain value, a ref or a getter. Use it with your own markup:
<script setup lang="ts">
const props = defineProps<{ src: string }>()
const hash = useHazeHash(() => props.src)
const { canvas, backgroundColor, aspectRatio } = usePlaceholder(hash)
</script>usePlaceholder(hash, options?)
The composable from hazehash-vue, auto-imported for convenience. See Placeholder State.
The component
The component the module registers is the PlaceholderImage of hazehash-vue with one addition: when hash is not given, it uses the hash generated for src. It takes the same props (hash, src, alt, width, height, size, fade).
Hashes from elsewhere
The module also fits projects that keep hashes in a database. Set generate: false, and give each component its hash:
hazehash: {
generate: false,
}<PlaceholderImage
:src="photo.url"
:hash="photo.hash"
:width="photo.width"
:height="photo.height"
alt=""
/>To produce those hashes, use the hazehash command or the Node.js helpers.
Requirements
Nuxt 3.9 or newer, Node.js 20+, and sharp in your project for build-time generation. The module transpiles hazehash and hazehash-vue itself.