Menu

图片配置

如果你想使用云服务提供商来优化图片,而不是使用 Next.js 内置的图片优化 API,可以通过以下方式配置 next.config.js

next.config.js
module.exports = {
  images: {
    loader: "custom",
    loaderFile: "./my/image/loader.js",
  },
};

这个 loaderFile 必须指向相对于你的 Next.js 应用根目录的文件。该文件必须导出一个默认函数,该函数返回一个字符串,例如:

my/image/loader.js
"use client";
 
export default function myImageLoader({ src, width, quality }) {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`;
}

或者,你可以使用 loader 属性 将函数传递给每个 next/image 实例。

值得注意的是:自定义图片加载器文件,接受一个函数,需要使用 客户端组件 来序列化提供的函数。

要了解更多关于配置内置 图片优化 API图片组件 的行为,请参阅 图片配置选项 以获取可用选项。

示例加载器配置

Akamai

// 文档: https://techdocs.akamai.com/ivm/reference/test-images-on-demand
export default function akamaiLoader({ src, width, quality }) {
  return `https://example.com/${src}?imwidth=${width}`;
}

AWS CloudFront

// 文档: https://aws.amazon.com/developer/application-security-performance/articles/image-optimization
export default function cloudfrontLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`);
  url.searchParams.set("format", "auto");
  url.searchParams.set("width", width.toString());
  url.searchParams.set("quality", (quality || 75).toString());
  return url.href;
}

Cloudinary

// 演示: https://res.cloudinary.com/demo/image/upload/w_300,c_limit,q_auto/turtles.jpg
export default function cloudinaryLoader({ src, width, quality }) {
  const params = ["f_auto", "c_limit", `w_${width}`, `q_${quality || "auto"}`];
  return `https://example.com/${params.join(",")}${src}`;
}

Cloudflare

// 文档: https://developers.cloudflare.com/images/transform-images
export default function cloudflareLoader({ src, width, quality }) {
  const params = [`width=${width}`, `quality=${quality || 75}`, "format=auto"];
  return `https://example.com/cdn-cgi/image/${params.join(",")}/${src}`;
}

Contentful

// 文档: https://www.contentful.com/developers/docs/references/images-api/
export default function contentfulLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`);
  url.searchParams.set("fm", "webp");
  url.searchParams.set("w", width.toString());
  url.searchParams.set("q", (quality || 75).toString());
  return url.href;
}

Fastly

// 文档: https://developer.fastly.com/reference/io/
export default function fastlyLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`);
  url.searchParams.set("auto", "webp");
  url.searchParams.set("width", width.toString());
  url.searchParams.set("quality", (quality || 75).toString());
  return url.href;
}

Gumlet

// 文档: https://docs.gumlet.com/reference/image-transform-size
export default function gumletLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`);
  url.searchParams.set("format", "auto");
  url.searchParams.set("w", width.toString());
  url.searchParams.set("q", (quality || 75).toString());
  return url.href;
}

ImageEngine

// 文档: https://support.imageengine.io/hc/en-us/articles/360058880672-Directives
export default function imageengineLoader({ src, width, quality }) {
  const compression = 100 - (quality || 50)
  const params = [`w_${width}`, `cmpr_${compression}`)]
  return `https://example.com${src}?imgeng=/${params.join('/')`
}

Imgix

// 演示: https://static.imgix.net/daisy.png?format=auto&fit=max&w=300
export default function imgixLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`);
  const params = url.searchParams;
  params.set("auto", params.getAll("auto").join(",") || "format");
  params.set("fit", params.get("fit") || "max");
  params.set("w", params.get("w") || width.toString());
  params.set("q", (quality || 50).toString());
  return url.href;
}

PixelBin

// 文档 (调整大小): https://www.pixelbin.io/docs/transformations/basic/resize/#width-w
// 文档 (优化): https://www.pixelbin.io/docs/optimizations/quality/#image-quality-when-delivering
// 文档 (自动格式交付): https://www.pixelbin.io/docs/optimizations/format/#automatic-format-selection-with-f_auto-url-parameter
export default function pixelBinLoader({ src, width, quality }) {
  const name = "<your-cloud-name>";
  const opt = `t.resize(w:${width})~t.compress(q:${quality || 75})`;
  return `https://cdn.pixelbin.io/v2/${name}/${opt}/${src}?f_auto=true`;
}

Sanity

// 文档: https://www.sanity.io/docs/image-urls
export default function sanityLoader({ src, width, quality }) {
  const prj = "zp7mbokg";
  const dataset = "production";
  const url = new URL(`https://cdn.sanity.io/images/${prj}/${dataset}${src}`);
  url.searchParams.set("auto", "format");
  url.searchParams.set("fit", "max");
  url.searchParams.set("w", width.toString());
  if (quality) {
    url.searchParams.set("q", quality.toString());
  }
  return url.href;
}

Sirv

// 文档: https://sirv.com/help/articles/dynamic-imaging/
export default function sirvLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`);
  const params = url.searchParams;
  params.set("format", params.getAll("format").join(",") || "optimal");
  params.set("w", params.get("w") || width.toString());
  params.set("q", (quality || 85).toString());
  return url.href;
}

Supabase

// 文档: https://supabase.com/docs/guides/storage/image-transformations#nextjs-loader
export default function supabaseLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`);
  url.searchParams.set("width", width.toString());
  url.searchParams.set("quality", (quality || 75).toString());
  return url.href;
}

Thumbor

// 文档: https://thumbor.readthedocs.io/en/latest/
export default function thumborLoader({ src, width, quality }) {
  const params = [`${width}x0`, `filters:quality(${quality || 75})`];
  return `https://example.com${params.join("/")}${src}`;
}