Skip to main content
Beta: Front-End Checklist is currently in beta. Some issues are still being fixed. Thanks for your patience.

Serve images from a CDN

Images are served from a CDN with automatic optimization, resizing, and format conversion.

Utilities
Quick take
Typical fix time 30 min
  • Use image CDN for automatic format conversion (WebP, AVIF)
  • Generate responsive sizes on-the-fly via URL parameters
  • CDN edge caching delivers images from nearest location
  • Popular options: Cloudinary, Imgix, Cloudflare Images, Vercel
Why it matters: Image CDNs automatically optimize, resize, and convert images on-the-fly—delivering the smallest file in the best format without manual processing.

Rule Details

Image CDNs automatically optimize images and deliver them from edge locations worldwide.

Code Example

<!-- Cloudinary: resize, format, quality -->
<img src="https://res.cloudinary.com/demo/image/upload/w_400,h_300,c_fill,f_auto,q_auto/sample.jpg">
 
<!-- Imgix: responsive with fit and format -->
<img src="https://example.imgix.net/image.jpg?w=400&h=300&fit=crop&auto=format,compress">
 
<!-- Cloudflare Images: variants -->
<img src="https://imagedelivery.net/account/image-id/public">

Why It Matters

Image CDNs automatically optimize, resize, and convert images on-the-fly—delivering the smallest file in the best format without manual processing.

ProviderKey Features
CloudinaryAI-based optimization, extensive transformations
ImgixURL-based API, real-time processing
Cloudflare ImagesLow cost, global network
Vercel/Next.js ImageBuilt-in for Next.js projects
Bunny.netBudget-friendly, simple API

Next.js Image Optimization

import Image from 'next/image'
 
// next.config.js configures remote domains
function ProductImage({ product }: { product: Product }) {
  return (
    <Image
      src={product.imageUrl}
      alt={product.name}
      width={400}
      height={300}
      // Next.js automatically:
      // - Serves WebP/AVIF based on browser support
      // - Generates responsive sizes
      // - Lazy loads below-fold images
    />
  )
}
// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      { hostname: 'res.cloudinary.com' },
      { hostname: 'images.example.com' }
    ],
    formats: ['image/avif', 'image/webp'],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384]
  }
}

Cloudinary Integration

import { CldImage } from 'next-cloudinary'
 
function HeroImage() {
  return (
    <CldImage
      src="hero-image"
      width={1200}
      height={600}
      crop="fill"
      gravity="auto"
      format="auto"
      quality="auto"
      alt="Hero"
    />
  )
}
 
// Generate URL programmatically
function getCloudinaryUrl(publicId: string, options: TransformOptions) {
  const { width, height, format = 'auto', quality = 'auto' } = options
  return `https://res.cloudinary.com/${CLOUD_NAME}/image/upload/w_${width},h_${height},c_fill,f_${format},q_${quality}/${publicId}`
}

Responsive Images with CDN

function ResponsiveCdnImage({ src, alt }: { src: string; alt: string }) {
  const sizes = [320, 640, 960, 1280, 1920]
 
  const srcSet = sizes
    .map(w => `${getCdnUrl(src, { width: w })} ${w}w`)
    .join(', ')
 
  return (
    <img
      src={getCdnUrl(src, { width: 960 })}
      srcSet={srcSet}
      sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
      alt={alt}
      loading="lazy"
    />
  )
}
 
function getCdnUrl(src: string, options: { width: number }) {
  // Cloudinary example
  return `https://res.cloudinary.com/demo/image/upload/w_${options.width},f_auto,q_auto/${src}`
}

React Component for CDN Images

interface CdnImageProps {
  src: string
  alt: string
  width: number
  height: number
  priority?: boolean
  className?: string
}
 
function CdnImage({ src, alt, width, height, priority, className }: CdnImageProps) {
  const baseUrl = process.env.NEXT_PUBLIC_IMAGE_CDN_URL
 
  // Build CDN URL with transformations
  const cdnSrc = `${baseUrl}/w_${width},h_${height},c_fill,f_auto,q_auto/${src}`
 
  // 2x for retina
  const cdnSrc2x = `${baseUrl}/w_${width * 2},h_${height * 2},c_fill,f_auto,q_auto/${src}`
 
  return (
    <img
      src={cdnSrc}
      srcSet={`${cdnSrc} 1x, ${cdnSrc2x} 2x`}
      alt={alt}
      width={width}
      height={height}
      loading={priority ? 'eager' : 'lazy'}
      className={className}
    />
  )
}

Benefits of Image CDNs

FeatureBenefit
Auto formatServe WebP/AVIF based on browser
On-demand resizeNo need to pre-generate sizes
Edge cachingFast delivery worldwide
Bandwidth savings40-80% smaller files
No build stepDynamic processing via URL

Support Notes

  • Image format and delivery behavior can vary by browser, CDN, and device characteristics, so verify the final bytes and rendered output on the supported browser matrix.
  • Add a fallback note when a modern format or loading behavior is not available for every required target browser.

Verification

  1. Check image URLs—should point to CDN domain
  2. Verify format negotiation (check Accept header response)
  3. Test from different locations (use VPN or online tools)
  4. Compare file sizes vs original images
  5. Check cache headers for proper CDN caching
Self-Hosted vs CDN

Self-hosting images requires manual optimization and doesn't adapt to browser capabilities. Image CDNs handle all optimization automatically but add a dependency on external services.

Use with AI

Copy these prompts to use with your AI assistant, or install the MCP server to use directly from Claude, Cursor, or Windsurf.

Check

Verify implementation

Verify if images are served from a CDN or image optimization service.

Fix

Auto-fix issues

Configure an image CDN like Cloudinary, Imgix, or Cloudflare Images for automatic optimization.

Explain

Learn more

Explain how image CDNs provide on-the-fly optimization, resizing, and format conversion.

Review

Code review

Review image assets, markup, and delivery configuration related to Serve images from a CDN. Flag exact files or components where format choice, sizing, or loading behavior violates the rule, and describe how to confirm the fix in DevTools.

Sources

References used to support the guidance in this rule.

Further Reading

Tools and supplementary material for exploring the topic in more depth.

Squoosh
squoosh.appTool

Rules that often go hand-in-hand with this one.

Optimize all images for web

Images are optimized with appropriate formats, compression, and modern techniques.

Images
Handle image loading errors gracefully

Broken images are handled gracefully with fallback images or placeholder content.

Images
Use descriptive image filenames

Image filenames are descriptive and human-readable, using lowercase letters, hyphens as separators, and meaningful words that reflect the image content.

Images
Compress images without quality loss

All images are compressed without significant quality loss to reduce file sizes.

Images

Was this rule helpful?

Your feedback helps improve rule quality. This stays internal for now.

Loading feedback...
0 / 385