Documentation Index
Fetch the complete documentation index at: https://mintlify.com/cloudflare/vinext/llms.txt
Use this file to discover all available pages before exploring further.
The Image component provides automatic image optimization, responsive sizing, and lazy loading. vinext routes local images through /_vinext/image and uses @unpic/react for CDN-hosted images.
Import
import Image from 'next/image'
import { getImageProps } from 'next/image'
import type { StaticImageData } from 'next/image'
Basic Usage
import Image from 'next/image'
import profilePic from './profile.jpg'
export default function Profile() {
return (
<>
{/* Remote image */}
<Image
src="https://example.com/photo.jpg"
alt="Profile photo"
width={500}
height={500}
/>
{/* Local import */}
<Image
src={profilePic}
alt="Profile"
/>
</>
)
}
API Reference
Props
src
string | StaticImageData
required
Image source URL or imported image.Supports:
- Remote URLs (validated against
remotePatterns)
- Local paths (
/images/photo.jpg)
- Static imports (
import img from './img.png')
<Image src="/images/hero.jpg" alt="Hero" width={1920} height={1080} />
Alternative text for accessibility.Required — omitting this prop will cause a build error.<Image src="/photo.jpg" alt="Person at beach" width={800} height={600} />
Intrinsic width in pixels.Required unless using fill or importing a static image:<Image src="/logo.png" alt="Logo" width={200} height={50} />
Intrinsic height in pixels.Required unless using fill or importing a static image:<Image src="/banner.jpg" alt="Banner" width={1200} height={300} />
Fill the parent container (replaces layout="fill").Sets position: absolute and sizes to fill the parent:<div style={{ position: 'relative', width: '100%', height: '400px' }}>
<Image src="/bg.jpg" alt="Background" fill />
</div>
Image quality (1-100).Higher values = better quality, larger file size:<Image src="/hero.jpg" alt="Hero" width={1920} height={1080} quality={90} />
Load the image with high priority (disables lazy loading).Use for above-the-fold images:<Image src="/hero.jpg" alt="Hero" width={1920} height={1080} priority />
Sets loading="eager" and fetchpriority="high".
placeholder
'blur' | 'empty'
default:"'empty'"
Placeholder shown while the image loads.
'blur' — requires blurDataURL
'empty' — transparent placeholder
<Image
src="/photo.jpg"
alt="Photo"
width={800}
height={600}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>
Data URL for blur placeholder (must start with data:image/).Automatically provided by static imports:import img from './photo.jpg'
// img.blurDataURL is auto-generated
<Image src={img} alt="Photo" placeholder="blur" />
Custom URL builder for CDN transforms.const myLoader = ({ src, width, quality }) => {
return `https://cdn.example.com/${src}?w=${width}&q=${quality || 75}`
}
<Image
loader={myLoader}
src="photo.jpg"
alt="Photo"
width={800}
height={600}
/>
Responsive size hints for the browser.<Image
src="/hero.jpg"
alt="Hero"
width={1920}
height={1080}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
Skip image optimization (serve original file).<Image src="/animation.gif" alt="Animation" width={400} height={300} unoptimized />
loading
'lazy' | 'eager'
default:"'lazy'"
Browser loading strategy.Automatically set to 'eager' when priority={true}.
Standard Img Props
All standard <img> attributes are supported:
<Image
src="/photo.jpg"
alt="Photo"
width={800}
height={600}
className="rounded-lg"
style={{ objectFit: 'cover' }}
onLoad={(e) => console.log('loaded')}
onError={(e) => console.error('error')}
/>
Remote Patterns
Configure allowed remote image hosts in next.config.js:
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
pathname: '/images/**',
},
{
protocol: 'https',
hostname: '*.cdn.example.com',
},
],
domains: ['legacy.example.com'], // Legacy format
},
}
Unconfigured remote URLs are:
- Dev: Warning logged, image still loads
- Production: Blocked with error
Optimization
Local Images
Routed through /_vinext/image?url=/path&w=800&q=75:
- Dev mode: Serves original file (passthrough)
- Cloudflare Workers: Uses Cloudflare Images binding for resize/transcode
- Custom: Implement your own handler
Remote Images (CDN)
Uses @unpic/react to generate CDN-specific URLs:
{/* Auto-detects Cloudinary */}
<Image
src="https://res.cloudinary.com/demo/image/upload/sample.jpg"
alt="Photo"
width={800}
height={600}
/>
{/* Generates: .../w_800,q_75/sample.jpg */}
Supported CDNs: Cloudinary, imgix, Cloudflare Images, Vercel, and more.
Responsive Images
Generates srcset with standard breakpoints:
<Image src="/hero.jpg" alt="Hero" width={1920} height={1080} />
{/* Generates srcset:
/_vinext/image?url=/hero.jpg&w=640&q=75 640w,
/_vinext/image?url=/hero.jpg&w=750&q=75 750w,
/_vinext/image?url=/hero.jpg&w=828&q=75 828w,
...
*/}
Breakpoints: [640, 750, 828, 1080, 1200, 1920, 2048, 3840]
Static Imports
Importing images provides automatic width/height:
import hero from './hero.jpg'
console.log(hero)
// {
// src: '/_next/static/media/hero.abc123.jpg',
// width: 1920,
// height: 1080,
// blurDataURL: 'data:image/jpeg;base64,...'
// }
<Image src={hero} alt="Hero" placeholder="blur" />
getImageProps
For advanced use cases (art direction, <picture> elements):
import { getImageProps } from 'next/image'
export default function Hero() {
const common = { alt: 'Hero', width: 800, height: 600 }
const { props: desktopProps } = getImageProps({ ...common, src: '/hero-desktop.jpg' })
const { props: mobileProps } = getImageProps({ ...common, src: '/hero-mobile.jpg' })
return (
<picture>
<source media="(min-width: 768px)" srcSet={desktopProps.srcSet} />
<source media="(max-width: 767px)" srcSet={mobileProps.srcSet} />
<img {...desktopProps} />
</picture>
)
}
Security
Blur Data URL Sanitization
vinext validates blurDataURL to prevent CSS injection:
{/* ✅ Valid */}
<Image blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRg..." />
{/* ❌ Blocked — contains ')' which could break CSS url() */}
<Image blurDataURL="data:image/jpeg;base64,abc); } body { background: red; } .x { (" />
Remote Pattern Validation
All remote URLs are validated against configured patterns. Missing configuration blocks production requests.
Limitations
layout prop: Deprecated in Next.js 13+. Use fill instead of layout="fill".
Server-side optimization: vinext does not perform image optimization at build time (no static generation of multiple sizes).
Source
View source code →
Implementation: /home/daytona/workspace/source/packages/vinext/src/shims/image.tsx