Cloudflare image optimization in Next.js

August 5, 2024

  • Frontend

  • Images

  • Optimization

  • Resizing

We know Cloudflare is really good at optimizing images. It's flexible, fast and can really relieve next.js server from responsibility of optimizing images, especially if we have hundreds of them. I assume you already set up Cloudflare for your application and enabled image optimization feature. Let's do some coding now!

Create custom loader for Image component

Let's start with defining types of parameters our cloudflareLoader must accept. We're going to extend core Next.js types.

import NextImage, { ImageProps, ImageLoaderProps } from 'next/image';

type CloudflareImageLoaderProps = ImageLoaderProps & {
  height?: number;
  fit?: 'scale-down' | 'contain' | 'cover' | 'crop' | 'pad';
  format?: 'jpeg' | 'webp' | 'avif';
};

Our custom loader will handle building an URL which points to cloudflare image optimization service. The service will optimize the image according to passed parameters, cache the image and serve it every time client makes a request.

const normalizeSrc = (src: string) => {
  return src.startsWith('/') ? src.slice(1) : src;
};

export const cloudflareLoader = ({
  src,
  width,
  height,
  fit,
  quality,
  format = 'webp',
}: CloudflareImageLoaderProps) => {
  const params = [`width=${width}`];
  if (height) {
    params.push(`height=${height}`);
  }
  if (fit) {
    params.push(`fit=${fit}`);
  }
  if (quality) {
    params.push(`quality=${quality}`);
  }
  if (format) {
    params.push(`format=${format}`);
  }
  const paramsString = params.join(',');
  return `https://my-nextjs-app.com/cdn-cgi/image/${paramsString}/${normalizeSrc(src)}`;
};

Use the loader in Image component

export const CloudflareImage = (props: ImageProps) => {
  return <NextImage loader={cloudflareLoader} {...props} />;
};

It's ready to use! Make it handle all images which require optimization and work out the best quality settings which fit your project well!

Adam Kaczmar

About the author

Adam Kaczmar, Web Developer

I've been a professional full-stack web developer since 2015. My experience comes mainly from e-commerce and consists of:

  • developing highly customized e-commerce software,
  • automating catalog and order integrations with external warehouse services,
  • creating tailor-made user-friendly administration tools for client teams,
  • creating front-end React / Next.js applications along with headless Magento, Laravel and Sanity back-ends.

Besides my programming job, I'm a husband, a father of two lovely daughters and I train boxing every Monday afternoon. Movie genere of my choice is western.

Want to talk? 🙂 Reach me on LinkedIn

...or explore all blog posts ➡️