Optimize images

Ask the GraphQL API for resized copies of collection, designer and article images and build a responsive srcset from them

Every image in the GraphQL API (including for font collections and article illustrations) is an Image type with a url for the file as it was uploaded and a meta object revealing its pixel width, height and mimeType. By default the API returns whatever you dropped into the admin, which could be a 10 MB, 3000×2000px JPEG, so serving url as-is means every visitor downloads the full file. Pass arguments to url and Fontdue returns a resized, optimized copy instead. Request several of these at different widths to make a srcset so the browser can choose the best size for the screen.11This page is for sites that render a plain <img>. In Next.js, next/image does the same work from the bare url – see Images in the walkthrough.

Request a sized copy

url takes three optional arguments, and any one of them switches the field from the original to an optimized copy:

images {
description
meta { width height mimeType }
src: url(width: 1600)
thumb: url(width: 400, height: 400)
}

width and height are maximums. The image keeps its aspect ratio within both and is never upscaled, so a 1200px upload requested at width: 1600 comes back at 1200px, and width: 400, height: 400 fits a landscape image into 400 wide by however tall that makes it. quality sets the encoding quality from 1 to 100 and defaults to 75. There is no format argument: the copy is encoded in the most efficient format the requesting browser accepts – AVIF, WebP, or the original – decided per request from the browser’s Accept header.

SVGs and videos are always returned as uploaded, whatever the arguments, so a template can request sizes without first checking what kind of file it has.22Collection images can be MP4 files, which the field returns unchanged. Check meta.mimeType for video/mp4 and render a <video> for those, as the templates do. Each distinct set of arguments is a separate copy to generate and cache, so settle on a handful of sizes and reuse them across the site rather than picking a new width per component.

Build a srcset

Alias the field once per width you want to offer, alongside the original dimensions from meta, for example:

images {
description
meta { width height mimeType }
w640: url(width: 640)
w1280: url(width: 1280)
w1920: url(width: 1920)
}

Then use srcSet together with the sizes attribute to describe how wide the image renders in your layout. In the example below, the image is full width on mobile and half the viewport width on desktop:

<img
src={image.w1280}
srcSet={`${image.w640} 640w, ${image.w1280} 1280w, ${image.w1920} 1920w`}
sizes="(min-width: 1024px) 50vw, 100vw"
width={image.meta.width}
height={image.meta.height}
alt={image.description ?? ""}
loading="lazy"
/>

Using your framework or host instead

Your frontend framework may already have its own image optimizer, and it can take Fontdue’s image URLs as long as the source host is allowlisted. Astro’s <Image> component resizes remote images once cdn.fontdue.com is in image.domains (or image.remotePatterns) in astro.config.mjs. Netlify’s Image CDN and Vercel’s image optimization both take a URL and a width from any framework – /.netlify/images?url=…&w=… with remote_images under [images] in netlify.toml, or /_vercel/image?url=…&w=… with images.remotePatterns in vercel.json.33Your logo is served from its own Fontdue host (<name>.fontdue.com or a custom domain), so allowlist that too if you route the logo through the same optimizer. The Netlify and Vercel services run on your hosting plan’s image quota; if you’re self-hosting there’s no such service, so use the url arguments.

1 This page is for sites that render a plain <img>. In Next.js, next/image does the same work from the bare url – see Images in the walkthrough. 
2 Collection images can be MP4 files, which the field returns unchanged. Check meta.mimeType for video/mp4 and render a <video> for those, as the templates do. 
3 Your logo is served from its own Fontdue host (<name>.fontdue.com or a custom domain), so allowlist that too if you route the logo through the same optimizer.