One provides a built-in way to import images with their metadata at build time using the ?imagedata suffix. This gives you automatic width, height, and blur placeholder data without any runtime cost.
Install sharp to enable image processing:
npm install sharp
If sharp is not installed, imports will still work but return 0 for dimensions and an empty blur placeholder. A console warning will be shown during build to remind you to install it.
Import any image with the ?imagedata suffix:
import heroImage from '/hero.jpg?imagedata'
// heroImage = {
// src: '/hero.jpg',
// width: 1920,
// height: 1080,
// blurDataURL: 'data:image/jpeg;base64,...'
// }
The returned object can be spread directly onto any image component:
import heroImage from '/hero.jpg?imagedata'
// Native img element
<img {...heroImage} alt="Hero" />
// Or with explicit props
<img
src={heroImage.src}
width={heroImage.width}
height={heroImage.height}
style={{ backgroundImage: `url(${heroImage.blurDataURL})` }}
alt="Hero"
/>
The plugin supports both public directory and relative imports:
// From public directory (starts with /)
import hero from '/images/hero.jpg?imagedata'
// Relative to current file
import avatar from './avatar.png?imagedata'
import logo from '../assets/logo.svg?imagedata'
Types are included automatically. The import returns an ImageData object:
import type { ImageData } from 'one'
// ImageData = {
// src: string
// width: number
// height: number
// blurDataURL: string
// }
The blur placeholder is a tiny (10px wide) base64-encoded JPEG that can be used as a low-quality image placeholder (LQIP) while the full image loads:
import hero from '/hero.jpg?imagedata'
function HeroImage() {
const [loaded, setLoaded] = useState(false)
return (
<div style={{ position: 'relative' }}>
{/* Blur placeholder */}
<img
src={hero.blurDataURL}
width={hero.width}
height={hero.height}
style={{
position: 'absolute',
filter: 'blur(20px)',
transform: 'scale(1.1)',
opacity: loaded ? 0 : 1,
transition: 'opacity 0.3s',
}}
alt=""
/>
{/* Full image */}
<img
{...hero}
onLoad={() => setLoaded(true)}
alt="Hero"
/>
</div>
)
}
For one-off usage or build scripts, use the getImageData helper:
import { getImageData } from 'one/image'
// Paths starting with / resolve from ./public
const heroData = await getImageData('/images/hero.jpg')
// { src: '/images/hero.jpg', width: 1920, height: 1080, blurDataURL: '...' }
// Or use relative paths from your current file
const logoData = await getImageData('../public/images/logo.png')
When using @vxrn/mdx, images in frontmatter are automatically processed with getMDX. If your MDX file has:
---
title: My Post
image: /images/post-hero.jpg
---
The frontmatter will include imageMeta with dimensions and blur placeholder:
import { getMDX } from '@vxrn/mdx'
const { frontmatter } = await getMDX(source, { publicDir: './public' })
// frontmatter.image = '/images/post-hero.jpg'
// frontmatter.imageMeta = { width: 1200, height: 630, blurDataURL: '...' }
The plugin uses sharp for image processing, which supports:
<img>, React Native <Image>, Tamagui, etc.)Edit this page on GitHub.