Advanced image capabilities including art direction for responsive design, external service integration, and custom image processing workflows.
Create art-directed images that display different images at different screen sizes, perfect for responsive design where different crops or compositions work better on different devices.
Combines multiple images with media queries to create art-directed responsive images.
/**
* Create art-directed images with different images for different screen sizes
* @param defaultImage - Default image used for sizing and fallback
* @param artDirected - Array of media query and image pairs
* @returns Combined image data with art direction support
*/
function withArtDirection(
defaultImage: IGatsbyImageData,
artDirected: Array<IArtDirectedImage>
): IGatsbyImageData;
interface IArtDirectedImage {
/** CSS media query string */
media: string;
/** Image to display when media query matches */
image: IGatsbyImageData;
}Usage Examples:
import React from "react";
import { graphql, useStaticQuery } from "gatsby";
import { GatsbyImage, getImage, withArtDirection } from "gatsby-plugin-image";
const ArtDirectedImage = () => {
const data = useStaticQuery(graphql`
query {
desktop: file(relativePath: { eq: "hero-desktop.jpg" }) {
childImageSharp {
gatsbyImageData(width: 1200, height: 600)
}
}
mobile: file(relativePath: { eq: "hero-mobile.jpg" }) {
childImageSharp {
gatsbyImageData(width: 800, height: 1000)
}
}
}
`);
const desktopImage = getImage(data.desktop);
const mobileImage = getImage(data.mobile);
const artDirectedImage = withArtDirection(desktopImage, [
{
media: "(max-width: 768px)",
image: mobileImage,
},
]);
return (
<GatsbyImage
image={artDirectedImage}
alt="Art directed hero image"
/>
);
};
// Multiple breakpoints example
const ComplexArtDirection = ({ images }) => {
const { desktop, tablet, mobile } = images;
const artDirectedImage = withArtDirection(desktop, [
{
media: "(max-width: 480px)",
image: mobile,
},
{
media: "(max-width: 1024px)",
image: tablet,
},
]);
return (
<GatsbyImage
image={artDirectedImage}
alt="Multi-breakpoint art directed image"
/>
);
};Advanced integration with external image services and CDNs for dynamic image processing.
Create sophisticated URL builders for external image services with custom processing options.
/**
* Advanced URL builder type for external services
* @param args - URL generation arguments with custom options
* @returns Generated image URL
*/
type UrlBuilder<OptionsType = Record<string, unknown>> = (
args: IUrlBuilderArgs<OptionsType>
) => string;
interface IUrlBuilderArgs<OptionsType = Record<string, unknown>> {
/** Target image width */
width: number;
/** Target image height */
height: number;
/** Image format */
format: ImageFormat;
/** Custom options specific to the service */
options: OptionsType;
}Advanced Integration Examples:
import { getImageData, GatsbyImage } from "gatsby-plugin-image";
// Cloudinary with transformations
interface CloudinaryOptions {
quality?: number;
crop?: string;
gravity?: string;
effects?: string[];
}
const getCloudinaryImage = (
publicId: string,
options: CloudinaryOptions = {}
) => {
return getImageData<CloudinaryOptions>({
baseUrl: `https://res.cloudinary.com/demo/image/upload/${publicId}`,
urlBuilder: ({ width, height, format, options }) => {
const transformations = [
`w_${width}`,
`h_${height}`,
`f_${format || "jpg"}`,
options.crop && `c_${options.crop}`,
options.gravity && `g_${options.gravity}`,
options.quality && `q_${options.quality}`,
...(options.effects || []),
].filter(Boolean).join(",");
return `https://res.cloudinary.com/demo/image/upload/${transformations}/${publicId}`;
},
width: 800,
height: 600,
formats: ["webp", "avif", "jpg"],
options,
});
};
// ImageKit integration
interface ImageKitOptions {
blur?: number;
sharpen?: number;
contrast?: number;
brightness?: number;
}
const getImageKitImage = (
path: string,
options: ImageKitOptions = {}
) => {
return getImageData<ImageKitOptions>({
baseUrl: `https://ik.imagekit.io/demo${path}`,
urlBuilder: ({ width, height, format, options }) => {
const transformations = [
`w-${width}`,
`h-${height}`,
`f-${format || "jpg"}`,
options.blur && `bl-${options.blur}`,
options.sharpen && `e-sharpen-${options.sharpen}`,
options.contrast && `e-contrast-${options.contrast}`,
options.brightness && `e-brightness-${options.brightness}`,
].filter(Boolean).join(",");
return `https://ik.imagekit.io/demo/tr:${transformations}${path}`;
},
width: 800,
height: 600,
formats: ["webp", "jpg"],
options,
});
};
// Usage with advanced options
const AdvancedExternalImage = () => {
const cloudinaryImage = getCloudinaryImage("sample", {
quality: 85,
crop: "crop",
gravity: "face",
effects: ["e_grayscale", "e_blur:300"],
});
const imageKitImage = getImageKitImage("/path/to/image.jpg", {
sharpen: 5,
contrast: 20,
});
return (
<div>
<GatsbyImage image={cloudinaryImage} alt="Cloudinary processed" />
<GatsbyImage image={imageKitImage} alt="ImageKit processed" />
</div>
);
};Advanced configuration for custom image processing pipelines and Sharp.js integration.
When using StaticImage or gatsby-plugin-sharp, advanced Sharp.js options are available for image processing.
interface ISharpGatsbyImageArgs {
/** Image layout strategy */
layout?: Layout;
/** Output image formats */
formats?: Array<ImageFormat>;
/** Type of placeholder to show during loading */
placeholder?: "tracedSVG" | "dominantColor" | "blurred" | "none";
/** Traced SVG options */
tracedSVGOptions?: Record<string, unknown>;
/** Desired width in pixels */
width?: number;
/** Desired height in pixels */
height?: number;
/** Aspect ratio as width/height */
aspectRatio?: number;
/** Responsive sizes attribute */
sizes?: string;
/** Image quality from 1-100 */
quality?: number;
/** Sharp transformation options */
transformOptions?: {
/** How to crop/resize the image */
fit?: Fit;
/** Crop focus point */
cropFocus?: number | string;
/** Duotone effect configuration */
duotone?: {
highlight: string;
shadow: string;
opacity?: number;
};
/** Convert to grayscale */
grayscale?: boolean;
/** Rotate image in degrees */
rotate?: number;
/** Trim border pixels */
trim?: number;
};
/** JPEG processing options */
jpgOptions?: Record<string, unknown>;
/** PNG processing options */
pngOptions?: Record<string, unknown>;
/** WebP processing options */
webpOptions?: Record<string, unknown>;
/** AVIF processing options */
avifOptions?: Record<string, unknown>;
/** Blurred placeholder options */
blurredOptions?: { width?: number; toFormat?: ImageFormat };
/** Custom breakpoints for responsive images */
breakpoints?: Array<number>;
/** Output pixel densities */
outputPixelDensities?: Array<number>;
/** Background color */
backgroundColor?: string;
}
type Fit = "cover" | "fill" | "inside" | "outside" | "contain";Advanced Processing Examples:
import { StaticImage } from "gatsby-plugin-image";
// Image with complex transformations
const ProcessedImage = () => (
<StaticImage
src="../images/raw-photo.jpg"
alt="Processed photo"
width={800}
height={600}
transformOptions={{
fit: "cover",
cropFocus: "attention",
grayscale: false,
rotate: 0,
sharpen: {
sigma: 1,
flat: 1,
jagged: 2,
},
}}
jpgOptions={{
quality: 90,
progressive: true,
}}
webpOptions={{
quality: 85,
lossless: false,
}}
avifOptions={{
quality: 80,
speed: 2,
}}
/>
);
// Artistic processing
const ArtisticImage = () => (
<StaticImage
src="../images/portrait.jpg"
alt="Artistic portrait"
width={600}
height={800}
transformOptions={{
fit: "cover",
cropFocus: "face",
blur: 2,
grayscale: true,
}}
formats={["webp", "jpg"]}
quality={95}
/>
);Advanced techniques for optimizing image performance and loading strategies.
Define custom breakpoints for responsive images to match your design system.
// Custom breakpoints example
const getOptimizedImageData = (baseUrl: string, urlBuilder: UrlBuilder) => {
return getImageData({
baseUrl,
urlBuilder,
width: 1200,
height: 800,
breakpoints: [320, 640, 768, 1024, 1280, 1536, 1920],
formats: ["webp", "avif", "jpg"],
layout: "constrained",
});
};Control lazy loading behavior for different use cases.
import { GatsbyImage } from "gatsby-plugin-image";
// Eager loading for above-the-fold images
const HeroImage = ({ imageData }) => (
<GatsbyImage
image={imageData}
alt="Hero image"
loading="eager" // Disable lazy loading
fetchPriority="high" // High priority loading
/>
);
// Custom lazy loading with intersection observer
const LazyImage = ({ imageData }) => (
<GatsbyImage
image={imageData}
alt="Lazy loaded image"
loading="lazy"
style={{
// Custom loading transition
transition: "opacity 0.3s ease-in-out",
}}
/>
);