Skip to main content

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} />
alt
string
required
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} />
width
number
Intrinsic width in pixels.Required unless using fill or importing a static image:
<Image src="/logo.png" alt="Logo" width={200} height={50} />
height
number
Intrinsic height in pixels.Required unless using fill or importing a static image:
<Image src="/banner.jpg" alt="Banner" width={1200} height={300} />
fill
boolean
default:"false"
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>
quality
number
default:"75"
Image quality (1-100).Higher values = better quality, larger file size:
<Image src="/hero.jpg" alt="Hero" width={1920} height={1080} quality={90} />
priority
boolean
default:"false"
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,..."
/>
blurDataURL
string
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" />
loader
(params) => string
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}
/>
sizes
string
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"
/>
unoptimized
boolean
default:"false"
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

Build docs developers (and LLMs) love